Redis高可用及分片集羣

一、主從複製

  • 使用異步複製
  • 一個服務器可以有多個從服務器
  • 從服務器也可以有自己的從服務器
  • 複製功能不會阻塞主服務器
  • 可以通過服務功能來上主服務器免於持久化操作,由從服務器去執行持久化操作即可。
Redis高可用及分片集群

以下是關於Redis複製功能的幾個重要方面:

  • Redis使用異步複製。從Redis 2.8開始,從服務器會以每秒一次的頻率向主服務器報告複製流(replication stream)的處理進度。
  • 一個主服務器可以有多個從服務器。
  • 不僅主服務器可以有從服務器,從服務器也可以有自己的從服務器,多個從服務器之間可以構成一個圖狀結構。
  • 複製功能不會阻塞主服務器: 即使有一個或多個從服務器正在進行初次同步, 主服務器也可以繼續處理命令請求。
  • 複製功能也不會阻塞從服務器: 只要在 redis.conf 文件中進行了相應的設置, 即使從服務器正在進行初次同步, 服務器也可以使用舊版本的數據集來處理命令查詢。
  • 不過, 在從服務器刪除舊版本數據集並載入新版本數據集的那段時間內, 連接請求會被阻塞。
  • 你還可以配置從服務器, 讓它在與主服務器之間的連接斷開時, 向客戶端發送一個錯誤。
  • 複製功能可以單純地用於數據冗餘(data redundancy), 也可以通過讓多個從服務器處理只讀命令請求來提升擴展性(scalability): 比如說, 繁重的 SORT 命令可以交給附屬節點去運行。
  • 可以通過複製功能來讓主服務器免於執行持久化操作: 只要關閉主服務器的持久化功能, 然後由從服務器去執行持久化操作即可。

Redis主從複製實踐

環境:

/data/6380/redis-server

/data/6380/redis.conf

/data/6381/redis-server

/data/6381/redis.conf

/data/6382/redis-server

/

data/6382/redis.conf

配置文件示例:

配置文件示例:

redis.conf

bind 127.0.0.1 192.168.29.128

port 6380

daemonize yes

pidfile /data/6380/redis.pid

loglevel notice

logfile "/data/6380/redis.log"

dbfilename dump.rdb

dir /data/6380

appendonly no

appendfilename "appendonly.aof"

appendfsync everysec

slowlog-log-slower-than 10000

slowlog-max-len 128

protected-mode no

啟動

/data/6380/redis-server /data/6380/redis.conf

/data/6381/redis-server /data/6381/redis.conf

/data/6382/redis-server /data/6382/redis.conf

主節點:6380

從節點:6381、6382

開啟主從:

6381/6382命令行:

redis-cli -p 6381

SLAVEOF 127.0.0.1 6380

運行原理

從服務器以每秒一次的頻率PING主服務器一次,並報告複製流的處理情況。主服務器記錄各個從服務器最後一次向它發送PING的時間。用戶可以通過配置,指定網絡延遲的最大值min-slaves-max-lag,以及執行操作所需的至少從服務器數量min-slaves-to-write

如果至少有min-slaves-to-write個從服務器,並且這些服務器的延遲值都少於min-slaves-max-lag秒,那麼主服務器就會執行客戶端請求的寫操作。你可以將這個特性看作CAP理論的C的條件放寬版本:儘管不能保證寫操作的持久性,但起碼丟失數量的窗口會被嚴格限制在指定的描述中。

另一方面,如果條件達不到min-slaves-to-write和min-slaves-max-lag所指定的條件,那麼寫操作就不會執行,主服務器會向請求執行寫操作的客戶端返回一個錯誤。

Redis主從複製管理

主從複製狀態監控:

info replication

主從切換:

slaveof no one

二、Redis Sentinel

Redis-SentinelRedis官方推薦的高可用性(HA)接近方案,當用RedisMaster-slave的高可用方案時,假如master宕機了,Redis本身(包括它的很多客戶端)都沒有實現自動進行主備切換,而Redis-sentinel

本身也是一個獨立運行的進程,他能監控多個master-slave集群,發現master宕機後能進行自動切換。

Sentinel的構造

Sentinel是一個監視器,它可以根據被監視實例的身份和狀態來判斷應該執行何種動作。

Redis高可用及分片集群

功能

  • 監控(Monitoring)

Sentinel會不斷地檢查你的主服務器和從服務器是否運作正常。

  • 提醒(Notification)

當被監控的某個Redis服務器出現問題時,Sentinel可以通過API向管理員或者其他應用程序發送通知。

  • 自動故障遷移(Automatic failover)

當一個主服務器不能正常工作時,Sentinel會開始一次自動故障遷移操作,它會將失效主服務器的其中一個從服務器升級為新的主服務器,並讓失效服務器的其他從服務器改為負值新的主服務器;當客戶端試圖連接失效的主服務器時,集群也會向客戶端返回新主服務器的地址,使得集群可以使用新主服務器代替失效服務器。

sentinel配置

mkdir /data/26380

cp /usr/local/redis/src/redis-sentinel /data/26380

cd /data/26380

Vim sentinel.conf

port 26380

dir "/tmp"

sentinel monitor mymaster 127.0.0.1 6380 2

sentinel down-after-milliseconds mymaster 60000

sentinel config-epoch mymaster 0

啟動

./redis-sentinel ./sentinel.conf

運行一個Sentinel所需的最少配置如下所示:

運行一個

Sentinel 所需的最少配置如下所示:

sentinel monitor mymaster 127.0.0.1 6379 2

sentinel down-after-milliseconds mymaster 60000

sentinel failover-timeout mymaster 180000

sentinel parallel-syncs mymaster 1

sentinel monitor resque 192.168.1.3 6380 4

sentinel down-after-milliseconds resque

10000

sentinel failover-timeout resque 180000

sentinel parallel-syncs resque 5

第一行配置指示 Sentinel 去監視一個名為 mymaster 的主服務器, 這個主服務器的 IP 地址為 127.0.0.1 , 端口號為 6379 , 而將這個主服務器判斷為失效至少需要 2 個 Sentinel 同意 (只要同意 Sentinel 的數量不達標,自動故障遷移就不會執行)。

不過要注意, 無論你設置要多少個 Sentinel 同意才能判斷一個服務器失效, 一個 Sentinel 都需要獲得系統中多數(majoritySentinel

的支持, 才能發起一次自動故障遷移, 並預留一個給定的配置節點 (configuration Epoch ,一個配置節點就是一個新主服務器配置的版本號)。

換句話說, 在只有少數(minoritySentinel 進程正常運作的情況下, Sentinel 是不能執行自動故障遷移的。

其他選項的基本格式如下:

sentinel

各個選項的功能如下:

down-after-milliseconds 選項指定了 Sentinel 認為服務器已經斷線所需的毫秒數。

如果服務器在給定的毫秒數之內, 沒有返回 Sentinel 發送的 Ping 命令的回覆, 或者返回一個錯誤, 那麼

Sentinel 將這個服務器標記為主觀下線(subjectively down,簡稱 SDOWN )。

不過只有一個 Sentinel 將服務器標記為主觀下線並不一定會引起服務器的自動故障遷移: 只有在足夠數量的 Sentinel 都將一個服務器標記為主觀下線之後, 服務器才會被標記為客觀下線(objectively down, 簡稱 ODOWN ), 這時自動故障遷移才會執行。

將服務器標記為客觀下線所需的 Sentinel 數量由對主服務器的配置決定。

parallel-syncs 選項指定了在執行故障轉移時, 最多可以有多少個從服務器同時對新的主服務器進行同步, 這個數字越小, 完成故障轉移所需的時間就越長。

如果從服務器被設置為允許使用過期數據集(參見對

redis.conf 文件中對 slave-serve-stale-data 選項的說明), 那麼你可能不希望所有從服務器都在同一時間向新的主服務器發送同步請求, 因為儘管複製過程的絕大部分步驟都不會阻塞從服務器, 但從服務器在載入主服務器發來的 RDB 文件時, 仍然會造成從服務器在一段時間內不能處理命令請求: 如果全部從服務器一起對新的主服務器進行同步, 那麼就可能會造成所有從服務器在短時間內全部不可用的情況出現。

你可以通過將這個值設為 1 來保證每次只有一個從服務器處於不能處理命令請求的狀態。

View Code

配置文件

指定監控master

sentinel monitor mymaster 127.0.0.1 6370 2

{2表示多少個sentinel同意}

安全信息

sentinel auth-pass mymaster root

超過15000毫秒後認為主機宕機

sentinel down-after-milliseconds mymaster 15000

當主從切換多久後認為主從切換失敗

sentinel failover-timeout mymaster 900000

這兩個配置後面的數量主從機需要一樣,epoch為master的版本

sentinel leader-epoch mymaster 1

sentinel config-epoch mymaster 1

Sentinel命令

PING :返回 PONG 。

SENTINEL masters :列出所有被監視的主服務器

SENTINEL slaves name>

SENTINEL get-master-addr-by-name name> : 返回給定名字的主服務器的 IP 地址和端口號。

SENTINEL reset : 重置所有名字和給定模式 pattern 相匹配的主服務器。

SENTINEL failover name> : 當主服務器失效時, 在不詢問其他 Sentinel 意見的情況下, 強制開始一次自動故障遷移。

三、Redis集群

Redis集群是一個可以在多個Redis節點之間進行數據共享的設施(installation)。

Redis集群不支持那些需要同時處理多個鍵的Redis命令,因為執行這些命令需要在多個Redis節點之間移動數據,並且在高負載的情況下,這些命令降低Redis集群的性能,並導致不可預測的行為。

Redis集群通過分區(partition)來提供一定程度的可用性(availability):即使集群中有一部分節點失效或者無法進行通訊,集群也可以繼續處理命令請求。

將數據自動切分(split)到多個節點的能力。

當集群中的一部分節點失效或者無法進行通訊時,仍然可以繼續處理命令請求的能力。

Redis集群數據共享

Redis集群使用數據分片(sharding)而非一致性哈希(consistency hashing)來實現:一個Redis集群包含16384個哈希槽(hash slot),數據庫中的每個鍵都屬於這16384個哈希槽的其中一個,集群使用公式CRC16(key)%16384來計算鍵key屬於哪個槽,其中CRC16(key)語句用於計算鍵keyCRC16校驗和。

節點A負責處理0號至5500號哈希槽。

節點B負責處理5501號至

11000號哈希槽。

節點C負責處理11001號至16384號哈希槽。

Redis Cluster

Redis高可用及分片集群

集群組件安裝

EPEL源安裝ruby支持

yum install ruby rubygems -y

使用國內源

gem sources --add https://gems.ruby-china.org/ --remove https://rubygems.org/

gem install redis -v 3.3.3

gem sources -l

如果無法使用,可以使用aliyun

gem sources -a http://mirrors.aliyun.com/rubygems/

gem sources --remove http://rubygems.org/

配置文件中包含

Redis 集群由多個運行在集群模式(cluster mode)下的 Redis 實例組成, 實例的集群模式需要通過配置來開啟, 開啟集群模式的實例將可以使用集群特有的功能和命令。

以下是一個包含了最少選項的集群配置文件示例:

port 7000

cluster-enabled yes

cluster-config-file nodes.conf

cluster-node-timeout 5000

appendonly yes

文件中的 cluster-enabled 選項用於開實例的集群模式, 而 cluster-conf-file 選項則設定了保存節點配置文件的路徑, 默認值為 nodes.conf

節點配置文件無須人為修改, 它由 Redis 集群在啟動時創建, 並在有需要時自動進行更新。

要讓集群正常運作至少需要三個主節點, 不過在剛開始試用集群功能時, 強烈建議使用六個節點: 其中三個為主節點, 而其餘三個則是各個主節點的從節點。

cd /data

mkdir cluster-test

cd cluster-test

mkdir 7000 7001 7002 7003 7004 7005

創建應用

mkdir cluster-test

cd cluster-test

mkdir 7000 7001 7002 7003 7004 7005

拷貝應用

cp redis.conf redis-server ./7000

啟動應用

cd 7000

./redis-server ./redis.conf

創建集群

{redis_src_home}/src/redis-trib.rb create

--replicas 1 127.0.0.1:7000 127.0.0.1:7001 \

127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005

給定 redis-trib.rb 程序的命令是 create , 這表示我們希望創建一個新的集群。

選項 --replicas 1

表示我們希望為集群中的每個主節點創建一個從節點。

集群客戶端

redis-cli -c -p 7000

set foo bar

get

foo

重新分片

./redis-trib.rb reshard 127.0.0.1:7000

集群管理

集群狀態

redis-cli -p 7000 cluster nodes | grep master

故障轉移

redis-cli -p 7002 debug segfault

查看狀態

redis-cli -p 7000 cluster nodes | grep master

增加新的節點

./redis-trib.rb add-node 127.0.0.1:7006 127.0.0.1:7000

刪除一個節點

redis-trib del-node ip:port ''

刪除master節點之前首先要使用reshard移除master的全部slot,然後再刪除當前節點

添加一個從節點

./redis-trib.rb add-node --slave --master-id $[nodeid] 127.0.0.1:7008 127.0.0.1:7000

狀態說明

集群最近一次向節點發送 PING 命令之後, 過去了多長時間還沒接到回覆。

節點最近一次返回 PONG 回覆的時間。

節點的配置節點(configuration epoch):詳細信息請參考 Redis 集群規範 。

本節點的網絡連接情況:例如 connected

節點目前包含的槽:例如 127.0.0.1:7001 目前包含號碼為 5960 至 10921 的哈希槽。

越努力越幸運,做一個愛思考 愛學習的程序員!


分享到:


相關文章: