redis cluster叢集管理工具redis-trib.rb命令小結-運維筆記

散盡浮華發表於2018-10-29

 

redis-trib.rb是redis官方推出的管理redis叢集的工具,整合在redis的原始碼src目錄下,是基於redis提供的叢集命令封裝成簡單、便捷、實用的操作工具。redis-trib.rb是redis作者用ruby完成的。所以要執行redis-trib.rb命令,需要Ruby,具體可參考:http://www.cnblogs.com/kevingrace/p/7846324.html

[root@redis-node01 ~]# /data/redis-4.0.6/src/redis-trib.rb 
Usage: redis-trib <command> <options> <arguments ...>

  create          host1:port1 ... hostN:portN
                  --replicas <arg>
  check           host:port
  info            host:port
  fix             host:port
                  --timeout <arg>
  reshard         host:port
                  --from <arg>
                  --to <arg>
                  --slots <arg>
                  --yes
                  --timeout <arg>
                  --pipeline <arg>
  rebalance       host:port
                  --weight <arg>
                  --auto-weights
                  --use-empty-masters
                  --timeout <arg>
                  --simulate
                  --pipeline <arg>
                  --threshold <arg>
  add-node        new_host:new_port existing_host:existing_port
                  --slave
                  --master-id <arg>
  del-node        host:port node_id
  set-timeout     host:port milliseconds
  call            host:port command arg arg .. arg
  import          host:port
                  --from <arg>
                  --copy
                  --replace
  help            (show this help)

For check, fix, reshard, del-node, set-timeout you can specify the host and port of any working node in the cluster.

根據上面幫助資訊可知,redis-trib.rb具有以下功能:
create:建立叢集 --replicas可以指定從節點個數
-  check:檢查叢集
-  info:檢視叢集資訊
-  fix:修復叢集
-  reshard:線上遷移slot
-  rebalance:平衡叢集節點slot數量
-  add-node:將新節點加入叢集
-  del-node:從叢集中刪除節點
-  set-timeout:設定叢集節點間心跳連線的超時時間
-  call:在叢集全部節點上執行命令
 import:將外部redis資料匯入叢集

redis-trib.rb主要有兩個類:ClusterNode和RedisTrib。ClusterNode儲存了每個節點的資訊,RedisTrib則是redis-trib.rb各個功能的實現。
先簡單介紹下redis-trib.rb指令碼的使用,以create為例:

create host1:port1 ... hostN:portN
       --replicas <arg>

host1:port1 ... hostN:portN表示子引數,這個必須在可選引數之後,--replicas <arg>是可選引數,帶的表示後面必須填寫一個引數,像--slave這樣,後面就不帶引數,掌握了這個基本規則,就能從help命令中獲得redis-trib.rb的使用方法。其他命令大都需要傳遞host:port,這是redis-trib.rb為了連線叢集,需要選擇叢集中的一個節點,然後通過該節點獲得整個叢集的資訊。

create建立叢集
create命令可選replicas引數,replicas表示需要有幾個slave。最簡單命令使用如下:

[root@redis-new01 ~]# /data/redis-4.0.6/src/redis-trib.rb create 192.168.10.199:6379 192.168.10.200:6379 192.168.10.201:6379

有一個slave的建立命令如下:

[root@redis-new01 ~]# /data/redis-4.0.6/src/redis-trib.rb create --replicas 1 192.168.10.199:6379 192.168.10.200:6379 192.168.10.201:6379 192.168.10.202:6379  192.168.10.205:6379  192.168.10.208:6379 

建立流程如下:
1)首先為每個節點建立ClusterNode物件,包括連線每個節點。檢查每個節點是否為獨立且db為空的節點。執行load_info方法匯入節點資訊。
2)檢查傳入的master節點數量是否大於等於3個。只有大於3個節點才能組成叢集。
3)計算每個master需要分配的slot數量,以及給master分配slave。分配的演算法大致如下:
- 先把節點按照host分類,這樣保證master節點能分配到更多的主機中。
- 不停遍歷遍歷host列表,從每個host列表中彈出一個節點,放入interleaved陣列。直到所有的節點都彈出為止。
- master節點列表就是interleaved前面的master數量的節點列表。儲存在masters陣列。
- 計算每個master節點負責的slot數量,儲存在slots_per_node物件,用slot總數除以master數量取整即可。
- 遍歷masters陣列,每個master分配slots_per_node個slot,最後一個master,分配到16384個slot為止。
- 接下來為master分配slave,分配演算法會盡量保證master和slave節點不在同一臺主機上。對於分配完指定slave數量的節點,還有多餘的節點,也會為這些節點尋找master。分配演算法會遍歷兩次masters陣列。
- 第一次遍歷masters陣列,在餘下的節點列表找到replicas數量個slave。每個slave為第一個和master節點host不一樣的節點,如果沒有不一樣的節點,則直接取出餘下列表的第一個節點。
- 第二次遍歷是在對於節點數除以replicas不為整數,則會多餘一部分節點。遍歷的方式跟第一次一樣,只是第一次會一次性給master分配replicas數量個slave,而第二次遍歷只分配一個,直到餘下的節點被全部分配出去。
4)列印出分配資訊,並提示使用者輸入“yes”確認是否按照列印出來的分配方式建立叢集。
5)輸入“yes”後,會執行flush_nodes_config操作,該操作執行前面的分配結果,給master分配slot,讓slave複製master,對於還沒有握手(cluster meet)的節點,slave複製操作無法完成,不過沒關係,flush_nodes_config操作出現異常會很快返回,後續握手後會再次執行flush_nodes_config。
6)給每個節點分配epoch,遍歷節點,每個節點分配的epoch比之前節點大1。
7)節點間開始相互握手,握手的方式為節點列表的其他節點跟第一個節點握手。
8)然後每隔1秒檢查一次各個節點是否已經訊息同步完成,使用ClusterNode的get_config_signature方法,檢查的演算法為獲取每個節點cluster nodes資訊,排序每個節點,組裝成node_id1:slots|node_id2:slot2|...的字串。如果每個節點獲得字串都相同,即認為握手成功。
9)此後會再執行一次flush_nodes_config,這次主要是為了完成slave複製操作。
10)最後再執行check_cluster,全面檢查一次叢集狀態。包括和前面握手時檢查一樣的方式再檢查一遍。確認沒有遷移的節點。確認所有的slot都被分配出去了。
11)至此完成了整個建立流程,返回[OK] All 16384 slots covered.。

check檢查叢集
檢查叢集狀態的命令,沒有其他引數,只需要選擇一個叢集中的一個節點即可。執行命令以及結果如下:

[root@redis-new01 ~]# /data/redis-4.0.6/src/redis-trib.rb check 192.168.10.199:6379
>>> Performing Cluster Check (using node 192.168.10.199:6379)
M: b2506515b38e6bbd3034d540599f4cd2a5279ad1 192.168.10.199:6379
   slots:0-5460 (5461 slots) master
   1 additional replica(s)
S: d376aaf80de0e01dde1f8cd4647d5ac3317a8641 192.168.10.205:6379
   slots: (0 slots) slave
   replicates e36c46dbe90960f30861af00786d4c2064e63df2
M: 15126fb33796c2c26ea89e553418946f7443d5a5 192.168.10.201:6379
   slots:10923-16383 (5461 slots) master
   1 additional replica(s)
S: 59fa6ee455f58a5076f6d6f83ddd74161fd7fb55 192.168.10.208:6379
   slots: (0 slots) slave
   replicates 15126fb33796c2c26ea89e553418946f7443d5a5
S: 460b3a11e296aafb2615043291b7dd98274bb351 192.168.10.202:6379
   slots: (0 slots) slave
   replicates b2506515b38e6bbd3034d540599f4cd2a5279ad1
M: e36c46dbe90960f30861af00786d4c2064e63df2 192.168.10.200:6379
   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.    

檢查前會先執行load_cluster_info_from_node方法,把所有節點資料load進來。load的方式為通過自己的cluster nodes發現其他節點,然後連線每個節點,並加入nodes陣列。接著生成節點間的複製關係。load完資料後,開始檢查資料,檢查的方式也是呼叫建立時候使用的check_cluster。

info檢視叢集資訊
info命令用來檢視叢集的資訊。info命令也是先執行load_cluster_info_from_node獲取完整的叢集資訊。然後顯示ClusterNode的info_string結果,示例如下:

[root@redis-new01 ~]# /data/redis-4.0.6/src/redis-trib.rb info 192.168.10.199:6379
192.168.10.199:6379 (b2506515...) -> 0 keys | 5461 slots | 1 slaves.
192.168.10.201:6379 (15126fb3...) -> 0 keys | 5461 slots | 1 slaves.
192.168.10.200:6379 (e36c46db...) -> 0 keys | 5462 slots | 1 slaves.
[OK] 0 keys in 3 masters.
0.00 keys per slot on average.

fix修復叢集
fix命令的流程跟check的流程很像,顯示載入叢集資訊,然後在check_cluster方法內傳入fix為true的變數,會在叢集檢查出現異常的時候執行修復流程。目前fix命令能修復兩種異常,一種是叢集有處於遷移中的slot的節點,一種是slot未完全分配的異常。

fix_open_slot方法是修復叢集有處於遷移中的slot的節點異常。
1)先檢查該slot是誰負責的,遷移的源節點如果沒完成遷移,owner還是該節點。沒有owner的slot無法完成修復功能。
2)遍歷每個節點,獲取哪些節點標記該slot為migrating狀態,哪些節點標記該slot為importing狀態。對於owner不是該節點,但是通過cluster countkeysinslot獲取到該節點有資料的情況,也認為該節點為importing狀態。
3)如果migrating和importing狀態的節點均只有1個,這可能是遷移過程中redis-trib.rb被中斷所致,直接執行move_slot繼續完成遷移任務即可。傳遞dots和fix為true。
4)如果migrating為空,importing狀態的節點大於0,那麼這種情況執行回滾流程,將importing狀態的節點資料通過move_slot方法導給slot的owner節點,傳遞dots)fix和cold為true。接著對importing的節點執行cluster stable命令恢復穩定。
5)如果importing狀態的節點為空,有一個migrating狀態的節點,而且該節點在當前slot沒有資料,那麼可以直接把這個slot設為stable。
6)如果migrating和importing狀態不是上述情況,目前redis-trib.rb工具無法修復,上述的三種情況也已經覆蓋了通過redis-trib.rb工具遷移出現異常的各個方面,人為的異常情形太多,很難考慮完全。
fix_slots_coverage方法能修復slot未完全分配的異常。未分配的slot有三種狀態:
a)所有節點的該slot都沒有資料。該狀態redis-trib.rb工具直接採用隨機分配的方式,並沒有考慮節點的均衡。本人嘗試對沒有分配slot的叢集通過fix修復叢集,結果slot還是能比較平均的分配,但是沒有了連續性,列印的slot資訊非常離散。
b)有一個節點的該slot有資料。該狀態下,直接把slot分配給該slot有資料的節點。
c)有多個節點的該slot有資料。此種情況目前還處於TODO狀態,不過redis作者列出了修復的步驟,對這些節點,除第一個節點,執行cluster migrating命令,然後把這些節點的資料遷移到第一個節點上。清除migrating狀態,然後把slot分配給第一個節點。

reshard線上遷移slot
reshard命令可以線上把叢集的一些slot從叢集原來slot負責節點遷移到新的節點,利用reshard可以完成叢集的線上橫向擴容和縮容。
reshard的引數:

reshard         host:port
                --from <arg>
                --to <arg>
                --slots <arg>
                --yes
                --timeout <arg>
                --pipeline <arg>

host:port:這個是必傳引數,用來從一個節點獲取整個叢集資訊,相當於獲取叢集資訊的入口。
--from <arg>:需要從哪些源節點上遷移slot,可從多個源節點完成遷移,以逗號隔開,傳遞的是節點的node id,還可以直接傳遞--from all,這樣源節點就是叢集的所有節點,不傳遞該引數的話,則會在遷移過程中提示使用者輸入。
--to <arg>:slot需要遷移的目的節點的node id,目的節點只能填寫一個,不傳遞該引數的話,則會在遷移過程中提示使用者輸入。
--slots <arg>:需要遷移的slot數量,不傳遞該引數的話,則會在遷移過程中提示使用者輸入。
--yes:設定該引數,可以在列印執行reshard計劃的時候,提示使用者輸入yes確認後再執行reshard。
--timeout <arg>:設定migrate命令的超時時間。
--pipeline <arg>:定義cluster getkeysinslot命令一次取出的key數量,不傳的話使用預設值為10。

遷移的流程如下:
1)通過load_cluster_info_from_node方法裝載叢集資訊。
2)執行check_cluster方法檢查叢集是否健康。只有健康的叢集才能進行遷移。
3)獲取需要遷移的slot數量,使用者沒傳遞--slots引數,則提示使用者手動輸入。
4)獲取遷移的目的節點,使用者沒傳遞--to引數,則提示使用者手動輸入。此處會檢查目的節點必須為master節點。
5)獲取遷移的源節點,使用者沒傳遞--from引數,則提示使用者手動輸入。此處會檢查源節點必須為master節點。--from all的話,源節點就是除了目的節點外的全部master節點。這裡為了保證叢集slot分配的平均,建議傳遞--from all。
6)執行compute_reshard_table方法,計算需要遷移的slot數量如何分配到源節點列表,採用的演算法是按照節點負責slot數量由多到少排序,計算每個節點需要遷移的slot的方法為:遷移slot數量 * (該源節點負責的slot數量 / 源節點列表負責的slot總數)。這樣算出的數量可能不為整數,這裡程式碼用了下面的方式處理:
7)列印出reshard計劃,如果使用者沒傳--yes,就提示使用者確認計劃。
8)根據reshard計劃,一個個slot的遷移到新節點上,遷移使用move_slot方法。
9)至此,就完成了全部的遷移任務。

[root@redis-new01 ~]# /data/redis-4.0.6/src/redis-trib.rb reshard --from all --to 80b661ecca260c89e3d8ea9b98f77edaeef43dcd --slots 11 192.168.10.199:6379
>>> Performing Cluster Check (using node 192.168.10.199:6379)
S: b2506515b38e6bbd3034d540599f4cd2a5279ad1 192.168.10.199:6379
   slots: (0 slots) slave
   replicates 460b3a11e296aafb2615043291b7dd98274bb351
S: d376aaf80de0e01dde1f8cd4647d5ac3317a8641 192.168.10.205:6379
   slots: (0 slots) slave
   replicates e36c46dbe90960f30861af00786d4c2064e63df2
M: 15126fb33796c2c26ea89e553418946f7443d5a5 192.168.10.201:6379
   slots:10923-16383 (5461 slots) master
   1 additional replica(s)
S: 59fa6ee455f58a5076f6d6f83ddd74161fd7fb55 192.168.10.208:6379
   slots: (0 slots) slave
   replicates 15126fb33796c2c26ea89e553418946f7443d5a5
M: 460b3a11e296aafb2615043291b7dd98274bb351 192.168.10.202:6379
   slots:0-5460 (5461 slots) master
   1 additional replica(s)
M: 80b661ecca260c89e3d8ea9b98f77edaeef43dcd 192.168.10.200:6380
   slots: (0 slots) master
   0 additional replica(s)
M: e36c46dbe90960f30861af00786d4c2064e63df2 192.168.10.200:6379
   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.

Ready to move 11 slots.
  Source nodes:
    M: 15126fb33796c2c26ea89e553418946f7443d5a5 192.168.10.201:6379
   slots:10923-16383 (5461 slots) master
   1 additional replica(s)
    M: 460b3a11e296aafb2615043291b7dd98274bb351 192.168.10.202:6379
   slots:0-5460 (5461 slots) master
   1 additional replica(s)
    M: e36c46dbe90960f30861af00786d4c2064e63df2 192.168.10.200:6379
   slots:5461-10922 (5462 slots) master
   1 additional replica(s)
  Destination node:
    M: 80b661ecca260c89e3d8ea9b98f77edaeef43dcd 192.168.10.200:6380
   slots: (0 slots) master
   0 additional replica(s)
  Resharding plan:
    Moving slot 5461 from e36c46dbe90960f30861af00786d4c2064e63df2
    Moving slot 5462 from e36c46dbe90960f30861af00786d4c2064e63df2
    Moving slot 5463 from e36c46dbe90960f30861af00786d4c2064e63df2
    Moving slot 5464 from e36c46dbe90960f30861af00786d4c2064e63df2
    Moving slot 0 from 460b3a11e296aafb2615043291b7dd98274bb351
    Moving slot 1 from 460b3a11e296aafb2615043291b7dd98274bb351
    Moving slot 2 from 460b3a11e296aafb2615043291b7dd98274bb351
    Moving slot 10923 from 15126fb33796c2c26ea89e553418946f7443d5a5
    Moving slot 10924 from 15126fb33796c2c26ea89e553418946f7443d5a5
    Moving slot 10925 from 15126fb33796c2c26ea89e553418946f7443d5a5
Do you want to proceed with the proposed reshard plan (yes/no)? yes
Moving slot 5461 from 192.168.10.200:6379 to 192.168.10.200:6380:
Moving slot 5462 from 192.168.10.200:6379 to 192.168.10.200:6380:
Moving slot 5463 from 192.168.10.200:6379 to 192.168.10.200:6380:
Moving slot 5464 from 192.168.10.200:6379 to 192.168.10.200:6380:
Moving slot 0 from 192.168.10.202:6379 to 192.168.10.200:6380:
Moving slot 1 from 192.168.10.202:6379 to 192.168.10.200:6380:
Moving slot 2 from 192.168.10.202:6379 to 192.168.10.200:6380:
Moving slot 10923 from 192.168.10.201:6379 to 192.168.10.200:6380:
Moving slot 10924 from 192.168.10.201:6379 to 192.168.10.200:6380:
Moving slot 10925 from 192.168.10.201:6379 to 192.168.10.200:6380:

rebalance平衡叢集節點slot數量
rebalance命令可以根據使用者傳入的引數平衡叢集節點的slot數量,rebalance功能非常強大,可以傳入的引數很多,以下是rebalance的引數列表和命令示例。

rebalance   host:port
            --weight <arg>
            --auto-weights
            --threshold <arg>
            --use-empty-masters
            --timeout <arg>
            --simulate
            --pipeline <arg>

host:port:這個是必傳引數,用來從一個節點獲取整個叢集資訊,相當於獲取叢集資訊的入口。
--weight <arg>:節點的權重,格式為node_id=weight,如果需要為多個節點分配權重的話,需要新增多個--weight <arg>引數,即--weight b31e3a2e=5 --weight 60b8e3a1=5,node_id可為節點名稱的字首,只要保證字首位數能唯一區分該節點即可。沒有傳遞–weight的節點的權重預設為1。
--auto-weights:這個引數在rebalance流程中並未用到。
--threshold <arg>:只有節點需要遷移的slot閾值超過threshold,才會執行rebalance操作。具體計算方法可以參考下面的rebalance命令流程的第四步。
--use-empty-masters:rebalance是否考慮沒有節點的master,預設沒有分配slot節點的master是不參與rebalance的,設定--use-empty-masters可以讓沒有分配slot的節點參與rebalance。
--timeout <arg>:設定migrate命令的超時時間。
--simulate:設定該引數,可以模擬rebalance操作,提示使用者會遷移哪些slots,而不會真正執行遷移操作。
--pipeline <arg>:與reshar的pipeline引數一樣,定義cluster getkeysinslot命令一次取出的key數量,不傳的話使用預設值為10。

示例如下

[root@redis-new01 ~]# /data/redis-4.0.6/src/redis-trib.rb rebalance --threshold 1 --weight b31e3a2e=5 --weight 60b8e3a1=5 --use-empty-masters  --simulate 192.168.10.199:6379

rebalance命令流程如下:
1)load_cluster_info_from_node方法先載入叢集資訊。
2)計算每個master的權重,根據引數--weight <arg>,為每個設定的節點分配權重,沒有設定的節點,則權重預設為1。
3)根據每個master的權重,以及總的權重,計算自己期望被分配多少個slot。計算的方式為:總slot數量 * (自己的權重 / 總權重)。
4)計算每個master期望分配的slot是否超過設定的閾值,即--threshold <arg>設定的閾值或者預設的閾值。計算的方式為:先計算期望移動節點的閾值,演算法為:(100-(100.0*expected/n.slots.length)).abs,如果計算出的閾值沒有超出設定閾值,則不需要為該節點移動slot。只要有一個master的移動節點超過閾值,就會觸發rebalance操作。
5)如果觸發了rebalance操作。那麼就開始執行rebalance操作,先將每個節點當前分配的slots數量減去期望分配的slot數量獲得balance值。將每個節點的balance從小到大進行排序獲得sn陣列。
6)用dst_idx和src_idx遊標分別從sn陣列的頭部和尾部開始遍歷。目的是為了把尾部節點的slot分配給頭部節點。

sn陣列儲存的balance列表排序後,負數在前面,正數在後面。負數表示需要有slot遷入,所以使用dst_idx遊標,正數表示需要有slot遷出,
所以使用src_idx遊標。理論上sn陣列各節點的balance值加起來應該為0,不過由於在計算期望分配的slot的時候只是使用直接取整的方式,
所以可能出現balance值之和不為0的情況,balance值之和不為0即為節點不平衡的slot數量,由於slot總數有16384個,不平衡數量相對於
總數,基數很小,所以對rebalance流程影響不大。

7)獲取sn[dst_idx]和sn[src_idx]的balance值較小的那個值,該值即為需要從sn[src_idx]節點遷移到sn[dst_idx]節點的slot數量。
8)接著通過compute_reshard_table方法計算源節點的slot如何分配到源節點列表。這個方法在reshard流程中也有呼叫,具體步驟可以參考reshard流程的第六步。
9)如果是simulate模式,則只是列印出遷移列表。
10)如果沒有設定simulate,則執行move_slot操作,遷移slot,傳入的引數為:quiet=>true,:dots=>false,:update=>true。
11)遷移完成後更新sn[dst_idx]和sn[src_idx]的balance值。如果balance值為0後,遊標向前進1。
12)直到dst_idx到達src_idx遊標,完成整個rebalance操作。

add-node將新節點加入叢集
add-node命令可以將新節點加入叢集,節點可以為master,也可以為某個master節點的slave。

add-node  new_host:new_port existing_host:existing_port
          --slave
          --master-id <arg>

add-node有兩個可選引數:
--slave:設定該引數,則新節點以slave的角色加入叢集
--master-id:這個引數需要設定了--slave才能生效,--master-id用來指定新節點的master節點。如果不設定該引數,則會隨機為節點選擇master節點。

[root@redis-new01 ~]# /data/redis-4.0.6/src/redis-trib.rb add-node --slave --master-id dcb792b3e85726f012e83061bf237072dfc45f99 192.168.10.202:6379 192.168.10.199:6379
>>> Adding node 192.168.10.202:6379 to cluster 192.168.10.199:6379
>>> Performing Cluster Check (using node 192.168.10.199:6379)
M: dcb792b3e85726f012e83061bf237072dfc45f99 192.168.10.199:6379
   slots:0-5460 (5461 slots) master
   0 additional replica(s)
M: 464d740bf48953ebcf826f4113c86f9db3a9baf3 192.168.10.201:6379
   slots:10923-16383 (5461 slots) master
   0 additional replica(s)
M: befa7e17b4e5f239e519bc74bfef3264a40f96ae 192.168.10.200:6379
   slots:5461-10922 (5462 slots) master
   0 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 192.168.10.202:6379 to make it join the cluster.
Waiting for the cluster to join.
>>> Configure node as replica of 192.168.10.199:6379.
[OK] New node added correctly.

add-node流程如下:
1)通過load_cluster_info_from_node方法轉載叢集資訊,check_cluster方法檢查叢集是否健康。
2)如果設定了--slave,則需要為該節點尋找master節點。設定了--master-id,則以該節點作為新節點的master,如果沒有設定--master-id,則呼叫get_master_with_least_replicas方法,尋找slave數量最少的master節點。如果slave數量一致,則選取load_cluster_info_from_node順序發現的第一個節點。load_cluster_info_from_node順序的第一個節點是add-node設定的existing_host:existing_port節點,後面的順序根據在該節點執行cluster nodes返回的結果返回的節點順序。
3)連線新的節點並與叢集第一個節點握手。
4)如果沒設定–slave就直接返回ok,設定了–slave,則需要等待確認新節點加入叢集,然後執行cluster replicate命令複製master節點。
5)至此,完成了全部的增加節點的流程。

del-node從叢集中刪除節點
del-node可以把某個節點從叢集中刪除。del-node只能刪除沒有分配slot的節點。刪除命令傳遞兩個引數:
host:port:從該節點獲取叢集資訊。
node_id:需要刪除的節點id。

[root@redis-new01 ~]# /data/redis-4.0.6/src/redis-trib.rb del-node 192.168.10.199:6379 d5f6d1d17426bd564a6e309f32d0f5b96962fe53
>>> Removing node d5f6d1d17426bd564a6e309f32d0f5b96962fe53 from cluster 192.168.10.199:6379
>>> Sending CLUSTER FORGET messages to the cluster...
>>> SHUTDOWN the node.

del-node流程如下:
1)通過load_cluster_info_from_node方法轉載叢集資訊。
2)根據傳入的node id獲取節點,如果節點沒找到,則直接提示錯誤並退出。
3)如果節點分配的slot不為空,則直接提示錯誤並退出。
4)遍歷叢集內的其他節點,執行cluster forget命令,從每個節點中去除該節點。如果刪除的節點是master,而且它有slave的話,這些slave會去複製其他master,呼叫的方法是get_master_with_least_replicas,與add-node沒設定--master-id尋找master的方法一樣。
5)然後關閉該節點。

set-timeout設定叢集節點間心跳連線的超時時間
set-timeout用來設定叢集節點間心跳連線的超時時間,單位是毫秒,不得小於100毫秒,因為100毫秒對於心跳時間來說太短了。該命令修改是節點配置引數cluster-node-timeout,預設是15000毫秒。通過該命令,可以給每個節點設定超時時間,設定的方式使用config set命令動態設定,然後執行config rewrite命令將配置持久化儲存到硬碟。以下是示例:

[root@redis-new01 ~]# /data/redis-4.0.6/src/redis-trib.rb  set-timeout 192.168.10.199:6379 30000
>>> Reconfiguring node timeout in every cluster node...
*** New timeout set for 192.168.10.199:6379
*** New timeout set for 192.168.10.205:6379
*** New timeout set for 192.168.10.201:6379
*** New timeout set for 192.168.10.200:6379
*** New timeout set for 192.168.10.208:6379
>>> New node timeout set. 5 OK, 0 ERR.

call在叢集全部節點上執行命令
call命令可以用來在叢集的全部節點執行相同的命令。call命令也是需要通過叢集的一個節點地址,連上整個叢集,然後在叢集的每個節點執行該命令。

[root@redis-new01 ~]# /data/redis-4.0.6/src/redis-trib.rb  call 192.168.10.199:6379 get key
>>> Calling GET key
192.168.10.199:6379: MOVED 12539 192.168.10.201:6379
192.168.10.205:6379: MOVED 12539 192.168.10.201:6379
192.168.10.201:6379:
192.168.10.200:6379: MOVED 12539 192.168.10.201:6379
192.168.10.208:6379: MOVED 12539 192.168.10.201:6379

import將外部redis資料匯入叢集
import命令可以把外部的redis節點資料匯入叢集。匯入的流程如下
1)通過load_cluster_info_from_node方法轉載叢集資訊,check_cluster方法檢查叢集是否健康。
2)連線外部redis節點,如果外部節點開啟了cluster_enabled,則提示錯誤。
3)通過scan命令遍歷外部節點,一次獲取1000條資料。
4)遍歷這些key,計算出key對應的slot。
5)執行migrate命令,源節點是外部節點,目的節點是叢集slot對應的節點,如果設定了--copy引數,則傳遞copy引數,如果設定了--replace,則傳遞replace引數。
6)不停執行scan命令,直到遍歷完全部的key。
7)至此完成整個遷移流程
這中間如果出現異常,程式就會停止。沒使用--copy模式,則可以重新執行import命令,使用--copy的話,最好清空新的叢集再匯入一次。

import命令更適合離線的把外部redis資料匯入,線上匯入的話最好使用更專業的匯入工具,以slave的方式連線redis節點去同步節點資料應該是更好的方式。

相關文章