一、Redis主從復制
1.1、主從復制介紹
1)使用異步復制。
2)一個主服務器可以有多個從服務器。從服務器也可以有自己的從服務器。
3)復制功能不會阻塞主服務器
4)可以通過復制功能來讓主服務器免於執行持久化操作,由從服務器去執行持久化操作即可。
1.2、數據安全
當配置Redis復制功能時,強烈建議打開主服務器的持久化功能。否則的話,由於延遲等問題,部署的服務應該要避免自動拉起。為了幫助理解主服務器關閉持久化時自動拉起的危險性,參考一下以下會導致主從服務器數據全部丟失的例子:
1. 假設節點A為主服務器,並且關閉了持久化。 並且節點B和節點C從節點A復制數據
2. 節點A崩潰,然后由自動拉起服務重啟了節點A. 由於節點A的持久化被關閉了,所以重啟之后沒有任何數據
3. 節點B和節點C將從節點A復制數據,但是A的數據是空的, 於是就把自身保存的數據副本刪除。
4)在關閉主服務器上的持久化,並同時開啟自動拉起進程的情況下,即便使用Sentinel來實現Redis的高可用性,也是非常危險的。 因為主服務器可能拉起得非常快,以至於Sentinel在配置的心跳時間間隔內沒有檢測到主服務器已被重啟,然后還是會執行上面的數據丟失的流程。
無論何時,數據安全都是極其重要的,所以應該禁止主服務器關閉持久化的同時自動拉起。
1.3、主從復制原理
原理說明:
1. 副本庫通過slaveof 10.0.0.51 6379命令,連接主庫,並發送SYNC給主庫
2. 主庫收到SYNC,會立即觸發BGSAVE,后台保存RDB,發送給副本庫
3. 副本庫接收后會應用RDB快照
4. 主庫會陸續將中間產生的新的操作,保存並發送給副本庫
5. 到此,我們主復制集就正常工作了
6. 再此以后,主庫只要發生新的操作,都會以命令傳播的形式自動發送給副本庫.
7. 所有復制相關信息,從info信息中都可以查到.即使重啟任何節點,他的主從關系依然都在.
8. 如果發生主從臨時斷開。從庫數據沒有被破壞的情況下,在下次重連之后,,從庫發送PSYNC給主庫 (2.8版本之后)
9. 主庫只會將從庫缺失部分的數據同步給從庫應用,達到快速恢復主從的目的
其他說明:
1)SYNC 命令執行示例
2)命令傳播
在主從服務器完成同步之后,主服務器每執行一個寫命令,它都會將被執行的寫命令發送給從服務器執行,這個操作被稱為“命令傳播”(command propagate)。命令傳播是一個持續的過程:只要復制仍在繼續,命令傳播就會一直進行,使得主從服務器的狀態可以一直保持一致
3)復制中的SYNC與PSYNC
①在 Redis 2.8 版本之前, 斷線之后重連的從服務器總要執行一次完整重同步(full resynchronization)操作。
②從 Redis 2.8 開始,Redis 使用 PSYNC命令代替 SYNC 命令。PSYNC 比起 SYNC 的最大改進在於 PSYNC 實現了部分重同步(partial resync)特性:在主從服務器斷線並且重新連接的時候,只要條件允許,PSYNC 可以讓主服務器只向從服務器同步斷線期間缺失的數據,而不用重新向從服務器同步整個數據庫。
SYNC 處理斷線重連示例:
PSYNC 處理斷線重連示例:
1.4、復制一致性
1.4.1、問題引出
1)在讀寫分離環境下,客戶端向主服務器發送寫命令 SET n 10086,主服務器在執行這個寫命令之后,向客戶端返回回復,並將這個寫命令傳播給從服務器。
2)接到回復的客戶端繼續向從服務器發送讀命令 GET n ,並且因為網絡狀態的原因,客戶端的 GET命令比主服務器傳播的 SET 命令更快到達了從服務器。
3)因為從服務器鍵 n 的值還未被更新,所以客戶端在從服務器讀取到的將是一個錯誤(過期)的 n值。
1.4.2、問題解決
從 Redis 2.8 開始, 為了保證數據的安全性, 可以通過配置, 讓主服務器只在有至少 N 個當前已連接從服務器的情況下, 才執行寫命令。不過, 因為 Redis 使用異步復制, 所以主服務器發送的寫數據並不一定會被從服務器接收到,因此, 數據丟失的可能性仍然是存在的。
通過以下兩個參數保證數據的安全:
min-slaves-to-write <number of slaves> min-slaves-max-lag <number of seconds> 這個特性的運作原理: 從服務器以每秒一次的頻率 PING 主服務器一次, 並報告復制流的處理情況。 主服務器會記錄各個從服務器最后一次向它發送 PING 的時間。 1)用戶可以通過配置, 指定網絡延遲的最大值 min-slaves-max-lag ,以及執行寫操作所需的至少從服務器數量 min-slaves-to-write 。如果至少有 min-slaves-to-write 個從服務器, 並且這些服務器的延遲值都少於 min-slaves-max-lag秒,那么主服務器就會執行客戶端請求的寫操作。 2)另一方面, 如果條件達不到 min-slaves-to-write 和 min-slaves-max-lag 所指定的條件, 那么寫操作就不會被執行,主服務器會向請求執行寫操作的客戶端返回一個錯誤。
1.5、主從復制配置
1)環境准備
准備兩個或兩個以上redis實例:主節點:6380 從節點:6381、6382
mkdir /data/638{0..2}
2)配置文件
cat >>/data/6380/redis.conf<<EOF port 6380 daemonize yes pidfile /data/6380/redis.pid loglevel notice logfile "/data/6380/redis.log" dbfilename dump.rdb dir /data/6380 requirepass 123 masterauth 123 EOF cat >>/data/6381/redis.conf<<EOF port 6381 daemonize yes pidfile /data/6381/redis.pid loglevel notice logfile "/data/6381/redis.log" dbfilename dump.rdb dir /data/6381 requirepass 123 masterauth 123 EOF cat >>/data/6382/redis.conf<<EOF port 6382 daemonize yes pidfile /data/6382/redis.pid loglevel notice logfile "/data/6382/redis.log" dbfilename dump.rdb dir /data/6382 requirepass 123 masterauth 123 EOF
3)啟動
redis-server /data/6380/redis.conf redis-server /data/6381/redis.conf redis-server /data/6382/redis.conf ps -ef|grep redis
4)開啟主從
6381/6382命令行上操作
redis-cli -p 6381 -a 123 SLAVEOF 127.0.0.1 6380 redis-cli -p 6382 -a 123 SLAVEOF 127.0.0.1 6380
5)查詢主從狀態
redis-cli -p 6380 -a 123 info replication redis-cli -p 6381 -a 123 info replication redis-cli -p 6382 -a 123 info replication
示例:
[root@redis-master ~]# redis-cli -p 6380 -a 123 info replication # Replication role:master connected_slaves:2 slave0:ip=127.0.0.1,port=6381,state=online,offset=1,lag=1 slave1:ip=127.0.0.1,port=6382,state=online,offset=1,lag=1 master_repl_offset:1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:2 repl_backlog_histlen:0 [root@redis-master ~]# redis-cli -p 6381 -a 123 info replication # Replication role:slave master_host:127.0.0.1 master_port:6380 master_link_status:up master_last_io_seconds_ago:8 master_sync_in_progress:0 slave_repl_offset:1 slave_priority:100 slave_read_only:1 connected_slaves:0 master_repl_offset:0 repl_backlog_active:0 repl_backlog_size:1048576 repl_backlog_first_byte_offset:0 repl_backlog_histlen:0 [root@redis-master ~]# redis-cli -p 6382 -a 123 info replication # Replication role:slave master_host:127.0.0.1 master_port:6380 master_link_status:up master_last_io_seconds_ago:2 master_sync_in_progress:0 slave_repl_offset:15 slave_priority:100 slave_read_only:1 connected_slaves:0 master_repl_offset:0 repl_backlog_active:0 repl_backlog_size:1048576 repl_backlog_first_byte_offset:0 repl_backlog_histlen:0
1.6、主從切換
1)模擬主庫故障
redis-cli -p 6380 -a 123 shutdown
2)解除主從關系
redis-cli -p 6381 -a 123 info replication slaveof no one
3)重新設置主從
#6382連接到6381: redis-cli -p 6382 -a 123 SLAVEOF no one SLAVEOF 127.0.0.1 6381 #6382作為6381的從庫
二、Redis Sentinel
2.1、哨兵簡介
Redis-Sentinel是Redis官方推薦的高可用性(HA)解決方案,當用Redis做Master-slave的高可用方案時,假如master宕機了,Redis本身(包括它的很多客戶端)都沒有實現自動進行主備切換,而Redis-sentinel本身也是一個獨立運行的進程,它能監控多個master-slave集群,發現master宕機后能進行自動切換。
2.2、Sentinel 的構造
Sentinel 是一個監視器,它可以根據被監視實例的身份和狀態來判斷應該執行何種動作。
2.3、哨兵功能
1)監控(Monitoring):Sentinel 會不斷地檢查你的主服務器和從服務器是否運作正常。
2)提醒(Notification):當被監控的某個 Redis 服務器出現問題時, Sentinel 可以通過 API 向管理員或者其他應用程序發送通知。
3)自動故障遷移(Automatic failover):當一個主服務器不能正常工作時, Sentinel 會開始一次自動故障遷移操作, 它會將失效主服務器的其中一個從服務器升級為新的主服務器, 並讓失效主服務器的其他從服務器改為復制新的主服務器; 當客戶端試圖連接失效的主服務器時,集群也會向客戶端返回新主服務器的地址,使得集群可以使用新主服務器代替失效服務器。
4)應用透明 ==>相當於mysql MHA vip功能
---------------------------------------------------------------------------------------------------------------------------------------------------
1)發現並連接主服務器
Sentinel 通過用戶給定的配置文件來發現主服務器。Sentinel 會與被監視的主服務器創建兩個網絡連接:
- 命令連接用於向主服務器發送命令。
- 訂閱連接用於訂閱指定的頻道,從而發現監視同一主服務器的其他 Sentinel
2)發現並連接從服務器
Sentinel 通過向主服務器發送 INFO 命令來自動獲得所有從服務器的地址。跟主服務器一樣,Sentinel 會與每個被發現的從服務器創建命令連接和訂閱連接
3)發現其他 Sentinel
Sentinel 會通過命令連接向被監視的主從服務器發送 “HELLO” 信息,該消息包含 Sentinel 的 IP、端口號、ID 等內容,以此來向其他 Sentinel 宣告自己的存在。與此同時Sentinel 會通過訂閱連接接收其他 Sentinel 的“HELLO” 信息,以此來發現監視同一個主服務器的其他 Sentinel 。sentinel1 通過發送HELLO 信息來讓sentinel2 和 sentinel3發現自己,其他兩個sentinel 也會進行類似的操作。
4)多個Sentienl之間的鏈接
Sentinel 之間只會互相創建命令連接,用於進行通信。因為已經有主從服務器作為發送和接收 HELLO 信息的中介,所以 Sentinel之間不會創建訂閱連接。
5)檢測實例的狀態
Sentinel 使用 PING 命令來檢測實例的狀態:如果實例在指定的時間內沒有返回回復,或者返回錯誤的回復,那么該實例會被 Sentinel 判斷為下線
Redis 的 Sentinel 中關於下線(down)有兩個不同的概念:
①主觀下線(Subjectively Down, 簡稱 SDOWN)指的是單個 Sentinel 實例對服務器做出的下線判斷。
②客觀下線(Objectively Down, 簡稱 ODOWN)指的是多個 Sentinel 實例在對同一個服務器做出 SDOWN 判斷, 並且通過 SENTINEL is-master-down-by-addr 命令互相交流之后, 得出的服務器下線判斷。 (一個 Sentinel 可以通過向另一個 Sentinel 發送 SENTINEL is-master-down-by-addr 命令來詢問對方是否認為給定的服務器已下線。)
如果一個服務器沒有在 master-down-after-milliseconds 選項所指定的時間內, 對向它發送 PING 命令的 Sentinel 返回一個有效回復(valid reply), 那么 Sentinel 就會將這個服務器標記為主觀下線。
6)故障轉移FAILOVER
一次故障轉移操作由以下步驟組成:
①發現主服務器已經進入客觀下線狀態。
②基於Raft leader election 協議 , 進行投票選舉
③如果當選失敗,那么在設定的故障遷移超時時間的兩倍之后,重新嘗試當選。 如果當選成功, 那么執行以下步驟。
④選出一個從服務器,並將它升級為主服務器。
⑤向被選中的從服務器發送 SLAVEOF NO ONE 命令,讓它轉變為主服務器。
⑥通過發布與訂閱功能, 將更新后的配置傳播給所有其他 Sentinel ,其他 Sentinel 對它們自己的配置進行更新。
⑦向已下線主服務器的從服務器發送 SLAVEOF 命令,讓它們去復制新的主服務器。
⑧當所有從服務器都已經開始復制新的主服務器時, leader Sentinel 終止這次故障遷移操作。
2.4、哨兵搭建過程
1)創建哨兵目錄
mkdir /data/26380 cd /data/26380
2)哨兵配置文件
cat >>sentinel.conf<<EOF port 26380 dir "/data/26380" sentinel monitor mymaster 127.0.0.1 6380 1 #mymaster名稱可選,1代表至少一台setinel認為主庫宕機,則切換主庫(一般是單數)(認為主庫宕機的最小票數) sentinel down-after-milliseconds mymaster 5000 #主庫宕機失聯最大時間,5s sentinel auth-pass mymaster 123 #setinel要監控節點,需要連接(所有節點密碼要統一) EOF
3)啟動哨兵
redis-sentinel /data/26380/sentinel.conf &
如果有問題,可按如下方法解決:
1、重新准備1主2從環境 2、kill掉sentinel進程 3、刪除sentinel目錄下的所有文件 4、重新搭建sentinel
2.5、故障測試
1)停主庫
2)查看哨兵配置
3)重新啟動宕機的實例
2.6、哨兵管理命令
redis-cli -p 26380 PING :#返回 PONG 。 SENTINEL masters :#列出所有被監視的主服務器 SENTINEL slaves <master name> SENTINEL get-master-addr-by-name <master name> : #返回給定名字的主服務器的 IP 地址和端口號。 SENTINEL reset <pattern> : #重置所有名字和給定模式 pattern 相匹配的主服務器。 SENTINEL failover <master name> : #當主服務器失效時, 在不詢問其他 Sentinel 意見的情況下, 強制開始一次自動故障遷移。 #--------------------------------------------------------------- [root@redis-master ~]# redis-cli -p 26380 127.0.0.1:26380> ping PONG 127.0.0.1:26380> SENTINEL masters ... 127.0.0.1:26380> SENTINEL slaves mymaster .... 127.0.0.1:26380> SENTINEL get-master-addr-by-name mymaster 1) "127.0.0.1" 2) "6382" 127.0.0.1:26380> SENTINEL failover mymaster .....
三、Redis cluster
3.1、cluster簡介
1)Redis 集群是一個可以在多個 Redis 節點之間進行數據共享的設施(installation)。
2)Redis 集群不支持那些需要同時處理多個鍵的 Redis 命令, 因為執行這些命令需要在多個 Redis 節點之間移動數據, 並且在高負載的情況下, 這些命令將降低 Redis 集群的性能, 並導致不可預測的行為。
3)Redis 集群通過分區(partition)來提供一定程度的可用性(availability): 即使集群中有一部分節點失效或者無法進行通訊,集群也可以繼續處理命令請求。
4)將數據自動切分(split)到多個節點的能力。當集群中的一部分節點失效或者無法進行通訊時, 仍然可以繼續處理命令請求的能力。
3.2、集群數據共享
Redis 集群使用數據分片(sharding)而非一致性哈希(consistency hashing)來實現: 一個 Redis 集群包含 16384 個哈希槽(hash slot), 數據庫中的每個鍵都屬於這 16384 個哈希槽的其中一個, 集群使用公式 CRC16(key) % 16384 來計算鍵 key 屬於哪個槽, 其中 CRC16(key) 語句用於計算鍵 key 的 CRC16 校驗和 。
節點 A 負責處理 0 號至 5500 號哈希槽。
節點 B 負責處理 5501 號至 11000 號哈希槽。
節點 C 負責處理 11001 號至 16384 號哈希槽。
集群使用公式 CRC16(key) & 16384 計算鍵 key屬於哪個槽
1)高性能
1、在多分片節點中,將16384個槽位,均勻分布到多個分片節點中
2、存數據時,將key做crc16(key),然后和16384進行取模,得出槽位值(0-16383之間)
3、根據計算得出的槽位值,找到相對應的分片節點的主節點,存儲到相應槽位上
4、如果客戶端當時連接的節點不是將來要存儲的分片節點,分片集群會將客戶端連接切換至真正存儲節點進行數據存儲
2)高可用
在搭建集群時,會為每一個分片的主節點,對應一個從節點,實現slaveof的功能,同時當主節點down,實現類似於sentinel的自動failover的功能。
3.3、運行機制
1)所有的redis節點彼此互聯(PING-PONG機制),內部使用二進制協議優化傳輸速度和帶寬.
2)節點的fail是通過集群中超過半數的master節點檢測失效時才生效.
3)客戶端與redis節點直連,不需要中間proxy層.客戶端不需要連接集群所有節點,連接集群中任何一個可用節點即可
4)把所有的物理節點映射到[0-16383]slot上,cluster 負責維護node<->slot<->key
3.4、集群的復制
為了使得集群在一部分節點下線或者無法與集群的大多數(majority)節點進行通訊的情況下, 仍然可以正常運作, Redis 集群對節點使用了主從復制功能: 集群中的每個節點都有 1 個至 N 個復制品(replica), 其中一個復制品為主節點(master), 而其余的 N-1 個復制品為從節點(slave)。
在之前列舉的節點 A 、B 、C 的例子中, 如果節點 B 下線了, 那么集群將無法正常運行, 因為集群找不到節點來處理 5501 號至 11000 號的哈希槽。
假如在創建集群的時候(或者至少在節點 B 下線之前), 我們為主節點 B 添加了從節點 B1 , 那么當主節點 B 下線的時候, 集群就會將 B1 設置為新的主節點, 並讓它代替下線的主節點 B , 繼續處理 5501 號至 11000 號的哈希槽, 這樣集群就不會因為主節點 B 的下線而無法正常運作了。
不過如果節點 B 和 B1 都下線的話, Redis 集群還是會停止運作。
集群的復制特性重用了 SLAVEOF 命令的代碼,所以集群節點的復制行為和 SLAVEOF 命令的復制行為完全相同。
3.5、集群故障轉移
在集群里面,節點會對其他節點進行下線檢測。當一個主節點下線時,集群里面的其他主節點負責對下線主節點進行故障移。換句話說,集群的節點集成了下線檢測和故障轉移等類似 Sentinel 的功能。因為 Sentinel 是一個獨立運行的監控程序,而集群的下線檢測和故障轉移等功能是集成在節點里面的,它們的運行模式非常地不同,所以盡管這兩者的功能很相似,但集群的實現沒有重用 Sentinel 的代碼。
3.6、集群執行命令情況
1)命令發送給正確的節點
命令發送到了正確的節點:命令要處理的鍵所在的槽正好是由接收命令的節點負責,那么該節點執行命令,就像單機 Redis 服務器一樣。鍵 date 位於 2022 槽,該槽由節點 7000 負責,命令會直接執行
2)命令發送給了錯誤的節點
命令發送到了錯誤的節點:接收到命令的節點並非處理鍵所在槽的節點,那么節點將向客戶端返回一個轉向(redirection)錯誤,告知客戶端應該到哪個節點去執行這個命令,客戶端會根據錯誤提示的信息,重新向正確的節點發送命令。鍵 date 位於 2022 槽,該槽由節點 7000 負責,但錯誤發送到了7001節點
轉向錯誤的實現:
1)集群中的節點會互相告知對方,自己負責處理哪些槽
2)集群中的每個節點都會記錄 16384 個槽分別由哪個節點負責,從而形成一個“槽表”(slot table)。
節點在接收到命令請求時,會通過槽表檢查鍵所在的槽是否由本節點處理:
- 如果是的話,那么節點直接執行命令;
- 如果不是的話,那么節點就從槽表里面提取出正確節點的地址信息,然后返回轉向錯誤。
3.7、集群搭建過程
1)環境准備
6個redis實例,一般會放到3台硬件服務器
注:在企業規划中,一個分片的兩個分到不同的物理機,防止硬件主機宕機造成的整個分片數據丟失。
端口號:7000-7005
2)安裝集群插件
#使用國內源,安裝ruby支持 yum install ruby rubygems -y gem sources -l gem sources -a http://mirrors.aliyun.com/rubygems/ gem sources --remove https://rubygems.org/ gem sources -l gem install redis -v 3.3.3 #或者: gem sources -a http://mirrors.aliyun.com/rubygems/ --remove https://rubygems.org/
3)集群節點准備
mkdir /data/700{0..5} cat > /data/7000/redis.conf <<EOF port 7000 daemonize yes pidfile /data/7000/redis.pid loglevel notice logfile "/data/7000/redis.log" dbfilename dump.rdb dir /data/7000 protected-mode no cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 appendonly yes EOF cat > /data/7001/redis.conf <<EOF port 7001 daemonize yes pidfile /data/7001/redis.pid loglevel notice logfile "/data/7001/redis.log" dbfilename dump.rdb dir /data/7001 protected-mode no cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 appendonly yes EOF cat > /data/7002/redis.conf <<EOF port 7002 daemonize yes pidfile /data/7002/redis.pid loglevel notice logfile "/data/7002/redis.log" dbfilename dump.rdb dir /data/7002 protected-mode no cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 appendonly yes EOF cat > /data/7003/redis.conf <<EOF port 7003 daemonize yes pidfile /data/7003/redis.pid loglevel notice logfile "/data/7003/redis.log" dbfilename dump.rdb dir /data/7003 protected-mode no cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 appendonly yes EOF cat > /data/7004/redis.conf <<EOF port 7004 daemonize yes pidfile /data/7004/redis.pid loglevel notice logfile "/data/7004/redis.log" dbfilename dump.rdb dir /data/7004 protected-mode no cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 appendonly yes EOF cat > /data/7005/redis.conf <<EOF port 7005 daemonize yes pidfile /data/7005/redis.pid loglevel notice logfile "/data/7005/redis.log" dbfilename dump.rdb dir /data/7005 protected-mode no cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 appendonly yes EOF
相關說明:
Redis 集群由多個運行在集群模式(cluster mode)下的 Redis 實例組成, 實例的集群模式需要通過配置來開啟,開啟集群模式的實例將可以使用集群特有的功能和命令
以下是一個包含了最少選項的集群配置文件示例:
port 7000 cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 appendonly yes
4)啟動節點
redis-server /data/7000/redis.conf redis-server /data/7001/redis.conf redis-server /data/7002/redis.conf redis-server /data/7003/redis.conf redis-server /data/7004/redis.conf redis-server /data/7005/redis.conf [root@redis-master ~]# ps -ef|grep redis root 40054 1 0 23:01 ? 00:00:00 redis-server *:7000 [cluster] root 40056 1 0 23:01 ? 00:00:00 redis-server *:7001 [cluster] root 40058 1 0 23:01 ? 00:00:00 redis-server *:7002 [cluster] root 40064 1 0 23:01 ? 00:00:00 redis-server *:7003 [cluster] root 40068 1 0 23:01 ? 00:00:00 redis-server *:7004 [cluster] root 40074 1 0 23:01 ? 00:00:00 redis-server *:7005 [cluster] root 40078 19597 0 23:01 pts/0 00:00:00 grep --color=auto redis
5)將節點加入集群管理
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
#--replicas 1表示副本是一個(如果是2,至少要准備9個節點,一主兩從)
#前三個是主庫,后三個是從庫(需要保證對應的主庫與從庫在不同的節點上)
[root@redis-master ~]# 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 >>> Creating cluster >>> Performing hash slots allocation on 6 nodes... Using 3 masters: 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 Adding replica 127.0.0.1:7003 to 127.0.0.1:7000 Adding replica 127.0.0.1:7004 to 127.0.0.1:7001 Adding replica 127.0.0.1:7005 to 127.0.0.1:7002 M: ffe340c33558da0d97d2bf1c0d5fb677d03607f2 127.0.0.1:7000 slots:0-5460 (5461 slots) master M: 9fa6e1fed6ce5048a1fe7ca1424a7b892c7a7740 127.0.0.1:7001 slots:5461-10922 (5462 slots) master M: 33d39fb9d19b8fd58527540ca5630552948a2ef9 127.0.0.1:7002 slots:10923-16383 (5461 slots) master S: e570f62c75dfa81196e0a76e68fe8facb3642876 127.0.0.1:7003 replicates ffe340c33558da0d97d2bf1c0d5fb677d03607f2 S: 8da392038590f0898ec87fbb7c7b0328fbee5b75 127.0.0.1:7004 replicates 9fa6e1fed6ce5048a1fe7ca1424a7b892c7a7740 S: 0130e90c4dc85caf281ba158c44707c12f7b9f44 127.0.0.1:7005 replicates 33d39fb9d19b8fd58527540ca5630552948a2ef9 Can I set the above configuration? (type 'yes' to accept): yes #輸入yes >>> Nodes configuration updated >>> Assign a different config epoch to each node >>> Sending CLUSTER MEET messages to join the cluster Waiting for the cluster to join.. >>> Performing Cluster Check (using node 127.0.0.1:7000) M: ffe340c33558da0d97d2bf1c0d5fb677d03607f2 127.0.0.1:7000 slots:0-5460 (5461 slots) master 1 additional replica(s) M: 33d39fb9d19b8fd58527540ca5630552948a2ef9 127.0.0.1:7002 slots:10923-16383 (5461 slots) master 1 additional replica(s) S: 8da392038590f0898ec87fbb7c7b0328fbee5b75 127.0.0.1:7004 slots: (0 slots) slave replicates 9fa6e1fed6ce5048a1fe7ca1424a7b892c7a7740 S: e570f62c75dfa81196e0a76e68fe8facb3642876 127.0.0.1:7003 slots: (0 slots) slave replicates ffe340c33558da0d97d2bf1c0d5fb677d03607f2 S: 0130e90c4dc85caf281ba158c44707c12f7b9f44 127.0.0.1:7005 slots: (0 slots) slave replicates 33d39fb9d19b8fd58527540ca5630552948a2ef9 M: 9fa6e1fed6ce5048a1fe7ca1424a7b892c7a7740 127.0.0.1:7001 slots:5461-10922 (5462 slots) master 1 additional replica(s) [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered.
6)查看節點信息
redis-cli -p 7000 cluster nodes|grep master #查看主節點信息 redis-cli -p 7000 cluster nodes|grep salve #查看從節點信息 #--------------------------------------------------------------------------------------- [root@redis-master ~]# redis-cli -p 7000 cluster nodes|grep master ffe340c33558da0d97d2bf1c0d5fb677d03607f2 127.0.0.1:7000 myself,master - 0 0 1 connected 0-5460 #7000節點可以看成是整個集群的管理節點 33d39fb9d19b8fd58527540ca5630552948a2ef9 127.0.0.1:7002 master - 0 1570115793282 3 connected 10923-16383 9fa6e1fed6ce5048a1fe7ca1424a7b892c7a7740 127.0.0.1:7001 master - 0 1570115792274 2 connected 5461-10922 [root@redis-master ~]# redis-cli -p 7000 cluster nodes|grep slave 8da392038590f0898ec87fbb7c7b0328fbee5b75 127.0.0.1:7004 slave 9fa6e1fed6ce5048a1fe7ca1424a7b892c7a7740 0 1570115826599 5 connected e570f62c75dfa81196e0a76e68fe8facb3642876 127.0.0.1:7003 slave ffe340c33558da0d97d2bf1c0d5fb677d03607f2 0 1570115827608 4 connected 0130e90c4dc85caf281ba158c44707c12f7b9f44 127.0.0.1:7005 slave 33d39fb9d19b8fd58527540ca5630552948a2ef9 0 1570115826599 6 connected
關注點:
1、集群節點id,相當於唯一號碼(內部通信使用的就是集群節點id) 2、分配的槽位號
3.8、集群節點管理
3.8.1、增加新的節點
1)創建新節點的目錄及配置文件
mkdir /data/7006 mkdir /data/7007 cat >>/data/7006/redis.conf<<EOF port 7006 daemonize yes pidfile /data/7006/redis.pid loglevel notice logfile "/data/7006/redis.log" dbfilename dump.rdb dir /data/7006 protected-mode no cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 appendonly yes EOF cat >>/data/7007/redis.conf<<EOF port 7007 daemonize yes pidfile /data/7007/redis.pid loglevel notice logfile "/data/7007/redis.log" dbfilename dump.rdb dir /data/7007 protected-mode no cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 appendonly yes EOF
2)啟動新節點
redis-server /data/7006/redis.conf redis-server /data/7007/redis.conf
3)添加主節點
redis-trib.rb add-node 127.0.0.1:7006 127.0.0.1:7000 #7006:新加的主節點 #7000:管理節點 #注意:此時新加入的主節點並沒有分配槽位,還不能使用
4)轉移slot(重新分片),從已有的節點上分配槽位給新添加的節點
redis-trib.rb reshard 127.0.0.1:7000 #16384/4=4096,新節點需要分配的slot為4096個
重新分片過程:
[root@redis-master ~]# redis-trib.rb reshard 127.0.0.1:7000 >>> Performing Cluster Check (using node 127.0.0.1:7000) M: ffe340c33558da0d97d2bf1c0d5fb677d03607f2 127.0.0.1:7000 slots:0-5460 (5461 slots) master 1 additional replica(s) M: 33d39fb9d19b8fd58527540ca5630552948a2ef9 127.0.0.1:7002 slots:10923-16383 (5461 slots) master 1 additional replica(s) S: 8da392038590f0898ec87fbb7c7b0328fbee5b75 127.0.0.1:7004 slots: (0 slots) slave replicates 9fa6e1fed6ce5048a1fe7ca1424a7b892c7a7740 S: e570f62c75dfa81196e0a76e68fe8facb3642876 127.0.0.1:7003 slots: (0 slots) slave replicates ffe340c33558da0d97d2bf1c0d5fb677d03607f2 S: 0130e90c4dc85caf281ba158c44707c12f7b9f44 127.0.0.1:7005 slots: (0 slots) slave replicates 33d39fb9d19b8fd58527540ca5630552948a2ef9 M: 3da906766793c65696c75adecd1797e782bd6f94 127.0.0.1:7006 slots: (0 slots) master 0 additional replica(s) M: 9fa6e1fed6ce5048a1fe7ca1424a7b892c7a7740 127.0.0.1:7001 slots:5461-10922 (5462 slots) master 1 additional replica(s) [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered. How many slots do you want to move (from 1 to 16384)? 4096 ##需要移動多少個槽位 What is the receiving node ID? 3da906766793c65696c75adecd1797e782bd6f94 #接受者id Please enter all the source node IDs. Type 'all' to use all the nodes as source nodes for the hash slots. Type 'done' once you entered all the source nodes IDs. Source node #1:all #來源的節點id ....... Moving slot 1363 from ffe340c33558da0d97d2bf1c0d5fb677d03607f2 Moving slot 1364 from ffe340c33558da0d97d2bf1c0d5fb677d03607f2 Do you want to proceed with the proposed reshard plan (yes/no)? yes #同意 .......
分片完之后,再次查看節點的槽位變化:
5)添加從節點
redis-trib.rb add-node --slave --master-id 主節點的id 127.0.0.1:7007 127.0.0.1:7000 #--master-id:主節點的id(7006)
過程說明:
[root@redis-master ~]# redis-cli -p 7000 cluster nodes|grep master ffe340c33558da0d97d2bf1c0d5fb677d03607f2 127.0.0.1:7000 myself,master - 0 0 1 connected 1365-5460 33d39fb9d19b8fd58527540ca5630552948a2ef9 127.0.0.1:7002 master - 0 1570117851388 3 connected 12288-16383 3da906766793c65696c75adecd1797e782bd6f94 127.0.0.1:7006 master - 0 1570117851892 7 connected 0-1364 5461-6826 10923-12287 9fa6e1fed6ce5048a1fe7ca1424a7b892c7a7740 127.0.0.1:7001 master - 0 1570117850380 2 connected 6827-10922 [root@redis-master ~]# redis-trib.rb add-node --slave --master-id 3da906766793c65696c75adecd1797e782bd6f94 127.0.0.1:7007 127.0.0.1:7000 >>> Adding node 127.0.0.1:7007 to cluster 127.0.0.1:7000 >>> Performing Cluster Check (using node 127.0.0.1:7000) M: ffe340c33558da0d97d2bf1c0d5fb677d03607f2 127.0.0.1:7000 slots:1365-5460 (4096 slots) master 1 additional replica(s) M: 33d39fb9d19b8fd58527540ca5630552948a2ef9 127.0.0.1:7002 slots:12288-16383 (4096 slots) master 1 additional replica(s) S: 8da392038590f0898ec87fbb7c7b0328fbee5b75 127.0.0.1:7004 slots: (0 slots) slave replicates 9fa6e1fed6ce5048a1fe7ca1424a7b892c7a7740 S: e570f62c75dfa81196e0a76e68fe8facb3642876 127.0.0.1:7003 slots: (0 slots) slave replicates ffe340c33558da0d97d2bf1c0d5fb677d03607f2 S: 0130e90c4dc85caf281ba158c44707c12f7b9f44 127.0.0.1:7005 slots: (0 slots) slave replicates 33d39fb9d19b8fd58527540ca5630552948a2ef9 M: 3da906766793c65696c75adecd1797e782bd6f94 127.0.0.1:7006 slots:0-1364,5461-6826,10923-12287 (4096 slots) master 0 additional replica(s) M: 9fa6e1fed6ce5048a1fe7ca1424a7b892c7a7740 127.0.0.1:7001 slots:6827-10922 (4096 slots) master 1 additional replica(s) [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered. >>> Send CLUSTER MEET to node 127.0.0.1:7007 to make it join the cluster. Waiting for the cluster to join. >>> Configure node as replica of 127.0.0.1:7006. [OK] New node added correctly. [root@redis-master ~]# redis-cli -p 7000 cluster nodes|grep slave e68ab83af8aceae5e92ca16c536a897cf7df74c0 127.0.0.1:7007 slave 3da906766793c65696c75adecd1797e782bd6f94 0 1570118059124 7 connected 8da392038590f0898ec87fbb7c7b0328fbee5b75 127.0.0.1:7004 slave 9fa6e1fed6ce5048a1fe7ca1424a7b892c7a7740 0 1570118058622 5 connected e570f62c75dfa81196e0a76e68fe8facb3642876 127.0.0.1:7003 slave ffe340c33558da0d97d2bf1c0d5fb677d03607f2 0 1570118059124 4 connected 0130e90c4dc85caf281ba158c44707c12f7b9f44 127.0.0.1:7005 slave 33d39fb9d19b8fd58527540ca5630552948a2ef9 0 1570118058119 6 connected
3.8.2、刪除節點
#刪除master節點之前首先要使用reshard移除master的全部slot,然后再刪除當前節點 redis-trib.rb del-node 127.0.0.1:7006 1c98b2b2ce18f88c76821cdb82dba4defaa5eb48 redis-trib.rb del-node 127.0.0.1:7007 00185d1cf069b23468d5863202ac651f0d02a9f8
1)查看當前槽位分配狀態:
127.0.0.1:7006 master - 0 1570152124813 7 connected 0-1364 5461-6826 10923-12287 需要歸還 1365 1365 1365
2) 將之前獲取的槽位分批歸還
#1.歸還7000的槽位 [root@redis-master ~]# redis-trib.rb reshard 127.0.0.1:7000 >>> Performing Cluster Check (using node 127.0.0.1:7000) M: ffe340c33558da0d97d2bf1c0d5fb677d03607f2 127.0.0.1:7000 slots:1365-5460 (4096 slots) master 1 additional replica(s) S: e68ab83af8aceae5e92ca16c536a897cf7df74c0 127.0.0.1:7007 slots: (0 slots) slave replicates 3da906766793c65696c75adecd1797e782bd6f94 M: 33d39fb9d19b8fd58527540ca5630552948a2ef9 127.0.0.1:7002 slots:12288-16383 (4096 slots) master 1 additional replica(s) S: 8da392038590f0898ec87fbb7c7b0328fbee5b75 127.0.0.1:7004 slots: (0 slots) slave replicates 9fa6e1fed6ce5048a1fe7ca1424a7b892c7a7740 S: e570f62c75dfa81196e0a76e68fe8facb3642876 127.0.0.1:7003 slots: (0 slots) slave replicates ffe340c33558da0d97d2bf1c0d5fb677d03607f2 S: 0130e90c4dc85caf281ba158c44707c12f7b9f44 127.0.0.1:7005 slots: (0 slots) slave replicates 33d39fb9d19b8fd58527540ca5630552948a2ef9 M: 3da906766793c65696c75adecd1797e782bd6f94 127.0.0.1:7006 slots:0-1364,5461-6826,10923-12287 (4096 slots) master 1 additional replica(s) M: 9fa6e1fed6ce5048a1fe7ca1424a7b892c7a7740 127.0.0.1:7001 slots:6827-10922 (4096 slots) master 1 additional replica(s) [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered. How many slots do you want to move (from 1 to 16384)? 1365 #歸還的槽位 What is the receiving node ID? ffe340c33558da0d97d2bf1c0d5fb677d03607f2 #7000接受者 Please enter all the source node IDs. Type 'all' to use all the nodes as source nodes for the hash slots. Type 'done' once you entered all the source nodes IDs. Source node #1:3da906766793c65696c75adecd1797e782bd6f94 ##7006要刪除的節點 Source node #2:done ...... Moving slot 1363 from 3da906766793c65696c75adecd1797e782bd6f94 Moving slot 1364 from 3da906766793c65696c75adecd1797e782bd6f94 Do you want to proceed with the proposed reshard plan (yes/no)? yes ......... #2.同理歸還1365槽位給7001 #3.同理歸還1365槽位給7002
查看最后歸還結果:
3)刪除主從節點(最好先刪除從節點后刪除主節點)
[root@redis-master ~]# redis-cli -p 7000 cluster nodes ffe340c33558da0d97d2bf1c0d5fb677d03607f2 127.0.0.1:7000 myself,master - 0 0 8 connected 0-5460 e68ab83af8aceae5e92ca16c536a897cf7df74c0 127.0.0.1:7007 slave 33d39fb9d19b8fd58527540ca5630552948a2ef9 0 1570153094607 10 connected 33d39fb9d19b8fd58527540ca5630552948a2ef9 127.0.0.1:7002 master - 0 1570153093599 10 connected 12287-16383 8da392038590f0898ec87fbb7c7b0328fbee5b75 127.0.0.1:7004 slave 9fa6e1fed6ce5048a1fe7ca1424a7b892c7a7740 0 1570153094102 9 connected e570f62c75dfa81196e0a76e68fe8facb3642876 127.0.0.1:7003 slave ffe340c33558da0d97d2bf1c0d5fb677d03607f2 0 1570153094102 8 connected 0130e90c4dc85caf281ba158c44707c12f7b9f44 127.0.0.1:7005 slave 33d39fb9d19b8fd58527540ca5630552948a2ef9 0 1570153093599 10 connected 3da906766793c65696c75adecd1797e782bd6f94 127.0.0.1:7006 master - 0 1570153092594 7 connected 9fa6e1fed6ce5048a1fe7ca1424a7b892c7a7740 127.0.0.1:7001 master - 0 1570153094102 9 connected 5461-12286 [root@redis-master ~]# redis-trib.rb del-node 127.0.0.1:7007 e68ab83af8aceae5e92ca16c536a897cf7df74c0 >>> Removing node e68ab83af8aceae5e92ca16c536a897cf7df74c0 from cluster 127.0.0.1:7007 >>> Sending CLUSTER FORGET messages to the cluster... >>> SHUTDOWN the node. [root@redis-master ~]# redis-trib.rb del-node 127.0.0.1:7006 3da906766793c65696c75adecd1797e782bd6f94 >>> Removing node 3da906766793c65696c75adecd1797e782bd6f94 from cluster 127.0.0.1:7006 >>> Sending CLUSTER FORGET messages to the cluster... >>> SHUTDOWN the node. [root@redis-master ~]#
注意:刪除之后,刪除節點的進程會自動關閉