Redis-Cluster操作詳解
redis在2.8版本中支援分散式的部署,但不是真正意義上的叢集,單獨操作一臺主機獲取相應key,如果這個key沒有落在該機器上,那麼就獲取不到。只有分片在該機器上才能獲取到。redis從3.0版本開始支援自身叢集方式,多個節點組成一個叢集, 無論操作哪臺機器,都可以設定值和獲取值。
redis3.0以上版本叢集方案採用了無中心節點設計的思想,多組節點構成叢集,每組節點中需要有主節點,每個主節點可以有一個或者多個從節點。這樣的設計,保證了一組節點中的主節點掛掉了,從節點可以被選舉為主節點,繼續保證叢集可用。當主節點恢復之後,他會變為從節點。
redis3.0保證叢集可用,並不是每個節點都保留了一份資料,而是採用了一種分槽(slots)的技術,將16384個槽,分配給每一組的節點。客戶端連線redis,不是直接操作slot,而是通過redis操作槽,讓槽來set,get。
我們如果構建三組節點,分配16384個槽,那麼會如下圖所示:
如果增加一個節點,那麼相應的,若需要槽均勻分佈,需要將三組中的槽分配給新的節點。按照16384/4=4096,每個節點可以分配4096個槽,新分配的節點的槽,不會是連續的,如下圖所示。
可以看出每組節點從開始位置分別移動1366,1366,1365個節點到新的主節點上。
下面我們通過示例演示:
建立叢集:
建立叢集的命令:src/redis-trib.rb create --replicas 1 10.100.8.13:7001 10.100.8.13:7002 10.100.8.14:7003 10.100.8.14:7004 10.100.8.18:7005 10.100.8.18:7006,--replicas表示需要為主節點建立的從節點的個數,這裡預設每個主節點配置一個從節點,建立成功的花,會出現如下圖所示slot的分配,7001,7002節點分配slot:0-5641,7003,7004分配slot:5461-10922,7005,7006分配slot:10923-10683,正好如我們前面分析,三組節點將16384個槽均勻分配了。
這樣叢集就建立成功了,我們可以通過設定一些值,看看值是如何在槽上分佈的。
新增主節點
新增的主節點要求節點中無任何資料,如果有資料,會出現以下提示
[ERR] Node 10.100.8.38:7007 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0.
新增主節點的命令:src/redis-trib.rb add-node 10.100.8.38:7007 10.100.8.13:7001,其中第一個節點是要增加的節點,第二個節點是叢集的節點,用來探測叢集的,這個節點可以是已經構成叢集中的任意節點,建立成功,會出現以下提示。
[[email protected] redis-4.0.2]# src/redis-trib.rb add-node 10.100.8.38:7007 10.100.8.13:7001
>>> Adding node 10.100.8.38:7007 to cluster 10.100.8.13:7001
>>> Performing Cluster Check (using node 10.100.8.13:7001)
M: 2b3899852379b189548cf5e05082f929f5075035 10.100.8.13:7001
slots:0-5460 (5461 slots) master
1 additional replica(s)
S: 3a8903716b1a155a14de5d9e12bad762770fa70b 10.100.8.18:7006
slots: (0 slots) slave
replicates 57ebdadddb746f942288f96ad13fe0d7484a3992
S: 81e1a9436c2b03afbbbbb21b8c8e171c46563c88 10.100.8.14:7004
slots: (0 slots) slave
replicates 2b3899852379b189548cf5e05082f929f5075035
M: 57ebdadddb746f942288f96ad13fe0d7484a3992 10.100.8.18:7005
slots:10923-16383 (5461 slots) master
1 additional replica(s)
S: d776390405375559b474f2e7f66e95f956450bb0 10.100.8.13:7002
slots: (0 slots) slave
replicates 4c41a0a371a2b81f3c69210891d8332e7e59ff3f
M: 4c41a0a371a2b81f3c69210891d8332e7e59ff3f 10.100.8.14:7003
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.
>>> Send CLUSTER MEET to node 10.100.8.38:7007 to make it join the cluster.
[OK] New node added correctly.
這裡可以通過check來檢查節點資訊,可以看到10.100.8.38:7007加入了叢集,但是還沒有分槽資訊,這樣他是無法儲存資料的。
這裡需要重新分槽redis-trib.rb reshard 10.100.8.14:7005,這裡指定的節點同樣可以是已經構成叢集的任意節點,他會將現有的槽根據後續指定的引數分配給新的節點。當輸入分槽命令之後,會出現how many slots do you want to move(from 1 to 16384)?的資訊,這裡我們根據之前的設計,需要移動4096個槽給10.100.8.38:7007節點,然後提示需要分配給哪個節點,這裡我們輸入10.100.8.38:7007節點的ID,最後會提示源節點,這裡我們輸入all,表示從現有的三組主節點均勻移動節點到新的節點。
輸入all之後會出現移動槽的滾屏操作,還會出現一次確認,輸入yes之後,分槽成功。我們再次check節點10.100.8.38:7007,按照分槽的結果,他上面的槽是不連續的。每個主節點4096個槽。
新增從節點:
redis-trib.rb add-node --slave --master-id $nodeid 10.100.8.38:7008 10.100.8.13:7001
master-id:指定主節點ID,表示哪個主節點的從節點 //如果不指定則隨機從主節點中從節點數少的節點中選擇一個節點
第一個節點引數:要增加的從節點
第二個節點引數:叢集節點,辨別叢集
[[email protected] redis-4.0.2]# src/redis-trib.rb add-node --slave 10.100.8.38:7008 10.100.8.13:7001
>>> Adding node 10.100.8.38:7008 to cluster 10.100.8.13:7001
>>> Performing Cluster Check (using node 10.100.8.13:7001)
...//省略部分資訊
M: 9ab41f255140a24131d3fd70d40973f5c0cf0fb7 10.100.8.38:7007
slots:0-1364,5461-6826,10923-12287 (4096 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.
Automatically selected master 10.100.8.38:7007
>>> Send CLUSTER MEET to node 10.100.8.38:7008 to make it join the cluster.
Waiting for the cluster to join.
>>> Configure node as replica of 10.100.8.38:7007.
[OK] New node added correctly.
這時可以檢視節點資訊,四個主節點,四個從節點。
10.100.8.13:7001> cluster nodes
f7488758b689af6715402ed7258e475934c53cb3 10.100.8.38:[email protected] slave 9ab41f255140a24131d3fd70d40973f5c0cf0fb7 0 1511851042000 7 connected
3a8903716b1a155a14de5d9e12bad762770fa70b 10.100.8.18:[email protected] slave 57ebdadddb746f942288f96ad13fe0d7484a3992 0 1511851042519 6 connected
81e1a9436c2b03afbbbbb21b8c8e171c46563c88 10.100.8.14:[email protected] slave 2b3899852379b189548cf5e05082f929f5075035 0 1511851042000 4 connected
57ebdadddb746f942288f96ad13fe0d7484a3992 10.100.8.18:[email protected] master - 0 1511851043620 5 connected 12288-16383
2b3899852379b189548cf5e05082f929f5075035 10.100.8.13:[email protected] myself,master - 0 1511851043000 1 connected 1365-5460
d776390405375559b474f2e7f66e95f956450bb0 10.100.8.13:[email protected] slave 4c41a0a371a2b81f3c69210891d8332e7e59ff3f 0 1511851042418 3 connected
4c41a0a371a2b81f3c69210891d8332e7e59ff3f 10.100.8.14:[email protected] master - 0 1511851041414 3 connected 6827-10922
9ab41f255140a24131d3fd70d40973f5c0cf0fb7 10.100.8.38:[email protected] master - 0 1511851043421 7 connected 0-1364 5461-6826 10923-12287
在這裡通過重新分槽,最早我們設定的資料,會分配到新的節點,還是可以查詢出來,但是很明顯槽的資訊發生了變化,他們都分配到了10.100.8.38:7007節點。
叢集高可用測試:我們殺掉節點10.100.8.38:7007程序,檢查叢集節點資訊,10.100.8.38:7008成為主節點,節點數變為7個。
恢復10.100.8.38:7007之後,他變為從節點。
刪除主節點:
刪除主節點需要先移走主節點上的資料,否則會提示節點非空。
[[email protected] redis-4.0.2]# src/redis-trib.rb del-node 10.100.8.13:7001 9ab41f255140a24131d3fd70d40973f5c0cf0fb7
>>> Removing node 9ab41f255140a24131d3fd70d40973f5c0cf0fb7 from cluster 10.100.8.13:7001
[ERR] Node 10.100.8.38:7007 is not empty! Reshard data away and try again.
這裡的reshard和前面給10.100.8.38:7007節點分配槽時類似,就是在提示接收的節點和源節點時需要設定。這裡是需要將4096個槽再分給任意節點,這裡唯一不同的是,接收節點不能是多個,只能指定一個節點。這樣槽的分配就不均勻了(理論上可以通過不斷的reshard,讓槽再次均勻分佈並且連續),所以在實際中不要輕易的刪除節點。
reshard之後再來刪除,就可以刪除了。
[[email protected] redis-4.0.2]# src/redis-trib.rb del-node 10.100.8.13:7001 9ab41f255140a24131d3fd70d40973f5c0cf0fb7
>>> Removing node 9ab41f255140a24131d3fd70d40973f5c0cf0fb7 from cluster 10.100.8.13:7001
>>> Sending CLUSTER FORGET messages to the cluster...
>>> SHUTDOWN the node.
刪除從節點:
直接移除,不用擔心資料槽資訊,這裡就需要指定叢集任意節點,用來探測叢集,再一個引數就是要刪除的節點ID。
[[email protected] redis-4.0.2]# src/redis-trib.rb del-node 10.100.8.13:7001 f7488758b689af6715402ed7258e475934c53cb3
>>> Removing node f7488758b689af6715402ed7258e475934c53cb3 from cluster 10.100.8.13:7001
>>> Sending CLUSTER FORGET messages to the cluster...
>>> SHUTDOWN the node.