Redis集羣研究和實踐(基於redis 3.0.5)(不錯)

轉載原文自:https://www.zybuluo.com/phper/note/195558

前言

redis 是我們目前大規模使用的緩存中間件,由於它強大高效而又便捷的功能,得到了廣泛的使用。現在的2.x的穩定版本是2.8.19,也是我們項目中普遍用到的版本。

redis在年初發布了3.0.0,官方支持了redis cluster,也就是集羣。至此結束了redis 沒有官方集羣的時代,之前我們用redis cluster用的最多的應該是twitter 發佈的Twemproxy(https://github.com/twitter/twemproxy)

還有就是豌豆莢開發的codis (https://github.com/wandoulabs/codis)

這2個我會在後續去使用它們。下面的文字,我儘量用通熟易懂的方式來闡述。

redis cluster 理論知識

截止寫這篇文章前,redis 3.x的最新版本是3.0.5。今天的學習和實踐就是用這個版本。

Redis Cluster設計要點

redis cluster在設計的時候,就考慮到了去中心化,去中間件,也就是說,集羣中的每個節點都是平等的關係,都是對等的,每個節點都保存各自的數據和整個集羣的狀態。每個節點都和其他所有節點連接,而且這些連接保持活躍,這樣就保證了我們只需要連接集羣中的任意一個節點,就可以獲取到其他節點的數據。

那麼redis 是如何合理分配這些節點和數據的呢?

Redis 集羣沒有並使用傳統的一致性哈希來分配數據,而是採用另外一種叫做哈希槽 (hash slot)的方式來分配的。redis cluster 默認分配了 16384 個slot,當我們set一個key 時,會用CRC16算法來取模得到所屬的slot,然後將這個key 分到哈希槽區間的節點上,具體算法就是:CRC16(key) % 16384

注意的是:必須要3個以後的主節點,否則在創建集羣時會失敗,我們在後續會實踐到。

所以,我們假設現在有3個節點已經組成了集羣,分別是:A, B, C 三個節點,它們可以是一臺機器上的三個端口,也可以是三臺不同的服務器。那麼,採用哈希槽 (hash slot)的方式來分配16384個slot 的話,它們三個節點分別承擔的slot 區間是:

  • 節點A覆蓋0-5460;
  • 節點B覆蓋5461-10922;
  • 節點C覆蓋10923-16383.

如下圖所示:

這裏寫圖片描述

那麼,現在我想設置一個key ,比如叫my_name:

set my_name yangyi

按照redis cluster的哈希槽算法:CRC16('my_name')%16384 = 2412。 那麼就會把這個key 的存儲分配到 A 上了。

同樣,當我連接(A,B,C)任何一個節點想獲取my_name這個key時,也會這樣的算法,然後內部跳轉到B節點上獲取數據。

這種哈希槽的分配方式有好也有壞,好處就是很清晰,比如我想新增一個節點D,redis cluster的這種做法是從各個節點的前面各拿取一部分slot到D上,我會在接下來的實踐中實驗。大致就會變成這樣:

  • 節點A覆蓋1365-5460
  • 節點B覆蓋6827-10922
  • 節點C覆蓋12288-16383
  • 節點D覆蓋0-1364,5461-6826,10923-12287

同樣刪除一個節點也是類似,移動完成後就可以刪除這個節點了。

所以redis cluster 就是這樣的一個形狀:

這裏寫圖片描述

Redis Cluster主從模式

redis cluster 爲了保證數據的高可用性,加入了主從模式,一個主節點對應一個或多個從節點,主節點提供數據存取,從節點則是從主節點拉取數據備份,當這個主節點掛掉後,就會有這個從節點選取一個來充當主節點,從而保證集羣不會掛掉。

上面那個例子裏, 集羣有ABC三個主節點, 如果這3個節點都沒有加入從節點,如果B掛掉了,我們就無法訪問整個集羣了。A和C的slot也無法訪問。

所以我們在集羣建立的時候,一定要爲每個主節點都添加了從節點, 比如像這樣, 集羣包含主節點A、B、C, 以及從節點A1、B1、C1, 那麼即使B掛掉系統也可以繼續正確工作。

B1節點替代了B節點,所以Redis集羣將會選擇B1節點作爲新的主節點,集羣將會繼續正確地提供服務。 當B重新開啓後,它就會變成B1的從節點。

不過需要注意,如果節點B和B1同時掛了,Redis集羣就無法繼續正確地提供服務了。

流程下圖所示:

這裏寫圖片描述

redis cluster 動手實踐

網上有很多教程,我最先是按照這個教程(http://blog.51yip.com/nosql/1725.html) 一步步的按照這個教程來,可是在最後啓動集羣的時候第一臺機器的6379端口死活啓動不了,這樣就沒有3臺主服務器,就完成不了集羣。最後也沒找到解決辦法。[知道原因了:我把redis-trib.rb create --replicas 1的 這個1沒有寫!!!!

現在,還是按照官方的教程,全程再演示一次,官方教程是在一臺機器上啓動6個節點,3個當主,3個當從(http://redis.io/topics/cluster-tutorial):

先下載官方的redis 版本(3.0.5) : http://download.redis.io/releases/redis-3.0.5.tar.gz

下載不了,請自行翻牆。我這次是在centos6.5上演示,用的是root 賬戶。

如果之前已經下載了redis的 2.x版本,只需要將 /usr/local/bin/redis-* 這幾個命令先刪除即可。

1.解壓

  1. [root@web3 ~]# tar zxvf redis-3.0.5.tar.gz

2.安裝

  1. [root@web3 ~]# cd redis-3.0.5
  2. [root@web3 ~]# make && make install

3.將redis-trib.rb 複製到/usr/local/bin

  1. [root@web3 redis-3.0.5]# cd src/
  2. [root@web3 src]# cp redis-trib.rb /usr/local/bin

4.開始集羣搭建

  1. [root@web3 redis-3.0.5]# vi redis.conf
  2. #修改以下地方
  3. port 7000
  4. cluster-enabled yes
  5. cluster-config-file nodes.conf
  6. cluster-node-timeout 5000
  7. appendonly yes

新建6個節點:

  1. [root@web3 redis-3.0.5]# mkdir -p /usr/local/cluster-test
  2. [root@web3 redis-3.0.5]# cd /usr/local/cluster-test/
  3. [root@web3 cluster-test]# mkdir 7000
  4. [root@web3 cluster-test]# mkdir 7001
  5. [root@web3 cluster-test]# mkdir 7002
  6. [root@web3 cluster-test]# mkdir 7003
  7. [root@web3 cluster-test]# mkdir 7004
  8. [root@web3 cluster-test]# mkdir 7005

將redis.conf 分別拷貝到這6個文件夾中,並修改成對應的端口號

  1. #拷貝配置文件
  2. [root@web3 cluster-test]# cp /root/redis-3.0.5/redis.conf /usr/local/cluster-test/7000
  3. [root@web3 cluster-test]# cp /root/redis-3.0.5/redis.conf /usr/local/cluster-test/7001
  4. [root@web3 cluster-test]# cp /root/redis-3.0.5/redis.conf /usr/local/cluster-test/7002
  5. [root@web3 cluster-test]# cp /root/redis-3.0.5/redis.conf /usr/local/cluster-test/7003
  6. [root@web3 cluster-test]# cp /root/redis-3.0.5/redis.conf /usr/local/cluster-test/7004
  7. [root@web3 cluster-test]# cp /root/redis-3.0.5/redis.conf /usr/local/cluster-test/7005
  8. #修改端口號
  9. root@web3 cluster-test]# sed -i "s/7000/7001/g" /usr/local/cluster-test/7001/redis.conf
  10. [root@web3 cluster-test]# sed -i "s/7000/7002/g" /usr/local/cluster-test/7002/redis.conf
  11. [root@web3 cluster-test]# sed -i "s/7000/7003/g" /usr/local/cluster-test/7003/redis.conf
  12. [root@web3 cluster-test]# sed -i "s/7000/7004/g" /usr/local/cluster-test/7004/redis.conf
  13. [root@web3 cluster-test]# sed -i "s/7000/7005/g" /usr/local/cluster-test/7005/redis.conf

分別,啓動這6個節點

  1. [root@web3 cluster-test]# cd /usr/local/cluster-test/7000/
  2. [root@web3 7000]# redis-server redis.conf
  3. [root@web3 7000]# cd ../7001
  4. [root@web3 7001]# redis-server redis.conf
  5. [root@web3 7001]# cd ../7002
  6. [root@web3 7002]# redis-server redis.conf
  7. [root@web3 7002]# cd ../7003
  8. [root@web3 7003]# redis-server redis.conf
  9. [root@web3 7003]# cd ../7004
  10. [root@web3 7004]# redis-server redis.conf
  11. [root@web3 7004]# cd ../7005
  12. [root@web3 7005]# redis-server redis.conf
  13. [root@web3 7005]#

查看6個節點的啓動進程情況:

  1. [root@web3 7005]# ps -ef|grep redis
  2. root 11380 1 0 07:37 ? 00:00:00 redis-server *:7000 [cluster]
  3. root 11384 1 0 07:37 ? 00:00:00 redis-server *:7001 [cluster]
  4. root 11388 1 0 07:37 ? 00:00:00 redis-server *:7002 [cluster]
  5. root 11392 1 0 07:37 ? 00:00:00 redis-server *:7003 [cluster]
  6. root 11396 1 0 07:37 ? 00:00:00 redis-server *:7004 [cluster]
  7. root 11400 1 0 07:37 ? 00:00:00 redis-server *:7005 [cluster]
  8. root 11404 8259 0 07:38 pts/0 00:00:00 grep redis

將6個節點連在一起構招成集羣

需要用到的命令就是redis-trib.rb,這是官方的一個用ruby寫的一個操作redis cluster的命令,所以,你的機器上需要安裝ruby。我們先試一下這個命令:

  1. 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

因爲我們要新建集羣, 所以這裏使用create命令. --replicas 1 參數表示爲每個主節點創建一個從節點. 其他參數是實例的地址集合。

由於我機子上沒安裝ruby,所以,會報錯:

  1. /usr/bin/env: ruby: No such file or directory

那先安裝ruby和rubygems:

  1. [root@web3 7005]# yum install ruby ruby-devel rubygems rpm-build

然後,再執行一次,發現還是報錯:

  1. [root@web3 7005]# 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
  2. /usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require': no such file to load -- redis (LoadError)
  3. from /usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `require'
  4. from /usr/local/bin/redis-trib.rb:25
  5. [root@web3 7005]#

原來是ruby和redis的連接沒安裝好:

  1. [root@web3 7005]# gem install redis
  2. Successfully installed redis-3.2.1
  3. 1 gem installed
  4. Installing ri documentation for redis-3.2.1...
  5. Installing RDoc documentation for redis-3.2.1...

好了。最重要的時刻來臨了,勝敗成舉在此了,啊啊啊啊啊啊,好激動:

  1. [root@web3 7005]# 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
  2. >>> Creating cluster
  3. Connecting to node 127.0.0.1:7000: OK
  4. Connecting to node 127.0.0.1:7001: OK
  5. Connecting to node 127.0.0.1:7002: OK
  6. Connecting to node 127.0.0.1:7003: OK
  7. Connecting to node 127.0.0.1:7004: OK
  8. Connecting to node 127.0.0.1:7005: OK
  9. >>> Performing hash slots allocation on 6 nodes...
  10. Using 3 masters:
  11. 127.0.0.1:7000
  12. 127.0.0.1:7001
  13. 127.0.0.1:7002
  14. Adding replica 127.0.0.1:7003 to 127.0.0.1:7000
  15. Adding replica 127.0.0.1:7004 to 127.0.0.1:7001
  16. Adding replica 127.0.0.1:7005 to 127.0.0.1:7002
  17. M: 3707debcbe7be66d4a1968eaf3a5ffaf4308efa4 127.0.0.1:7000
  18. slots:0-5460 (5461 slots) master
  19. M: cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c 127.0.0.1:7001
  20. slots:5461-10922 (5462 slots) master
  21. M: dfa0754c7854a874a6ebd2613b86140ad97701fc 127.0.0.1:7002
  22. slots:10923-16383 (5461 slots) master
  23. S: d2237fdcfbba672de766b913d1186cebcb6e1761 127.0.0.1:7003
  24. replicates 3707debcbe7be66d4a1968eaf3a5ffaf4308efa4
  25. S: 4b4aef8b48c427a3c903518339d53b6447c58b93 127.0.0.1:7004
  26. replicates cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c
  27. S: 30858dbf483b61b9838d5c1f853a60beaa4e7afd 127.0.0.1:7005
  28. replicates dfa0754c7854a874a6ebd2613b86140ad97701fc
  29. Can I set the above configuration? (type 'yes' to accept): yes
  30. >>> Nodes configuration updated
  31. >>> Assign a different config epoch to each node
  32. >>> Sending CLUSTER MEET messages to join the cluster
  33. Waiting for the cluster to join...
  34. >>> Performing Cluster Check (using node 127.0.0.1:7000)
  35. M: 3707debcbe7be66d4a1968eaf3a5ffaf4308efa4 127.0.0.1:7000
  36. slots:0-5460 (5461 slots) master
  37. M: cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c 127.0.0.1:7001
  38. slots:5461-10922 (5462 slots) master
  39. M: dfa0754c7854a874a6ebd2613b86140ad97701fc 127.0.0.1:7002
  40. slots:10923-16383 (5461 slots) master
  41. M: d2237fdcfbba672de766b913d1186cebcb6e1761 127.0.0.1:7003
  42. slots: (0 slots) master
  43. replicates 3707debcbe7be66d4a1968eaf3a5ffaf4308efa4
  44. M: 4b4aef8b48c427a3c903518339d53b6447c58b93 127.0.0.1:7004
  45. slots: (0 slots) master
  46. replicates cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c
  47. M: 30858dbf483b61b9838d5c1f853a60beaa4e7afd 127.0.0.1:7005
  48. slots: (0 slots) master
  49. replicates dfa0754c7854a874a6ebd2613b86140ad97701fc
  50. [OK] All nodes agree about slots configuration.
  51. >>> Check for open slots...
  52. >>> Check slots coverage...
  53. [OK] All 16384 slots covered.

哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈。終於他媽的成功了!!!!

Redis-trib會提示你做了什麼配置, 輸入yes接受. 集羣就被配置和加入了, 意思是, 實例會經過互相交流後啓動。

測試集羣的狀態:

  1. [root@web3 7000]# redis-trib.rb check 127.0.0.1:7000
  2. Connecting to node 127.0.0.1:7000: OK
  3. Connecting to node 127.0.0.1:7002: OK
  4. Connecting to node 127.0.0.1:7003: OK
  5. Connecting to node 127.0.0.1:7005: OK
  6. Connecting to node 127.0.0.1:7001: OK
  7. Connecting to node 127.0.0.1:7004: OK
  8. >>> Performing Cluster Check (using node 127.0.0.1:7000)
  9. M: 3707debcbe7be66d4a1968eaf3a5ffaf4308efa4 127.0.0.1:7000
  10. slots:0-5460 (5461 slots) master
  11. 1 additional replica(s)
  12. M: dfa0754c7854a874a6ebd2613b86140ad97701fc 127.0.0.1:7002
  13. slots:10923-16383 (5461 slots) master
  14. 1 additional replica(s)
  15. S: d2237fdcfbba672de766b913d1186cebcb6e1761 127.0.0.1:7003
  16. slots: (0 slots) slave
  17. replicates 3707debcbe7be66d4a1968eaf3a5ffaf4308efa4
  18. S: 30858dbf483b61b9838d5c1f853a60beaa4e7afd 127.0.0.1:7005
  19. slots: (0 slots) slave
  20. replicates dfa0754c7854a874a6ebd2613b86140ad97701fc
  21. M: cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c 127.0.0.1:7001
  22. slots:5461-10922 (5462 slots) master
  23. 1 additional replica(s)
  24. S: 4b4aef8b48c427a3c903518339d53b6447c58b93 127.0.0.1:7004
  25. slots: (0 slots) slave
  26. replicates cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c
  27. [OK] All nodes agree about slots configuration.
  28. >>> Check for open slots...
  29. >>> Check slots coverage...
  30. [OK] All 16384 slots covered.

可以看到有3個主節點,3個從節點。每個節點都是成功的連接狀態。

3個主節點[M]是:

7000 (3707debcbe7be66d4a1968eaf3a5ffaf4308efa4) 
7001 (cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c) 
7002 (dfa0754c7854a874a6ebd2613b86140ad97701fc)

3個從節點[S]是:

7003 (d2237fdcfbba672de766b913d1186cebcb6e1761)->7000 
7004 (4b4aef8b48c427a3c903518339d53b6447c58b93)->7001 
7005 (30858dbf483b61b9838d5c1f853a60beaa4e7afd) ->7002

5. 測試連接集羣

剛纔集羣搭建成功了。按照redis cluster的特點,它是去中心化,每個節點都是對等的,所以,你連接哪個節點都可以獲取和設置數據,我們來試一下。

redis-cli是redis默認的客戶端工具,啓動時加上`-c`參數,就可以連接到集羣。

連接任意一個節點端口:

  1. [root@web3 7000]# redis-cli -c -p 7000
  2. 127.0.0.1:7000>

設置一個值:

  1. 127.0.0.1:7000> set my_name yangyi
  2. -> Redirected to slot [12803] located at 127.0.0.1:7002
  3. OK
  4. 127.0.0.1:7002> get my_name
  5. "yangyi"
  6. 127.0.0.1:7002>

前面理論知識我們知道了,分配key的時候,它會使用CRC16('my_name')%16384算法,來計算,將這個key 放到哪個節點,這裏分配到了12803slot 就分配到了7002(10923-16383)這個節點上。

Redirected to slot [12803] located at 127.0.0.1:7002

redis cluster 採用的方式很直接,它直接跳轉到7002 節點了,而不是還在自身的7000節點。

好,現在我們連接7005這個節點:

  1. [root@web3 7000]# redis-cli -c -p 7005
  2. 127.0.0.1:7005> get my_name
  3. -> Redirected to slot [12803] located at 127.0.0.1:7002
  4. "yangyi"
  5. 127.0.0.1:7002>

我們同樣是獲取my_name的值,它同樣也是跳轉到了7002上。

我們再嘗試一些其他的可以:

  1. 127.0.0.1:7002> set age 123
  2. -> Redirected to slot [741] located at 127.0.0.1:7000
  3. OK
  4. 127.0.0.1:7000> set height 565
  5. -> Redirected to slot [8223] located at 127.0.0.1:7001
  6. OK
  7. 127.0.0.1:7001> set sex 1
  8. -> Redirected to slot [2584] located at 127.0.0.1:7000
  9. OK
  10. 127.0.0.1:7000> set home china
  11. -> Redirected to slot [10814] located at 127.0.0.1:7001
  12. OK
  13. 127.0.0.1:7001> set city shanghai
  14. -> Redirected to slot [11479] located at 127.0.0.1:7002
  15. OK
  16. 127.0.0.1:7002> set citylocate shanghaipudong
  17. OK
  18. 127.0.0.1:7001> set wsdwxzx hhh
  19. -> Redirected to slot [15487] located at 127.0.0.1:7002
  20. OK
  21. 127.0.0.1:7002> zadd erew 333 rrr
  22. -> Redirected to slot [10576] located at 127.0.0.1:7001
  23. (integer) 1
  24. 127.0.0.1:7000> zrange erew 0 -1
  25. -> Redirected to slot [10576] located at 127.0.0.1:7001
  26. 1) "rrr"
  27. 127.0.0.1:7001>

可以看出,數據都會在7000-7002 這3個主節點來跳轉存粗。

6. 測試集羣中的節點掛掉

上面我們建立來了一個集羣。3個主節點[7000-7002]提供數據存粗和讀取,3個從節點[7003-7005]則是負責把[7000-7002]的數據同步到自己的節點上來,我們來看一下[7003-7005]的appendonly.aof的內容。看看是不是不這樣:

  1. [root@web3 7005]# cd /usr/local/cluster-test/7003
  2. [root@web3 7003]# vi appendonly.aof
  3. *2
  4. $6
  5. SELECT
  6. $1
  7. 0
  8. *3
  9. $3
  10. set
  11. $3
  12. age
  13. $3
  14. 123
  15. *3
  16. $3
  17. set
  18. $3
  19. sex
  20. $1
  21. 1
  22. *3
  23. $3
  24. set
  25. $3
  26. job
  27. $3
  28. php

我們看下,的確是從7000節點上同步過來的數據,7004,7005也是。

下面,我們先來模擬其中一臺Master主服務器掛掉的情況,那就7000掛掉吧:

  1. [root@web3 7003]# ps -ef|grep redis
  2. root 11380 1 0 07:37 ? 00:00:03 redis-server *:7000 [cluster]
  3. root 11384 1 0 07:37 ? 00:00:03 redis-server *:7001 [cluster]
  4. root 11388 1 0 07:37 ? 00:00:03 redis-server *:7002 [cluster]
  5. root 11392 1 0 07:37 ? 00:00:03 redis-server *:7003 [cluster]
  6. root 11396 1 0 07:37 ? 00:00:04 redis-server *:7004 [cluster]
  7. root 11400 1 0 07:37 ? 00:00:03 redis-server *:7005 [cluster]
  8. [root@web3 7003]# kill 11380
  9. [root@web3 7003]#

好,安裝前面的理論,7000主節點掛掉了,那麼這個時候,7000的從節點只有7003一個,肯定7003就會被選舉稱Master節點了:

  1. [root@web3 7003]# redis-trib.rb check 127.0.0.1:7000
  2. Connecting to node 127.0.0.1:7000: [ERR] Sorry, can't connect to node 127.0.0.1:7000
  3. [root@web3 7003]# redis-trib.rb check 127.0.0.1:7001
  4. Connecting to node 127.0.0.1:7001: OK
  5. Connecting to node 127.0.0.1:7004: OK
  6. Connecting to node 127.0.0.1:7005: OK
  7. Connecting to node 127.0.0.1:7003: OK
  8. Connecting to node 127.0.0.1:7002: OK
  9. >>> Performing Cluster Check (using node 127.0.0.1:7001)
  10. M: cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c 127.0.0.1:7001
  11. slots:5461-10922 (5462 slots) master
  12. 1 additional replica(s)
  13. S: 4b4aef8b48c427a3c903518339d53b6447c58b93 127.0.0.1:7004
  14. slots: (0 slots) slave
  15. replicates cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c
  16. S: 30858dbf483b61b9838d5c1f853a60beaa4e7afd 127.0.0.1:7005
  17. slots: (0 slots) slave
  18. replicates dfa0754c7854a874a6ebd2613b86140ad97701fc
  19. M: d2237fdcfbba672de766b913d1186cebcb6e1761 127.0.0.1:7003
  20. slots:0-5460 (5461 slots) master
  21. 0 additional replica(s)
  22. M: dfa0754c7854a874a6ebd2613b86140ad97701fc 127.0.0.1:7002
  23. slots:10923-16383 (5461 slots) master
  24. 1 additional replica(s)
  25. [OK] All nodes agree about slots configuration.
  26. >>> Check for open slots...
  27. >>> Check slots coverage...
  28. [OK] All 16384 slots covered.
  29. [root@web3 7003]#

看了下,上面有了三個M 節點了,果真,7003被選取成了替代7000成爲主節點了。那我們來獲取原先存在7000節點的數據:

  1. [root@web3 7003]# redis-cli -c -p 7001
  2. 127.0.0.1:7001> get sex
  3. -> Redirected to slot [2584] located at 127.0.0.1:7003
  4. "1"
  5. 127.0.0.1:7003>

數據果真沒有丟失,而是從7003上面獲取了。

OK。我們再來模擬 7000節點重新啓動了的情況,那麼它還會自動加入到集羣中嗎?那麼,7000這個節點上充當什麼角色呢? 我們試一下:

重新啓動 7000 節點:

  1. [root@web3 7003]# cd ../7000
  2. [root@web3 7000]# ll
  3. total 56
  4. -rw-r--r-- 1 root root 114 Oct 17 08:16 appendonly.aof
  5. -rw-r--r-- 1 root root 43 Oct 17 08:37 dump.rdb
  6. -rw-r--r-- 1 root root 745 Oct 17 08:00 nodes.conf
  7. -rw-r--r-- 1 root root 41550 Oct 17 07:37 redis.conf
  8. [root@web3 7000]# redis-server redis.conf

啓動好了,現在,再來檢查一下集羣:

  1. redis-trib.rb check 127.0.0.1:700`
  1. [root@web3 7000]# redis-trib.rb check 127.0.0.1:7001
  2. Connecting to node 127.0.0.1:7001: OK
  3. Connecting to node 127.0.0.1:7004: OK
  4. Connecting to node 127.0.0.1:7005: OK
  5. Connecting to node 127.0.0.1:7003: OK
  6. Connecting to node 127.0.0.1:7000: OK
  7. Connecting to node 127.0.0.1:7002: OK
  8. >>> Performing Cluster Check (using node 127.0.0.1:7001)
  9. M: cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c 127.0.0.1:7001
  10. slots:5461-10922 (5462 slots) master
  11. 1 additional replica(s)
  12. S: 4b4aef8b48c427a3c903518339d53b6447c58b93 127.0.0.1:7004
  13. slots: (0 slots) slave
  14. replicates cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c
  15. S: 30858dbf483b61b9838d5c1f853a60beaa4e7afd 127.0.0.1:7005
  16. slots: (0 slots) slave
  17. replicates dfa0754c7854a874a6ebd2613b86140ad97701fc
  18. M: d2237fdcfbba672de766b913d1186cebcb6e1761 127.0.0.1:7003
  19. slots:0-5460 (5461 slots) master
  20. 1 additional replica(s)
  21. S: 3707debcbe7be66d4a1968eaf3a5ffaf4308efa4 127.0.0.1:7000
  22. slots: (0 slots) slave
  23. replicates d2237fdcfbba672de766b913d1186cebcb6e1761
  24. M: dfa0754c7854a874a6ebd2613b86140ad97701fc 127.0.0.1:7002
  25. slots:10923-16383 (5461 slots) master
  26. 1 additional replica(s)
  27. [OK] All nodes agree about slots configuration.
  28. >>> Check for open slots...
  29. >>> Check slots coverage...
  30. [OK] All 16384 slots covered.

你看,7000節點啓動起來了,它卻作爲了 70003 的從節點了。驗證了之前的這張圖:

這裏寫圖片描述

一定要保證有3個master 節點,不然,集羣就掛掉了。

7. 集羣中新加入節點

我們再來測試一下,新加入一個節點,分2種情況,1是作爲主節點,2是作爲一個節點的從節點。我們分別來試一下:

1. 新建一個 7006 節點 作爲一個新的主節點加入:

首先就是新建一個 7006的文件夾和redis.conf:

  1. [root@web3 cluster-test]# cd /usr/local/cluster-test/
  2. [root@web3 cluster-test]# mkdir 7006
  3. [root@web3 cluster-test]# cp 7005/redis.conf 7006/redis.conf
  4. #修改端口
  5. [root@web3 cluster-test]sed -i "s/7005/7006/g" /usr/local/cluster-test/7006/redis.conf

啓動 7006

  1. [root@web3 7006]# redis-server redis.conf
  2. [root@web3 7006]# ps -ef|grep redis
  3. root 11384 1 0 07:37 ? 00:00:05 redis-server *:7001 [cluster]
  4. root 11388 1 0 07:37 ? 00:00:05 redis-server *:7002 [cluster]
  5. root 11392 1 0 07:37 ? 00:00:05 redis-server *:7003 [cluster]
  6. root 11396 1 0 07:37 ? 00:00:06 redis-server *:7004 [cluster]
  7. root 11400 1 0 07:37 ? 00:00:05 redis-server *:7005 [cluster]
  8. root 12100 1 0 08:42 ? 00:00:01 redis-server *:7000 [cluster]
  9. root 12132 1 0 09:09 ? 00:00:00 redis-server *:7006 [cluster]
  10. root 12136 8259 0 09:10 pts/0 00:00:00 grep redis

ok,7006 端口已經啓動好了,並且進程也存在了,下面就是加入到集羣中,也是得用到redis-trib.rb命令:

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

add-node是加入指令,127.0.0.1:7006 表示新加入的節點,127.0.0.1:7000 表示加入的集羣的一個節點,用來辨識是哪個集羣,理論上哪個都可以。

  1. [root@web3 7006]# redis-trib.rb add-node 127.0.0.1:7006 127.0.0.1:7000
  2. >>> Adding node 127.0.0.1:7006 to cluster 127.0.0.1:7000
  3. Connecting to node 127.0.0.1:7000: OK
  4. Connecting to node 127.0.0.1:7004: OK
  5. Connecting to node 127.0.0.1:7005: OK
  6. Connecting to node 127.0.0.1:7003: OK
  7. Connecting to node 127.0.0.1:7001: OK
  8. Connecting to node 127.0.0.1:7002: OK
  9. >>> Performing Cluster Check (using node 127.0.0.1:7000)
  10. S: 3707debcbe7be66d4a1968eaf3a5ffaf4308efa4 127.0.0.1:7000
  11. slots: (0 slots) slave
  12. replicates d2237fdcfbba672de766b913d1186cebcb6e1761
  13. S: 4b4aef8b48c427a3c903518339d53b6447c58b93 127.0.0.1:7004
  14. slots: (0 slots) slave
  15. replicates cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c
  16. S: 30858dbf483b61b9838d5c1f853a60beaa4e7afd 127.0.0.1:7005
  17. slots: (0 slots) slave
  18. replicates dfa0754c7854a874a6ebd2613b86140ad97701fc
  19. M: d2237fdcfbba672de766b913d1186cebcb6e1761 127.0.0.1:7003
  20. slots:0-5460 (5461 slots) master
  21. 1 additional replica(s)
  22. M: cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c 127.0.0.1:7001
  23. slots:5461-10922 (5462 slots) master
  24. 1 additional replica(s)
  25. M: dfa0754c7854a874a6ebd2613b86140ad97701fc 127.0.0.1:7002
  26. slots:10923-16383 (5461 slots) master
  27. 1 additional replica(s)
  28. [OK] All nodes agree about slots configuration.
  29. >>> Check for open slots...
  30. >>> Check slots coverage...
  31. [OK] All 16384 slots covered.
  32. Connecting to node 127.0.0.1:7006: OK
  33. >>> Send CLUSTER MEET to node 127.0.0.1:7006 to make it join the cluster.
  34. [OK] New node added correctly.

這個命令執行完成之後,它順便檢查來其他的6個節點都是成功的,最後幾句話:

  1. Connecting to node 127.0.0.1:7006: OK
  2. >>> Send CLUSTER MEET to node 127.0.0.1:7006 to make it join the cluster.
  3. [OK] New node added correctly.

表示新的節點連接成功了,而且也已經加入到集羣了,我們再來檢查一下:

  1. [root@web3 7006]# redis-trib.rb check 127.0.0.1:7006
  2. Connecting to node 127.0.0.1:7006: OK
  3. Connecting to node 127.0.0.1:7001: OK
  4. Connecting to node 127.0.0.1:7004: OK
  5. Connecting to node 127.0.0.1:7000: OK
  6. Connecting to node 127.0.0.1:7002: OK
  7. Connecting to node 127.0.0.1:7005: OK
  8. Connecting to node 127.0.0.1:7003: OK
  9. >>> Performing Cluster Check (using node 127.0.0.1:7006)
  10. M: efc3131fbdc6cf929720e0e0f7136cae85657481 127.0.0.1:7006
  11. slots: (0 slots) master
  12. 0 additional replica(s)
  13. M: cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c 127.0.0.1:7001
  14. slots:5461-10922 (5462 slots) master
  15. 1 additional replica(s)
  16. S: 4b4aef8b48c427a3c903518339d53b6447c58b93 127.0.0.1:7004
  17. slots: (0 slots) slave
  18. replicates cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c
  19. S: 3707debcbe7be66d4a1968eaf3a5ffaf4308efa4 127.0.0.1:7000
  20. slots: (0 slots) slave
  21. replicates d2237fdcfbba672de766b913d1186cebcb6e1761
  22. M: dfa0754c7854a874a6ebd2613b86140ad97701fc 127.0.0.1:7002
  23. slots:10923-16383 (5461 slots) master
  24. 1 additional replica(s)
  25. S: 30858dbf483b61b9838d5c1f853a60beaa4e7afd 127.0.0.1:7005
  26. slots: (0 slots) slave
  27. replicates dfa0754c7854a874a6ebd2613b86140ad97701fc
  28. M: d2237fdcfbba672de766b913d1186cebcb6e1761 127.0.0.1:7003
  29. slots:0-5460 (5461 slots) master
  30. 1 additional replica(s)
  31. [OK] All nodes agree about slots configuration.
  32. >>> Check for open slots...
  33. >>> Check slots coverage...
  34. [OK] All 16384 slots covered.

可以看到了,7006 已經成爲了主節點。

我們也可以連接到客戶端後,來看這個集羣節點情況:

  1. [root@web3 7006]# redis-cli -c -p 7006
  2. 127.0.0.1:7006> cluster nodes
  3. cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c 127.0.0.1:7001 master - 0 1445073797986 2 connected 5461-10922
  4. 4b4aef8b48c427a3c903518339d53b6447c58b93 127.0.0.1:7004 slave cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c 0 1445073799497 2 connected
  5. efc3131fbdc6cf929720e0e0f7136cae85657481 127.0.0.1:7006 myself,master - 0 0 0 connected
  6. 3707debcbe7be66d4a1968eaf3a5ffaf4308efa4 127.0.0.1:7000 slave d2237fdcfbba672de766b913d1186cebcb6e1761 0 1445073797482 7 connected
  7. dfa0754c7854a874a6ebd2613b86140ad97701fc 127.0.0.1:7002 master - 0 1445073798489 3 connected 10923-16383
  8. 30858dbf483b61b9838d5c1f853a60beaa4e7afd 127.0.0.1:7005 slave dfa0754c7854a874a6ebd2613b86140ad97701fc 0 1445073798993 3 connected
  9. d2237fdcfbba672de766b913d1186cebcb6e1761 127.0.0.1:7003 master - 0 1445073799498 7 connected 0-5460
  10. 127.0.0.1:7006>

可以看到 有7個節點。7006 也作爲了master節點,但是,但是,你看看後面的:

  1. efc3131fbdc6cf929720e0e0f7136cae85657481 127.0.0.1:7006
  2. slots: (0 slots) master

臥槽,什麼情況。o slots 也就是說,雖然它現在是主節點,但是,缺沒有分配任何節點給它,也就是它現在還不負責數據存取。那加上去有毛用啊!!!!

看來,redis cluster 不是在新加節點的時候幫我們做好了遷移工作,需要我們手動對集羣進行重新分片遷移,也是這個命令:

redis-trib.rb reshard 127.0.0.1:7000

這個命令是用來遷移slot節點的,後面的127.0.0.1:7000是表示是哪個集羣,端口填[7000-7006]都可以,我們運行下:

  1. [root@web3 7006]# redis-trib.rb reshard 127.0.0.1:7000
  2. Connecting to node 127.0.0.1:7006: OK
  3. Connecting to node 127.0.0.1:7001: OK
  4. Connecting to node 127.0.0.1:7004: OK
  5. Connecting to node 127.0.0.1:7000: OK
  6. Connecting to node 127.0.0.1:7002: OK
  7. Connecting to node 127.0.0.1:7005: OK
  8. Connecting to node 127.0.0.1:7003: OK
  9. >>> Performing Cluster Check (using node 127.0.0.1:7006)
  10. M: efc3131fbdc6cf929720e0e0f7136cae85657481 127.0.0.1:7006
  11. slots: (0 slots) master
  12. 0 additional replica(s)
  13. M: cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c 127.0.0.1:7001
  14. slots:5461-10922 (5462 slots) master
  15. 1 additional replica(s)
  16. S: 4b4aef8b48c427a3c903518339d53b6447c58b93 127.0.0.1:7004
  17. slots: (0 slots) slave
  18. replicates cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c
  19. S: 3707debcbe7be66d4a1968eaf3a5ffaf4308efa4 127.0.0.1:7000
  20. slots: (0 slots) slave
  21. replicates d2237fdcfbba672de766b913d1186cebcb6e1761
  22. M: dfa0754c7854a874a6ebd2613b86140ad97701fc 127.0.0.1:7002
  23. slots:10923-16383 (5461 slots) master
  24. 1 additional replica(s)
  25. S: 30858dbf483b61b9838d5c1f853a60beaa4e7afd 127.0.0.1:7005
  26. slots: (0 slots) slave
  27. replicates dfa0754c7854a874a6ebd2613b86140ad97701fc
  28. M: d2237fdcfbba672de766b913d1186cebcb6e1761 127.0.0.1:7003
  29. slots:0-5460 (5461 slots) master
  30. 1 additional replica(s)
  31. [OK] All nodes agree about slots configuration.
  32. >>> Check for open slots...
  33. >>> Check slots coverage...
  34. [OK] All 16384 slots covered.
  35. How many slots do you want to move (from 1 to 16384)?

它提示我們需要遷移多少slot到7006上,我們可以算一下:16384/4 = 4096,也就是說,爲了平衡分配起見,我們需要移動4096個槽點到7006上。

好,那輸入4096:

  1. How many slots do you want to move (from 1 to 16384)? 4096
  2. What is the receiving node ID?

它又提示我們,接受的node ID是多少,7006的id 我們通過上面就可以看到是efc3131fbdc6cf929720e0e0f7136cae85657481 :

  1. What is the receiving node ID? efc3131fbdc6cf929720e0e0f7136cae85657481
  2. Please enter all the source node IDs.
  3. Type 'all' to use all the nodes as source nodes for the hash slots.
  4. Type 'done' once you entered all the source nodes IDs.
  5. Source node #1:

接着, redis-trib 會向你詢問重新分片的源節點(source node), 也即是, 要從哪個節點中取出 4096 個哈希槽, 並將這些槽移動到7006節點上面。

如果我們不打算從特定的節點上取出指定數量的哈希槽, 那麼可以向 redis-trib 輸入 all , 這樣的話, 集羣中的所有主節點都會成爲源節點, redis-trib 將從各個源節點中各取出一部分哈希槽, 湊夠 4096 個, 然後移動到7006節點上:

  1. Source node #1:all

接下來就開始遷移了,並且會詢問你是否確認:

  1. Moving slot 1359 from d2237fdcfbba672de766b913d1186cebcb6e1761
  2. Moving slot 1360 from d2237fdcfbba672de766b913d1186cebcb6e1761
  3. Moving slot 1361 from d2237fdcfbba672de766b913d1186cebcb6e1761
  4. Moving slot 1362 from d2237fdcfbba672de766b913d1186cebcb6e1761
  5. Moving slot 1363 from d2237fdcfbba672de766b913d1186cebcb6e1761
  6. Moving slot 1364 from d2237fdcfbba672de766b913d1186cebcb6e1761
  7. Do you want to proceed with the proposed reshard plan (yes/no)?

輸入 yes 並使用按下回車之後, redis-trib 就會正式開始執行重新分片操作, 將指定的哈希槽從源節點一個個地移動到7006節點上面。

遷移完畢之後,我們來檢查下:

  1. [root@web3 7006]# redis-trib.rb check 127.0.0.1:7000
  2. Connecting to node 127.0.0.1:7000: OK
  3. Connecting to node 127.0.0.1:7006: OK
  4. Connecting to node 127.0.0.1:7004: OK
  5. Connecting to node 127.0.0.1:7005: OK
  6. Connecting to node 127.0.0.1:7003: OK
  7. Connecting to node 127.0.0.1:7001: OK
  8. Connecting to node 127.0.0.1:7002: OK
  9. >>> Performing Cluster Check (using node 127.0.0.1:7000)
  10. S: 3707debcbe7be66d4a1968eaf3a5ffaf4308efa4 127.0.0.1:7000
  11. slots: (0 slots) slave
  12. replicates d2237fdcfbba672de766b913d1186cebcb6e1761
  13. M: efc3131fbdc6cf929720e0e0f7136cae85657481 127.0.0.1:7006
  14. slots:0-1364,5461-6826,10923-12287 (4096 slots) master
  15. 0 additional replica(s)
  16. S: 4b4aef8b48c427a3c903518339d53b6447c58b93 127.0.0.1:7004
  17. slots: (0 slots) slave
  18. replicates cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c
  19. S: 30858dbf483b61b9838d5c1f853a60beaa4e7afd 127.0.0.1:7005
  20. slots: (0 slots) slave
  21. replicates dfa0754c7854a874a6ebd2613b86140ad97701fc
  22. M: d2237fdcfbba672de766b913d1186cebcb6e1761 127.0.0.1:7003
  23. slots:1365-5460 (4096 slots) master
  24. 1 additional replica(s)
  25. M: cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c 127.0.0.1:7001
  26. slots:6827-10922 (4096 slots) master
  27. 1 additional replica(s)
  28. M: dfa0754c7854a874a6ebd2613b86140ad97701fc 127.0.0.1:7002
  29. slots:12288-16383 (4096 slots) master
  30. 1 additional replica(s)
  31. [OK] All nodes agree about slots configuration.
  32. >>> Check for open slots...
  33. >>> Check slots coverage...
  34. [OK] All 16384 slots covered.

我們着重看7006:

0-1364,5461-6826,10923-12287 (4096 slots)

這些原來在其他節點上的slot 杯遷移到了7006上。原來,它只是間隔的移動,並不是銜接的整體移動,我們看下有數據了沒?

  1. [root@web3 7006]# redis-cli -c -p 7006
  2. 127.0.0.1:7006> keys *
  3. 1) "city"
  4. 2) "age"
  5. 3) "citylocate"
  6. 127.0.0.1:7006> get city
  7. "shanghai"

非常贊,已經有數據了。

2. 新建一個 7007從節點,作爲7006的從節點

我們再新建一個節點7007,步驟類似,就先省略了。建好後,啓動起來,我們看如何把它加入到集羣中的從節點中:

[root@web3 7007]# redis-trib.rb add-node --slave 127.0.0.1:7007 127.0.0.1:7000

add-node的時候加上--slave表示是加入到從節點中,但是這樣加,是隨機的。這裏的命令行完全像我們在添加一個新主服務器時使用的一樣,所以我們沒有指定要給哪個主服 務器添加副本。這種情況下,redis-trib 會將7007作爲一個具有較少副本的隨機的主服務器的副本。

那麼,你猜,它會作爲誰的從節點,應該是7006,因爲7006還沒有從節點。我們運行下。

  1. [root@web3 7007]# redis-trib.rb add-node --slave 127.0.0.1:7007 127.0.0.1:7000
  2. ...
  3. ...
  4. [OK] All 16384 slots covered.
  5. Automatically selected master 127.0.0.1:7006
  6. Connecting to node 127.0.0.1:7007: OK
  7. >>> Send CLUSTER MEET to node 127.0.0.1:7007 to make it join the cluster.
  8. Waiting for the cluster to join.
  9. >>> Configure node as replica of 127.0.0.1:7006.
  10. [OK] New node added correctly.

上面提示說,自動選擇了7006作爲master節點。並且成功了。我們檢查下:

  1. [root@web3 7007]# redis-trib.rb check 127.0.0.1:7000
  2. Connecting to node 127.0.0.1:7000: OK
  3. Connecting to node 127.0.0.1:7006: OK
  4. Connecting to node 127.0.0.1:7004: OK
  5. Connecting to node 127.0.0.1:7005: OK
  6. Connecting to node 127.0.0.1:7003: OK
  7. Connecting to node 127.0.0.1:7001: OK
  8. Connecting to node 127.0.0.1:7007: OK
  9. Connecting to node 127.0.0.1:7002: OK
  10. >>> Performing Cluster Check (using node 127.0.0.1:7000)
  11. S: 3707debcbe7be66d4a1968eaf3a5ffaf4308efa4 127.0.0.1:7000
  12. slots: (0 slots) slave
  13. replicates d2237fdcfbba672de766b913d1186cebcb6e1761
  14. M: efc3131fbdc6cf929720e0e0f7136cae85657481 127.0.0.1:7006
  15. slots:0-1364,5461-6826,10923-12287 (4096 slots) master
  16. 1 additional replica(s)
  17. S: 4b4aef8b48c427a3c903518339d53b6447c58b93 127.0.0.1:7004
  18. slots: (0 slots) slave
  19. replicates cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c
  20. S: 30858dbf483b61b9838d5c1f853a60beaa4e7afd 127.0.0.1:7005
  21. slots: (0 slots) slave
  22. replicates dfa0754c7854a874a6ebd2613b86140ad97701fc
  23. M: d2237fdcfbba672de766b913d1186cebcb6e1761 127.0.0.1:7003
  24. slots:1365-5460 (4096 slots) master
  25. 1 additional replica(s)
  26. M: cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c 127.0.0.1:7001
  27. slots:6827-10922 (4096 slots) master
  28. 1 additional replica(s)
  29. S: 86d05e7c2b197dc182b5e71069e791d033cf899e 127.0.0.1:7007
  30. slots: (0 slots) slave
  31. replicates efc3131fbdc6cf929720e0e0f7136cae85657481
  32. M: dfa0754c7854a874a6ebd2613b86140ad97701fc 127.0.0.1:7002
  33. slots:12288-16383 (4096 slots) master
  34. 1 additional replica(s)
  35. [OK] All nodes agree about slots configuration.
  36. >>> Check for open slots...
  37. >>> Check slots coverage...
  38. [OK] All 16384 slots covered.

果然,7007加入到了7006的從節點當中。

你說,我如果想指定一個主節點行不行?當然可以。我們再建一個7008節點。

  1. redis-trib.rb add-node --slave --master-id efc3131fbdc6cf929720e0e0f7136cae85657481 127.0.0.1:7008 127.0.0.1:7000

--master-id 表示指定的主節點node id。這裏指定的是 7006 這個主節點。

  1. Waiting for the cluster to join.
  2. >>> Configure node as replica of 127.0.0.1:7006.
  3. [OK] New node added correctly.
  4. [root@web3 7008]#

提示我們已經作爲7006的附屬品,也就是加入到7006的從節點來了,照這麼說,7006就有2個從節點了,我們看一下:

  1. redis-cli -c -p 7008 cluster nodes |grep efc3131fbdc6cf929720e0e0f7136cae85657481
  2. 86d05e7c2b197dc182b5e71069e791d033cf899e 127.0.0.1:7007 slave efc3131fbdc6cf929720e0e0f7136cae85657481 0 1445089507786 8 connected
  3. efc3131fbdc6cf929720e0e0f7136cae85657481 127.0.0.1:7006 master - 0 1445089508289 8 connected 0-1364 5461-6826 10923-12287
  4. 44321e7d619410dc4e0a8745366610a0d06d2395 127.0.0.1:7008 myself,slave efc3131fbdc6cf929720e0e0f7136cae85657481 0 0 0 connected

我們過濾了下看結果,果真,7007和7008是7006的從節點了。

剛好,我們再做一個實驗,我把7006的殺掉,看7007和7008誰會變成主節點:

  1. [root@web3 7008]# ps -ef|grep redis
  2. root 11384 1 0 09:56 ? 00:00:16 redis-server *:7001 [cluster]
  3. root 11388 1 0 09:56 ? 00:00:16 redis-server *:7002 [cluster]
  4. root 11392 1 0 09:56 ? 00:00:16 redis-server *:7003 [cluster]
  5. root 11396 1 0 09:56 ? 00:00:15 redis-server *:7004 [cluster]
  6. root 11400 1 0 09:56 ? 00:00:15 redis-server *:7005 [cluster]
  7. root 12100 1 0 11:01 ? 00:00:11 redis-server *:7000 [cluster]
  8. root 12132 1 0 11:28 ? 00:00:11 redis-server *:7006 [cluster]
  9. root 12202 1 0 13:14 ? 00:00:02 redis-server *:7007 [cluster]
  10. root 12219 1 0 13:39 ? 00:00:00 redis-server *:7008 [cluster]
  11. root 12239 8259 0 13:49 pts/0 00:00:00 grep redis
  12. [root@web3 7008]# kill 12132
  13. [root@web3 7008]# redis-cli -c -p 7008
  14. 127.0.0.1:7008> get ss5rtr
  15. -> Redirected to slot [1188] located at 127.0.0.1:7007
  16. "66"
  17. 127.0.0.1:7007> cluster nodes
  18. efc3131fbdc6cf929720e0e0f7136cae85657481 127.0.0.1:7006 master,fail - 1445089780668 1445089779963 8 disconnected
  19. d2237fdcfbba672de766b913d1186cebcb6e1761 127.0.0.1:7003 master - 0 1445089812195 7 connected 1365-5460
  20. 30858dbf483b61b9838d5c1f853a60beaa4e7afd 127.0.0.1:7005 slave dfa0754c7854a874a6ebd2613b86140ad97701fc 0 1445089813710 3 connected
  21. 86d05e7c2b197dc182b5e71069e791d033cf899e 127.0.0.1:7007 myself,master - 0 0 10 connected 0-1364 5461-6826 10923-12287
  22. cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c 127.0.0.1:7001 master - 0 1445089814214 2 connected 6827-10922
  23. 4b4aef8b48c427a3c903518339d53b6447c58b93 127.0.0.1:7004 slave cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c 0 1445089812701 2 connected
  24. 44321e7d619410dc4e0a8745366610a0d06d2395 127.0.0.1:7008 slave 86d05e7c2b197dc182b5e71069e791d033cf899e 0 1445089814214 10 connected
  25. 3707debcbe7be66d4a1968eaf3a5ffaf4308efa4 127.0.0.1:7000 slave d2237fdcfbba672de766b913d1186cebcb6e1761 0 1445089813204 7 connected
  26. dfa0754c7854a874a6ebd2613b86140ad97701fc 127.0.0.1:7002 master - 0 1445089813204 3 connected 12288-16383
  27. 127.0.0.1:7007>

看,7007獲得了成爲主節點的機會,7008就變成了7007的從節點。

那麼這個時候,重啓7006節點,那麼他就會變成了一個7007的從節點了。

  1. 27.0.0.1:7008> cluster nodes
  2. 30858dbf483b61b9838d5c1f853a60beaa4e7afd 127.0.0.1:7005 slave dfa0754c7854a874a6ebd2613b86140ad97701fc 0 1445089986148 3 connected
  3. 86d05e7c2b197dc182b5e71069e791d033cf899e 127.0.0.1:7007 master - 0 1445089986652 10 connected 0-1364 5461-6826 10923-12287
  4. d2237fdcfbba672de766b913d1186cebcb6e1761 127.0.0.1:7003 master - 0 1445089986148 7 connected 1365-5460
  5. cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c 127.0.0.1:7001 master - 0 1445089987155 2 connected 6827-10922
  6. efc3131fbdc6cf929720e0e0f7136cae85657481 127.0.0.1:7006 slave 86d05e7c2b197dc182b5e71069e791d033cf899e 0 1445089985644 10 connected
  7. 44321e7d619410dc4e0a8745366610a0d06d2395 127.0.0.1:7008 myself,slave 86d05e7c2b197dc182b5e71069e791d033cf899e 0 0 0 connected
  8. dfa0754c7854a874a6ebd2613b86140ad97701fc 127.0.0.1:7002 master - 0 1445089986652 3 connected 12288-16383
  9. 4b4aef8b48c427a3c903518339d53b6447c58b93 127.0.0.1:7004 slave cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c 0 1445089987660 2 connected
  10. 3707debcbe7be66d4a1968eaf3a5ffaf4308efa4 127.0.0.1:7000 slave d2237fdcfbba672de766b913d1186cebcb6e1761 0 1445089985644 7 connected
  11. 127.0.0.1:7008>
3. 移除一個主節點

有加肯定有減,redis cluster同樣支持移除節點功能,同樣也是redis-trib.rb的用法:

redis-trib del-node 127.0.0.1:7000 `<node-id>`

和新加節點有點不同的是,移除需要節點的node-id。那我們嘗試將7007這個主節點移除:

  1. [root@web3 7006]# redis-trib.rb del-node 127.0.0.1:7000 86d05e7c2b197dc182b5e71069e791d033cf899e
  2. >>> Removing node 86d05e7c2b197dc182b5e71069e791d033cf899e from cluster 127.0.0.1:7000
  3. Connecting to node 127.0.0.1:7000: OK
  4. Connecting to node 127.0.0.1:7006: OK
  5. Connecting to node 127.0.0.1:7004: OK
  6. Connecting to node 127.0.0.1:7001: OK
  7. Connecting to node 127.0.0.1:7003: OK
  8. Connecting to node 127.0.0.1:7007: OK
  9. Connecting to node 127.0.0.1:7008: OK
  10. Connecting to node 127.0.0.1:7005: OK
  11. Connecting to node 127.0.0.1:7002: OK
  12. [ERR] Node 127.0.0.1:7007 is not empty! Reshard data away and try again.

報錯了,它提示我們說,由於7007裏面已經有數據了,不能被移除,要先將它的數據轉移出去。也就是說得重新分片,用上面增加新節點後的分片方式一樣,用我們再來一遍:

redis-trib.rb reshard 127.0.0.1:7000

由於中間太多內容,就省略不重要的,只簡單說明下關鍵的幾步:

  1. M: 86d05e7c2b197dc182b5e71069e791d033cf899e 127.0.0.1:7007
  2. slots:0-1364,5461-6826,10923-12287 (4096 slots) master
  3. How many slots do you want to move (from 1 to 16384)?

提示,我們要分多少個槽點,由於7007上有4096個槽點,所以這裏填寫4096

  1. How many slots do you want to move (from 1 to 16384)? 4096
  2. What is the receiving node ID?

提示我們,需要移動到哪個id上,那就填7001的吧:

  1. What is the receiving node ID? cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c
  2. Please enter all the source node IDs.
  3. Type 'all' to use all the nodes as source nodes for the hash slots.
  4. Type 'done' once you entered all the source nodes IDs.
  5. Source node #1:

這裏就是關鍵了,它要我們從哪個節點去轉移數據到7001,因爲我們是要刪除7007的,所以,我們就得7007的id了

  1. Source node #1:86d05e7c2b197dc182b5e71069e791d033cf899e
  2. Source node #2:done
  3. Do you want to proceed with the proposed reshard plan (yes/no)? yes

ok,這樣就遷移好了。我們看看7007是否爲空了:

  1. [root@web3 7006]# redis-cli -c -p 7007
  2. 127.0.0.1:7007> keys *
  3. (empty list or set)
  4. 127.0.0.1:7007> cluster nodes
  5. 86d05e7c2b197dc182b5e71069e791d033cf899e 127.0.0.1:7007 myself,master - 0 0 10 connected

果然爲空了,好。現在再進行移除節點操作:

  1. [root@web3 7006]# redis-trib.rb del-node 127.0.0.1:7000 86d05e7c2b197dc182b5e71069e791d033cf899e
  2. >>> Removing node 86d05e7c2b197dc182b5e71069e791d033cf899e from cluster 127.0.0.1:7000
  3. Connecting to node 127.0.0.1:7000: OK
  4. Connecting to node 127.0.0.1:7006: OK
  5. Connecting to node 127.0.0.1:7004: OK
  6. Connecting to node 127.0.0.1:7001: OK
  7. Connecting to node 127.0.0.1:7003: OK
  8. Connecting to node 127.0.0.1:7007: OK
  9. Connecting to node 127.0.0.1:7008: OK
  10. Connecting to node 127.0.0.1:7005: OK
  11. Connecting to node 127.0.0.1:7002: OK
  12. >>> Sending CLUSTER FORGET messages to the cluster...
  13. >>> 127.0.0.1:7006 as replica of 127.0.0.1:7001
  14. >>> 127.0.0.1:7008 as replica of 127.0.0.1:7001
  15. >>> SHUTDOWN the node.

哈哈哈哈哈,刪除成功,而且還很人性化的將700670082個沒了爹的孩子送給了7001。好評

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章