1. 程式人生 > >Redis叢集研究和實踐(基於redis 3.0.5)

Redis叢集研究和實踐(基於redis 3.0.5)

前言


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.解壓


[
[email protected]
~]# tar zxvf redis-3.0.5.tar.gz
2.安裝


[[email protected] ~]# cd redis-3.0.5
[[email protected] ~]# make && make install
3.將redis-trib.rb 複製到/usr/local/bin


[[email protected] redis-3.0.5]# cd src/
[[email protected] src]# cp redis-trib.rb /usr/local/bin
4.開始叢集搭建


[[email protected]
redis-3.0.5]# vi redis.conf
#修改以下地方
port 7000
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
新建6個節點:


[[email protected] redis-3.0.5]# mkdir -p /usr/local/cluster-test
[[email protected] redis-3.0.5]# cd /usr/local/cluster-test/
[[email protected] cluster-test]# mkdir 7000
[
[email protected]
cluster-test]# mkdir 7001
[[email protected] cluster-test]# mkdir 7002
[[email protected] cluster-test]# mkdir 7003
[[email protected] cluster-test]# mkdir 7004
[[email protected] cluster-test]# mkdir 7005
將redis.conf 分別拷貝到這6個資料夾中,並修改成對應的埠號


#拷貝配置檔案
[[email protected] cluster-test]# cp /root/redis-3.0.5/redis.conf  /usr/local/cluster-test/7000
[[email protected] cluster-test]# cp /root/redis-3.0.5/redis.conf  /usr/local/cluster-test/7001
[[email protected] cluster-test]# cp /root/redis-3.0.5/redis.conf  /usr/local/cluster-test/7002
[[email protected] cluster-test]# cp /root/redis-3.0.5/redis.conf  /usr/local/cluster-test/7003
[[email protected] cluster-test]# cp /root/redis-3.0.5/redis.conf  /usr/local/cluster-test/7004
[[email protected] cluster-test]# cp /root/redis-3.0.5/redis.conf  /usr/local/cluster-test/7005
#修改埠號
[email protected] cluster-test]# sed -i "s/7000/7001/g" /usr/local/cluster-test/7001/redis.conf
[[email protected] cluster-test]# sed -i "s/7000/7002/g" /usr/local/cluster-test/7002/redis.conf
[[email protected] cluster-test]# sed -i "s/7000/7003/g" /usr/local/cluster-test/7003/redis.conf
[[email protected] cluster-test]# sed -i "s/7000/7004/g" /usr/local/cluster-test/7004/redis.conf
[[email protected] cluster-test]# sed -i "s/7000/7005/g" /usr/local/cluster-test/7005/redis.conf
分別,啟動這6個節點


[[email protected] cluster-test]# cd /usr/local/cluster-test/7000/
[[email protected] 7000]# redis-server redis.conf
[[email protected] 7000]# cd ../7001
[[email protected] 7001]# redis-server redis.conf
[[email protected] 7001]# cd ../7002
[[email protected] 7002]# redis-server redis.conf
[[email protected] 7002]# cd ../7003
[[email protected] 7003]# redis-server redis.conf
[[email protected] 7003]# cd ../7004
[[email protected] 7004]# redis-server redis.conf
[[email protected] 7004]# cd ../7005
[[email protected] 7005]# redis-server redis.conf
[[email protected] 7005]#
檢視6個節點的啟動程序情況:


[[email protected] 7005]# ps -ef|grep redis
root     11380     1  0 07:37 ?        00:00:00 redis-server *:7000 [cluster]
root     11384     1  0 07:37 ?        00:00:00 redis-server *:7001 [cluster]
root     11388     1  0 07:37 ?        00:00:00 redis-server *:7002 [cluster]
root     11392     1  0 07:37 ?        00:00:00 redis-server *:7003 [cluster]
root     11396     1  0 07:37 ?        00:00:00 redis-server *:7004 [cluster]
root     11400     1  0 07:37 ?        00:00:00 redis-server *:7005 [cluster]
root     11404  8259  0 07:38 pts/0    00:00:00 grep redis
將6個節點連在一起構招成叢集


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


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,所以,會報錯:


/usr/bin/env: ruby: No such file or directory
那先安裝ruby和rubygems:


[[email protected] 7005]# yum install ruby ruby-devel rubygems rpm-build
然後,再執行一次,發現還是報錯:


[[email protected] 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
/usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require': no such file to load -- redis (LoadError)
    from /usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `require'
    from /usr/local/bin/redis-trib.rb:25
[[email protected] 7005]#
原來是ruby和redis的連線沒安裝好:


[[email protected] 7005]# gem install redis
Successfully installed redis-3.2.1
1 gem installed
Installing ri documentation for redis-3.2.1...
Installing RDoc documentation for redis-3.2.1...
好了。最重要的時刻來臨了,勝敗成舉在此了,啊啊啊啊啊啊,好激動:


[[email protected] 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
>>> Creating cluster
Connecting to node 127.0.0.1:7000: OK
Connecting to node 127.0.0.1:7001: OK
Connecting to node 127.0.0.1:7002: OK
Connecting to node 127.0.0.1:7003: OK
Connecting to node 127.0.0.1:7004: OK
Connecting to node 127.0.0.1:7005: OK
>>> 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: 3707debcbe7be66d4a1968eaf3a5ffaf4308efa4 127.0.0.1:7000
   slots:0-5460 (5461 slots) master
M: cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c 127.0.0.1:7001
   slots:5461-10922 (5462 slots) master
M: dfa0754c7854a874a6ebd2613b86140ad97701fc 127.0.0.1:7002
   slots:10923-16383 (5461 slots) master
S: d2237fdcfbba672de766b913d1186cebcb6e1761 127.0.0.1:7003
   replicates 3707debcbe7be66d4a1968eaf3a5ffaf4308efa4
S: 4b4aef8b48c427a3c903518339d53b6447c58b93 127.0.0.1:7004
   replicates cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c
S: 30858dbf483b61b9838d5c1f853a60beaa4e7afd 127.0.0.1:7005
   replicates dfa0754c7854a874a6ebd2613b86140ad97701fc
Can I set the above configuration? (type 'yes' to accept): 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: 3707debcbe7be66d4a1968eaf3a5ffaf4308efa4 127.0.0.1:7000
   slots:0-5460 (5461 slots) master
M: cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c 127.0.0.1:7001
   slots:5461-10922 (5462 slots) master
M: dfa0754c7854a874a6ebd2613b86140ad97701fc 127.0.0.1:7002
   slots:10923-16383 (5461 slots) master
M: d2237fdcfbba672de766b913d1186cebcb6e1761 127.0.0.1:7003
   slots: (0 slots) master
   replicates 3707debcbe7be66d4a1968eaf3a5ffaf4308efa4
M: 4b4aef8b48c427a3c903518339d53b6447c58b93 127.0.0.1:7004
   slots: (0 slots) master
   replicates cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c
M: 30858dbf483b61b9838d5c1f853a60beaa4e7afd 127.0.0.1:7005
   slots: (0 slots) master
   replicates dfa0754c7854a874a6ebd2613b86140ad97701fc
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈。終於他媽的成功了!!!!


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


測試叢集的狀態:


[[email protected] 7000]# redis-trib.rb check 127.0.0.1:7000
Connecting to node 127.0.0.1:7000: OK
Connecting to node 127.0.0.1:7002: OK
Connecting to node 127.0.0.1:7003: OK
Connecting to node 127.0.0.1:7005: OK
Connecting to node 127.0.0.1:7001: OK
Connecting to node 127.0.0.1:7004: OK
>>> Performing Cluster Check (using node 127.0.0.1:7000)
M: 3707debcbe7be66d4a1968eaf3a5ffaf4308efa4 127.0.0.1:7000
   slots:0-5460 (5461 slots) master
   1 additional replica(s)
M: dfa0754c7854a874a6ebd2613b86140ad97701fc 127.0.0.1:7002
   slots:10923-16383 (5461 slots) master
   1 additional replica(s)
S: d2237fdcfbba672de766b913d1186cebcb6e1761 127.0.0.1:7003
   slots: (0 slots) slave
   replicates 3707debcbe7be66d4a1968eaf3a5ffaf4308efa4
S: 30858dbf483b61b9838d5c1f853a60beaa4e7afd 127.0.0.1:7005
   slots: (0 slots) slave
   replicates dfa0754c7854a874a6ebd2613b86140ad97701fc
M: cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c 127.0.0.1:7001
   slots:5461-10922 (5462 slots) master
   1 additional replica(s)
S: 4b4aef8b48c427a3c903518339d53b6447c58b93 127.0.0.1:7004
   slots: (0 slots) slave
   replicates cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[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`引數,就可以連線到叢集。


連線任意一個節點埠:


[[email protected] 7000]# redis-cli -c -p 7000
127.0.0.1:7000>
設定一個值:


127.0.0.1:7000> set my_name yangyi
-> Redirected to slot [12803] located at 127.0.0.1:7002
OK
127.0.0.1:7002> get my_name
"yangyi"
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這個從節點:


[[email protected] 7000]# redis-cli -c -p 7005
127.0.0.1:7005> get my_name
-> Redirected to slot [12803] located at 127.0.0.1:7002
"yangyi"
127.0.0.1:7002>
我們同樣是獲取my_name的值,它同樣也是跳轉到了7002上。


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


127.0.0.1:7002> set age 123
-> Redirected to slot [741] located at 127.0.0.1:7000
OK
127.0.0.1:7000> set height 565
-> Redirected to slot [8223] located at 127.0.0.1:7001
OK
127.0.0.1:7001> set sex 1
-> Redirected to slot [2584] located at 127.0.0.1:7000
OK
127.0.0.1:7000> set home china
-> Redirected to slot [10814] located at 127.0.0.1:7001
OK
127.0.0.1:7001> set city shanghai
-> Redirected to slot [11479] located at 127.0.0.1:7002
OK
127.0.0.1:7002> set citylocate shanghaipudong
OK
127.0.0.1:7001> set wsdwxzx  hhh
-> Redirected to slot [15487] located at 127.0.0.1:7002
OK
127.0.0.1:7002> zadd erew 333 rrr
-> Redirected to slot [10576] located at 127.0.0.1:7001
(integer) 1
127.0.0.1:7000> zrange erew 0 -1
-> Redirected to slot [10576] located at 127.0.0.1:7001
1) "rrr"
127.0.0.1:7001>
可以看出,資料都會在7000-7002 這3個主節點來跳轉存粗。


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


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


[[email protected] 7005]# cd /usr/local/cluster-test/7003
[[email protected] 7003]# vi appendonly.aof
*2
$6
SELECT
$1
0
*3
$3
set
$3
age
$3
123
*3
$3
set
$3
sex
$1
1
*3
$3
set
$3
job
$3
php
我們看下,的確是從7000節點上同步過來的資料,7004,7005也是。


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


[[email protected] 7003]# ps -ef|grep redis
root     11380     1  0 07:37 ?        00:00:03 redis-server *:7000 [cluster]
root     11384     1  0 07:37 ?        00:00:03 redis-server *:7001 [cluster]
root     11388     1  0 07:37 ?        00:00:03 redis-server *:7002 [cluster]
root     11392     1  0 07:37 ?        00:00:03 redis-server *:7003 [cluster]
root     11396     1  0 07:37 ?        00:00:04 redis-server *:7004 [cluster]
root     11400     1  0 07:37 ?        00:00:03 redis-server *:7005 [cluster]
[[email protected] 7003]# kill 11380
[[email protected] 7003]#
好,安裝前面的理論,7000主節點掛掉了,那麼這個時候,7000的從節點只有7003一個,肯定7003就會被選舉稱Master節點了:


[[email protected] 7003]# redis-trib.rb check 127.0.0.1:7000
Connecting to node 127.0.0.1:7000: [ERR] Sorry, can't connect to node 127.0.0.1:7000
[[email protected] 7003]# redis-trib.rb check 127.0.0.1:7001
Connecting to node 127.0.0.1:7001: OK
Connecting to node 127.0.0.1:7004: OK
Connecting to node 127.0.0.1:7005: OK
Connecting to node 127.0.0.1:7003: OK
Connecting to node 127.0.0.1:7002: OK
>>> Performing Cluster Check (using node 127.0.0.1:7001)
M: cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c 127.0.0.1:7001
   slots:5461-10922 (5462 slots) master
   1 additional replica(s)
S: 4b4aef8b48c427a3c903518339d53b6447c58b93 127.0.0.1:7004
   slots: (0 slots) slave
   replicates cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c
S: 30858dbf483b61b9838d5c1f853a60beaa4e7afd 127.0.0.1:7005
   slots: (0 slots) slave
   replicates dfa0754c7854a874a6ebd2613b86140ad97701fc
M: d2237fdcfbba672de766b913d1186cebcb6e1761 127.0.0.1:7003
   slots:0-5460 (5461 slots) master
   0 additional replica(s)
M: dfa0754c7854a874a6ebd2613b86140ad97701fc 127.0.0.1:7002
   slots:10923-16383 (5461 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.
[[email protected] 7003]#
看了下,上面有了三個M 節點了,果真,7003被選取成了替代7000成為主節點了。那我們來獲取原先存在7000節點的資料:


[[email protected] 7003]# redis-cli -c -p 7001
127.0.0.1:7001> get sex
-> Redirected to slot [2584] located at 127.0.0.1:7003
"1"
127.0.0.1:7003>
資料果真沒有丟失,而是從7003上面獲取了。


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


重新啟動 7000 節點:


[[email protected] 7003]# cd ../7000
[[email protected] 7000]# ll
total 56
-rw-r--r-- 1 root root   114 Oct 17 08:16 appendonly.aof
-rw-r--r-- 1 root root    43 Oct 17 08:37 dump.rdb
-rw-r--r-- 1 root root   745 Oct 17 08:00 nodes.conf
-rw-r--r-- 1 root root 41550 Oct 17 07:37 redis.conf
[[email protected] 7000]# redis-server redis.conf
啟動好了,現在,再來檢查一下叢集:


redis-trib.rb check 127.0.0.1:700`
[[email protected] 7000]# redis-trib.rb check 127.0.0.1:7001
Connecting to node 127.0.0.1:7001: OK
Connecting to node 127.0.0.1:7004: OK
Connecting to node 127.0.0.1:7005: OK
Connecting to node 127.0.0.1:7003: OK
Connecting to node 127.0.0.1:7000: OK
Connecting to node 127.0.0.1:7002: OK
>>> Performing Cluster Check (using node 127.0.0.1:7001)
M: cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c 127.0.0.1:7001
   slots:5461-10922 (5462 slots) master
   1 additional replica(s)
S: 4b4aef8b48c427a3c903518339d53b6447c58b93 127.0.0.1:7004
   slots: (0 slots) slave
   replicates cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c
S: 30858dbf483b61b9838d5c1f853a60beaa4e7afd 127.0.0.1:7005
   slots: (0 slots) slave
   replicates dfa0754c7854a874a6ebd2613b86140ad97701fc
M: d2237fdcfbba672de766b913d1186cebcb6e1761 127.0.0.1:7003
   slots:0-5460 (5461 slots) master
   1 additional replica(s)
S: 3707debcbe7be66d4a1968eaf3a5ffaf4308efa4 127.0.0.1:7000
   slots: (0 slots) slave
   replicates d2237fdcfbba672de766b913d1186cebcb6e1761
M: dfa0754c7854a874a6ebd2613b86140ad97701fc 127.0.0.1:7002
   slots:10923-16383 (5461 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.
你看,7000節點啟動起來了,它卻作為了 70003 的從節點了。驗證了之前的這張圖:


這裡寫圖片描述


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


7. 叢集中新加入節點


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


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


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


[[email protected] cluster-test]# cd /usr/local/cluster-test/
[[email protected] cluster-test]# mkdir 7006
[[email protected] cluster-test]# cp 7005/redis.conf  7006/redis.conf
#修改埠
[[email protected] cluster-test]sed -i "s/7005/7006/g" /usr/local/cluster-test/7006/redis.conf
啟動 7006


[[email protected] 7006]# redis-server redis.conf
[[email protected] 7006]# ps -ef|grep redis
root     11384     1  0 07:37 ?        00:00:05 redis-server *:7001 [cluster]
root     11388     1  0 07:37 ?        00:00:05 redis-server *:7002 [cluster]
root     11392     1  0 07:37 ?        00:00:05 redis-server *:7003 [cluster]
root     11396     1  0 07:37 ?        00:00:06 redis-server *:7004 [cluster]
root     11400     1  0 07:37 ?        00:00:05 redis-server *:7005 [cluster]
root     12100     1  0 08:42 ?        00:00:01 redis-server *:7000 [cluster]
root     12132     1  0 09:09 ?        00:00:00 redis-server *:7006 [cluster]
root     12136  8259  0 09:10 pts/0    00:00:00 grep redis
ok,7006 埠已經啟動好了,並且程序也存在了,下面就是加入到叢集中,也是得用到redis-trib.rb命令:


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 表示加入的叢集的一個節點,用來辨識是哪個叢集,理論上哪個都可以。


[[email protected] 7006]# redis-trib.rb add-node 127.0.0.1:7006 127.0.0.1:7000
>>> Adding node 127.0.0.1:7006 to cluster 127.0.0.1:7000
Connecting to node 127.0.0.1:7000: OK
Connecting to node 127.0.0.1:7004: OK
Connecting to node 127.0.0.1:7005: OK
Connecting to node 127.0.0.1:7003: OK
Connecting to node 127.0.0.1:7001: OK
Connecting to node 127.0.0.1:7002: OK
>>> Performing Cluster Check (using node 127.0.0.1:7000)
S: 3707debcbe7be66d4a1968eaf3a5ffaf4308efa4 127.0.0.1:7000
   slots: (0 slots) slave
   replicates d2237fdcfbba672de766b913d1186cebcb6e1761
S: 4b4aef8b48c427a3c903518339d53b6447c58b93 127.0.0.1:7004
   slots: (0 slots) slave
   replicates cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c
S: 30858dbf483b61b9838d5c1f853a60beaa4e7afd 127.0.0.1:7005
   slots: (0 slots) slave
   replicates dfa0754c7854a874a6ebd2613b86140ad97701fc
M: d2237fdcfbba672de766b913d1186cebcb6e1761 127.0.0.1:7003
   slots:0-5460 (5461 slots) master
   1 additional replica(s)
M: cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c 127.0.0.1:7001
   slots:5461-10922 (5462 slots) master
   1 additional replica(s)
M: dfa0754c7854a874a6ebd2613b86140ad97701fc 127.0.0.1:7002
   slots:10923-16383 (5461 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.
Connecting to node 127.0.0.1:7006: OK
>>> Send CLUSTER MEET to node 127.0.0.1:7006 to make it join the cluster.
[OK] New node added correctly.
這個命令執行完成之後,它順便檢查來其他的6個節點都是成功的,最後幾句話:


Connecting to node 127.0.0.1:7006: OK
>>> Send CLUSTER MEET to node 127.0.0.1:7006 to make it join the cluster.
[OK] New node added correctly.
表示新的節點連線成功了,而且也已經加入到叢集了,我們再來檢查一下:


[[email protected] 7006]# redis-trib.rb check 127.0.0.1:7006
Connecting to node 127.0.0.1:7006: OK
Connecting to node 127.0.0.1:7001: OK
Connecting to node 127.0.0.1:7004: OK
Connecting to node 127.0.0.1:7000: OK
Connecting to node 127.0.0.1:7002: OK
Connecting to node 127.0.0.1:7005: OK
Connecting to node 127.0.0.1:7003: OK
>>> Performing Cluster Check (using node 127.0.0.1:7006)
M: efc3131fbdc6cf929720e0e0f7136cae85657481 127.0.0.1:7006
   slots: (0 slots) master
   0 additional replica(s)
M: cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c 127.0.0.1:7001
   slots:5461-10922 (5462 slots) master
   1 additional replica(s)
S: 4b4aef8b48c427a3c903518339d53b6447c58b93 127.0.0.1:7004
   slots: (0 slots) slave
   replicates cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c
S: 3707debcbe7be66d4a1968eaf3a5ffaf4308efa4 127.0.0.1:7000
   slots: (0 slots) slave
   replicates d2237fdcfbba672de766b913d1186cebcb6e1761
M: dfa0754c7854a874a6ebd2613b86140ad97701fc 127.0.0.1:7002
   slots:10923-16383 (5461 slots) master
   1 additional replica(s)
S: 30858dbf483b61b9838d5c1f853a60beaa4e7afd 127.0.0.1:7005
   slots: (0 slots) slave
   replicates dfa0754c7854a874a6ebd2613b86140ad97701fc
M: d2237fdcfbba672de766b913d1186cebcb6e1761 127.0.0.1:7003
   slots:0-5460 (5461 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.
可以看到了,7006 已經成為了主節點。


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


[[email protected] 7006]# redis-cli -c -p 7006
127.0.0.1:7006> cluster nodes
cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c 127.0.0.1:7001 master - 0 1445073797986 2 connected 5461-10922
4b4aef8b48c427a3c903518339d53b6447c58b93 127.0.0.1:7004 slave cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c 0 1445073799497 2 connected
efc3131fbdc6cf929720e0e0f7136cae85657481 127.0.0.1:7006 myself,master - 0 0 0 connected
3707debcbe7be66d4a1968eaf3a5ffaf4308efa4 127.0.0.1:7000 slave d2237fdcfbba672de766b913d1186cebcb6e1761 0 1445073797482 7 connected
dfa0754c7854a874a6ebd2613b86140ad97701fc 127.0.0.1:7002 master - 0 1445073798489 3 connected 10923-16383
30858dbf483b61b9838d5c1f853a60beaa4e7afd 127.0.0.1:7005 slave dfa0754c7854a874a6ebd2613b86140ad97701fc 0 1445073798993 3 connected
d2237fdcfbba672de766b913d1186cebcb6e1761 127.0.0.1:7003 master - 0 1445073799498 7 connected 0-5460
127.0.0.1:7006>
可以看到 有7個節點。7006 也作為了master節點,但是,但是,你看看後面的:


efc3131fbdc6cf929720e0e0f7136cae85657481 127.0.0.1:7006
   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]都可以,我們執行下:


[[email protected] 7006]# redis-trib.rb reshard 127.0.0.1:7000
Connecting to node 127.0.0.1:7006: OK
Connecting to node 127.0.0.1:7001: OK
Connecting to node 127.0.0.1:7004: OK
Connecting to node 127.0.0.1:7000: OK
Connecting to node 127.0.0.1:7002: OK
Connecting to node 127.0.0.1:7005: OK
Connecting to node 127.0.0.1:7003: OK
>>> Performing Cluster Check (using node 127.0.0.1:7006)
M: efc3131fbdc6cf929720e0e0f7136cae85657481 127.0.0.1:7006
   slots: (0 slots) master
   0 additional replica(s)
M: cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c 127.0.0.1:7001
   slots:5461-10922 (5462 slots) master
   1 additional replica(s)
S: 4b4aef8b48c427a3c903518339d53b6447c58b93 127.0.0.1:7004
   slots: (0 slots) slave
   replicates cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c
S: 3707debcbe7be66d4a1968eaf3a5ffaf4308efa4 127.0.0.1:7000
   slots: (0 slots) slave
   replicates d2237fdcfbba672de766b913d1186cebcb6e1761
M: dfa0754c7854a874a6ebd2613b86140ad97701fc 127.0.0.1:7002
   slots:10923-16383 (5461 slots) master
   1 additional replica(s)
S: 30858dbf483b61b9838d5c1f853a60beaa4e7afd 127.0.0.1:7005
   slots: (0 slots) slave
   replicates dfa0754c7854a874a6ebd2613b86140ad97701fc
M: d2237fdcfbba672de766b913d1186cebcb6e1761 127.0.0.1:7003
   slots:0-5460 (5461 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)?
它提示我們需要遷移多少slot到7006上,我們可以算一下:16384/4 = 4096,也就是說,為了平衡分配起見,我們需要移動4096個槽點到7006上。


好,那輸入4096:


How many slots do you want to move (from 1 to 16384)? 4096
What is the receiving node ID?
它又提示我們,接受的node ID是多少,7006的id 我們通過上面就可以看到是efc3131fbdc6cf929720e0e0f7136cae85657481 :


What is the receiving node ID? efc3131fbdc6cf929720e0e0f7136cae85657481
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:
接著, redis-trib 會向你詢問重新分片的源節點(source node), 也即是, 要從哪個節點中取出 4096 個雜湊槽, 並將這些槽移動到7006節點上面。


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


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


Moving slot 1359 from d2237fdcfbba672de766b913d1186cebcb6e1761
    Moving slot 1360 from d2237fdcfbba672de766b913d1186cebcb6e1761
    Moving slot 1361 from d2237fdcfbba672de766b913d1186cebcb6e1761
    Moving slot 1362 from d2237fdcfbba672de766b913d1186cebcb6e1761
    Moving slot 1363 from d2237fdcfbba672de766b913d1186cebcb6e1761
    Moving slot 1364 from d2237fdcfbba672de766b913d1186cebcb6e1761
Do you want to proceed with the proposed reshard plan (yes/no)?
輸入 yes 並使用按下回車之後, redis-trib 就會正式開始執行重新分片操作, 將指定的雜湊槽從源節點一個個地移動到7006節點上面。


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


[[email protected] 7006]# redis-trib.rb check 127.0.0.1:7000
Connecting to node 127.0.0.1:7000: OK
Connecting to node 127.0.0.1:7006: OK
Connecting to node 127.0.0.1:7004: OK
Connecting to node 127.0.0.1:7005: OK
Connecting to node 127.0.0.1:7003: OK
Connecting to node 127.0.0.1:7001: OK
Connecting to node 127.0.0.1:7002: OK
>>> Performing Cluster Check (using node 127.0.0.1:7000)
S: 3707debcbe7be66d4a1968eaf3a5ffaf4308efa4 127.0.0.1:7000
   slots: (0 slots) slave
   replicates d2237fdcfbba672de766b913d1186cebcb6e1761
M: efc3131fbdc6cf929720e0e0f7136cae85657481 127.0.0.1:7006
   slots:0-1364,5461-6826,10923-12287 (4096 slots) master
   0 additional replica(s)
S: 4b4aef8b48c427a3c903518339d53b6447c58b93 127.0.0.1:7004
   slots: (0 slots) slave
   replicates cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c
S: 30858dbf483b61b9838d5c1f853a60beaa4e7afd 127.0.0.1:7005
   slots: (0 slots) slave
   replicates dfa0754c7854a874a6ebd2613b86140ad97701fc
M: d2237fdcfbba672de766b913d1186cebcb6e1761 127.0.0.1:7003
   slots:1365-5460 (4096 slots) master
   1 additional replica(s)
M: cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c 127.0.0.1:7001
   slots:6827-10922 (4096 slots) master
   1 additional replica(s)
M: dfa0754c7854a874a6ebd2613b86140ad97701fc 127.0.0.1:7002
   slots:12288-16383 (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.
我們著重看7006:


0-1364,5461-6826,10923-12287 (4096 slots)
這些原來在其他節點上的slot 杯遷移到了7006上。原來,它只是間隔的移動,並不是銜接的整體移動,我們看下有資料了沒?


[[email protected] 7006]# redis-cli -c -p 7006
127.0.0.1:7006> keys *
1) "city"
2) "age"
3) "citylocate"
127.0.0.1:7006> get city
"shanghai"
非常贊,已經有資料了。


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


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


[[email protected] 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還沒有從節點。我們執行下。


[[email protected] 7007]# redis-trib.rb add-node --slave 127.0.0.1:7007 127.0.0.1:7000
...
...
[OK] All 16384 slots covered.
Automatically selected master 127.0.0.1:7006
Connecting to node 127.0.0.1:7007: OK
>>> 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.
上面提示說,自動選擇了7006作為master節點。並且成功了。我們檢查下:


[[email protected] 7007]# redis-trib.rb check 127.0.0.1:7000
Connecting to node 127.0.0.1:7000: OK
Connecting to node 127.0.0.1:7006: OK
Connecting to node 127.0.0.1:7004: OK
Connecting to node 127.0.0.1:7005: OK
Connecting to node 127.0.0.1:7003: OK
Connecting to node 127.0.0.1:7001: OK
Connecting to node 127.0.0.1:7007: OK
Connecting to node 127.0.0.1:7002: OK
>>> Performing Cluster Check (using node 127.0.0.1:7000)
S: 3707debcbe7be66d4a1968eaf3a5ffaf4308efa4 127.0.0.1:7000
   slots: (0 slots) slave
   replicates d2237fdcfbba672de766b913d1186cebcb6e1761
M: efc3131fbdc6cf929720e0e0f7136cae85657481 127.0.0.1:7006
   slots:0-1364,5461-6826,10923-12287 (4096 slots) master
   1 additional replica(s)
S: 4b4aef8b48c427a3c903518339d53b6447c58b93 127.0.0.1:7004
   slots: (0 slots) slave
   replicates cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c
S: 30858dbf483b61b9838d5c1f853a60beaa4e7afd 127.0.0.1:7005
   slots: (0 slots) slave
   replicates dfa0754c7854a874a6ebd2613b86140ad97701fc
M: d2237fdcfbba672de766b913d1186cebcb6e1761 127.0.0.1:7003
   slots:1365-5460 (4096 slots) master
   1 additional replica(s)
M: cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c 127.0.0.1:7001
   slots:6827-10922 (4096 slots) master
   1 additional replica(s)
S: 86d05e7c2b197dc182b5e71069e791d033cf899e 127.0.0.1:7007
   slots: (0 slots) slave
   replicates efc3131fbdc6cf929720e0e0f7136cae85657481
M: dfa0754c7854a874a6ebd2613b86140ad97701fc 127.0.0.1:7002
   slots:12288-16383 (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.
果然,7007加入到了7006的從節點當中。


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


redis-trib.rb add-node --slave --master-id efc3131fbdc6cf929720e0e0f7136cae85657481 127.0.0.1:7008 127.0.0.1:7000
--master-id 表示指定的主節點node id。這裡指定的是 7006 這個主節點。


Waiting for the cluster to join.
>>> Configure node as replica of 127.0.0.1:7006.
[OK] New node added correctly.
[[email protected] 7008]#
提示我們已經作為7006的附屬品,也就是加入到7006的從節點來了,照這麼說,7006就有2個從節點了,我們看一下:


redis-cli -c -p 7008 cluster nodes |grep efc3131fbdc6cf929720e0e0f7136cae85657481
86d05e7c2b197dc182b5e71069e791d033cf899e 127.0.0.1:7007 slave efc3131fbdc6cf929720e0e0f7136cae85657481 0 1445089507786 8 connected
efc3131fbdc6cf929720e0e0f7136cae85657481 127.0.0.1:7006 master - 0 1445089508289 8 connected 0-1364 5461-6826 10923-12287
44321e7d619410dc4e0a8745366610a0d06d2395 127.0.0.1:7008 myself,slave efc3131fbdc6cf929720e0e0f7136cae85657481 0 0 0 connected
我們過濾了下看結果,果真,7007和7008是7006的從節點了。


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


[[email protected] 7008]# ps -ef|grep redis
root     11384     1  0 09:56 ?        00:00:16 redis-server *:7001 [cluster]
root     11388     1  0 09:56 ?        00:00:16 redis-server *:7002 [cluster]
root     11392     1  0 09:56 ?        00:00:16 redis-server *:7003 [cluster]
root     11396     1  0 09:56 ?        00:00:15 redis-server *:7004 [cluster]
root     11400     1  0 09:56 ?        00:00:15 redis-server *:7005 [cluster]
root     12100     1  0 11:01 ?        00:00:11 redis-server *:7000 [cluster]
root     12132     1  0 11:28 ?        00:00:11 redis-server *:7006 [cluster]
root     12202     1  0 13:14 ?        00:00:02 redis-server *:7007 [cluster]
root     12219     1  0 13:39 ?        00:00:00 redis-server *:7008 [cluster]
root     12239  8259  0 13:49 pts/0    00:00:00 grep redis
[[email protected] 7008]# kill 12132
[[email protected] 7008]# redis-cli -c -p 7008
127.0.0.1:7008> get ss5rtr
-> Redirected to slot [1188] located at 127.0.0.1:7007
"66"
127.0.0.1:7007> cluster nodes
efc3131fbdc6cf929720e0e0f7136cae85657481 127.0.0.1:7006 master,fail - 1445089780668 1445089779963 8 disconnected
d2237fdcfbba672de766b913d1186cebcb6e1761 127.0.0.1:7003 master - 0 1445089812195 7 connected 1365-5460
30858dbf483b61b9838d5c1f853a60beaa4e7afd 127.0.0.1:7005 slave dfa0754c7854a874a6ebd2613b86140ad97701fc 0 1445089813710 3 connected
86d05e7c2b197dc182b5e71069e791d033cf899e 127.0.0.1:7007 myself,master - 0 0 10 connected 0-1364 5461-6826 10923-12287
cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c 127.0.0.1:7001 master - 0 1445089814214 2 connected 6827-10922
4b4aef8b48c427a3c903518339d53b6447c58b93 127.0.0.1:7004 slave cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c 0 1445089812701 2 connected
44321e7d619410dc4e0a8745366610a0d06d2395 127.0.0.1:7008 slave 86d05e7c2b197dc182b5e71069e791d033cf899e 0 1445089814214 10 connected
3707debcbe7be66d4a1968eaf3a5ffaf4308efa4 127.0.0.1:7000 slave d2237fdcfbba672de766b913d1186cebcb6e1761 0 1445089813204 7 connected
dfa0754c7854a874a6ebd2613b86140ad97701fc 127.0.0.1:7002 master - 0 1445089813204 3 connected 12288-16383
127.0.0.1:7007>
看,7007獲得了成為主節點的機會,7008就變成了7007的從節點。


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


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


[[email protected] 7006]# redis-trib.rb del-node 127.0.0.1:7000 86d05e7c2b197dc182b5e71069e791d033cf899e
>>> Removing node 86d05e7c2b197dc182b5e71069e791d033cf899e from cluster 127.0.0.1:7000
Connecting to node 127.0.0.1:7000: OK
Connecting to node 127.0.0.1:7006: OK
Connecting to node 127.0.0.1:7004: OK
Connecting to node 127.0.0.1:7001: OK
Connecting to node 127.0.0.1:7003: OK
Connecting to node 127.0.0.1:7007: OK
Connecting to node 127.0.0.1:7008: OK
Connecting to node 127.0.0.1:7005: OK
Connecting to node 127.0.0.1:7002: OK
[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
由於中間太多內容,就省略不重要的,只簡單說明下關鍵的幾步:


M: 86d05e7c2b197dc182b5e71069e791d033cf899e 127.0.0.1:7007
   slots:0-1364,5461-6826,10923-12287 (4096 slots) master
How many slots do you want to move (from 1 to 16384)?
提示,我們要分多少個槽點,由於7007上有4096個槽點,所以這裡填寫4096


How many slots do you want to move (from 1 to 16384)? 4096
What is the receiving node ID?
提示我們,需要移動到哪個id上,那就填7001的吧:


What is the receiving node ID? cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c
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:
這裡就是關鍵了,它要我們從哪個節點去轉移資料到7001,因為我們是要刪除7007的,所以,我們就得7007的id了


Source node #1:86d05e7c2b197dc182b5e71069e791d033cf899e
Source node #2:done
Do you want to proceed with the proposed reshard plan (yes/no)? yes
ok,這樣就遷移好了。我們看看7007是否為空了:


[[email protected] 7006]# redis-cli -c -p 7007
127.0.0.1:7007> keys *
(empty list or set)
127.0.0.1:7007> cluster nodes
86d05e7c2b197dc182b5e71069e791d033cf899e 127.0.0.1:7007 myself,master - 0 0 10 connected
果然為空了,好。現在再進行移除節點操作:


[[email protected] 7006]# redis-trib.rb del-node 127.0.0.1:7000 86d05e7c2b197dc182b5e71069e791d033cf899e
>>> Removing node 86d05e7c2b197dc182b5e71069e791d033cf899e from cluster 127.0.0.1:7000
Connecting to node 127.0.0.1:7000: OK
Connecting to node 127.0.0.1:7006: OK
Connecting to node 127.0.0.1:7004: OK
Connecting to node 127.0.0.1:7001: OK
Connecting to node 127.0.0.1:7003: OK
Connecting to node 127.0.0.1:7007: OK
Connecting to node 127.0.0.1:7008: OK
Connecting to node 127.0.0.1:7005: OK
Connecting to node 127.0.0.1:7002: OK
>>> Sending CLUSTER FORGET messages to the cluster...
>>> 127.0.0.1:7006 as replica of 127.0.0.1:7001
>>> 127.0.0.1:7008 as replica of 127.0.0.1:7001
>>> SHUTDOWN the node.
哈哈哈哈哈,刪除成功,而且還很人性化的將7006和70082個沒了爹的孩子送給了7001。好評�


我們再檢查一下:7007 已經移除,連不上了。


[[email protected] 7006]# redis-trib.rb check 127.0.0.1:7007
Connecting to node 127.0.0.1:7007: [ERR] Sorry, can't connect to node 127.0.0.1:7007
[[email protected] 7006]# redis-trib.rb check 127.0.0.1:7008
Connecting to node 127.0.0.1:7008: OK
Connecting to node 127.0.0.1:7005: OK
Connecting to node 127.0.0.1:7003: OK
Connecting to node 127.0.0.1:7001: OK
Connecting to node 127.0.0.1:7006: OK
Connecting to node 127.0.0.1:7002: OK
Connecting to node 127.0.0.1:7004: OK
Connecting to node 127.0.0.1:7000: OK
>>> Performing Cluster Check (using node 127.0.0.1:7008)
S: 44321e7d619410dc4e0a8745366610a0d06d2395 127.0.0.1:7008
   slots: (0 slots) slave
   replicates cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c
S: 30858dbf483b61b9838d5c1f853a60beaa4e7afd 127.0.0.1:7005
   slots: (0 slots) slave
   replicates dfa0754c7854a874a6ebd2613b86140ad97701fc
M: d2237fdcfbba672de766b913d1186cebcb6e1761 127.0.0.1:7003
   slots:1365-5460 (4096 slots) master
   1 additional replica(s)
M: cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c 127.0.0.1:7001
   slots:0-1364,5461-12287 (8192 slots) master
   3 additional replica(s)
S: efc3131fbdc6cf929720e0e0f7136cae85657481 127.0.0.1:7006
   slots: (0 slots) slave
   replicates cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c
M: dfa0754c7854a874a6ebd2613b86140ad97701fc 127.0.0.1:7002
   slots:12288-16383 (4096 slots) master
   1 additional replica(s)
S: 4b4aef8b48c427a3c903518339d53b6447c58b93 127.0.0.1:7004
   slots: (0 slots) slave
   replicates cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c
S: 3707debcbe7be66d4a1968eaf3a5ffaf4308efa4 127.0.0.1:7000
   slots: (0 slots) slave
   replicates d2237fdcfbba672de766b913d1186cebcb6e1761
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
[[email protected] 7006]#
7006和7008果然也成功加入到了7001的大家庭。


4. 移除一個從節點


移除一個從節點就簡單的多了,因為不需要考慮資料的遷移,我們7008給移除:


[[email protected] 7006]# redis-trib.rb del-node 127.0.0.1:7005 44321e7d619410dc4e0a8745366610a0d06d2395
>>> Removing node 44321e7d619410dc4e0a8745366610a0d06d2395 from cluster 127.0.0.1:7005
Connecting to node 127.0.0.1:7005: OK
Connecting to node 127.0.0.1:7001: OK
Connecting to node 127.0.0.1:7002: OK
Connecting to node 127.0.0.1:7004: OK
Connecting to node 127.0.0.1:7000: OK
Connecting to node 127.0.0.1:7006: OK
Connecting to node 127.0.0.1:7008: OK
Connecting to node 127.0.0.1:7003: OK
>>> Sending CLUSTER FORGET messages to the cluster...
>>> SHUTDOWN the node.
[[email protected] 7006]# redis-trib.rb check 127.0.0.1:7008
Connecting to node 127.0.0.1:7008: [ERR] Sorry, can't connect to node 127.0.0.1:7008
移除成功。

相關推薦

Redis叢集研究實踐基於redis 3.0.5

前言 redis 是我們目前大規模使用的快取中介軟體,由於它強大高效而又便捷的功能,得到了廣泛的使用。現在的2.x的穩定版本是2.8.19,也是我們專案中普遍用到的版本。 redis在年初發布了3.0.0,官方支援了redis cluster,也就是叢集。至此結束了redi

redis詳解——redis叢集搭建使用

上一章我寫到redis簡單的介紹和如何單機的使用,當我們redis相當重要的時候那麼接下來就需要搭建一個叢集了。 1 Redis叢集的介紹 1.1 redis-cluster(叢集)架構圖 架構細節: (1)所有的redis節點彼此互聯(PING-PONG機制),

redis 叢集配置基於3.0.5

前言 redis 是我們目前大規模使用的快取中介軟體,由於它強大高效而又便捷的功能,得到了廣泛的使用。現在的2.x的穩定版本是2.8.19,也是我們專案中普遍用到的版本。 redis在年初發布了3.0.0,官方支援了redis cluster,也就是叢集。至此結束了redis 沒有官方叢集的時代,之前我們

Java主執行緒其餘執行緒的區別實踐Main、Runnable、Thread

在日常的開發中,很多一些開發中較常見的問題,還是需要去仔細研究一下,最重要的還是實踐。以小見大。 一、Java執行緒中。Main、Runnable和Thread。 相信在工作中,只要是有用到多執行緒非同步程式設計,最起碼都要和這三個打交道。 1、每個Java應用程式

Beginng_Java7(譯):發現類物件第二章3.4.5節)(完)

多型 一些現實世界的實體可以改變他們的形式。 例如,水(在地球上而不是星際空間)自然是液體,但在冷凍時會變成固體,在加熱到沸點時會變成氣體。 諸如經歷變態的蝴蝶之類的昆蟲是另一個例子。 改變形式的能力被稱為多型,並且對於在程式語言中建模是有用的。 例如,通過引入

Problem1Multiples of 3 and 5

一.問題描述       官方問題描述如下:           If we list all the natural numbers below 10 that are multiples of

Spring集成Redis方案spring-data-redis基於Jedis的單機模式實踐

packaging 基於 .cn @override time Coding 很好 -o -i 繼上一篇文章http://www.cnblogs.com/EasonJim/p/7625738.html中提到的幾款客戶端,它們基本都能和Spring集成。 下面介紹的是基於S

redis cluster 叢集重新分片故障處理基於redis 4.0.6

redis cluster 叢集重新分片故障處理(基於redis 4.0.6)  環境: redis:4.0.6 現象: 開始gem安裝redis預設版本,gem install redis,部署叢集完畢後,測試程式碼寫入叢集資料,然後進行分片,發現一隻報錯,錯誤如下

Redis叢集新增刪除節點

一、原始叢集(6個節點,3主3從): (1)啟動叢集:因為叢集建立一次就行,所以直接啟動所有節點服務即可 [[email protected] ~]# /usr/local/redis/bin/redis-server /usr/local/redis-clus

Redis的安裝部署windows

數據庫 inux 保持 設置 cli 窗口 mas log height Redis是一個開源的試用ANSI C語言編寫的、遵守BSD協議、支持網絡、可基於內存可持久化的日誌型、key-value數據庫。通常被稱為數據結構服務器. redis的數據類型有:字符串(strin

虛擬機搭建redis單機版及redis-cluster,使用redis desktop managerjavaeclipse連接redis過程遇到問題匯總

init clu centos 一律 有用 tex 保護模式 bin service 如果你看到這裏,我默認你已經安裝好了redis,並且已經成功的在虛擬機的Linux系統中ping通。 介紹一下我的環境:VMware虛擬機安裝centos 6.5版的Linux系統,red

Redis的安裝配置

execute local bench redis-cli HR file 版本 dir mac 一. mac下redis的安裝 1. 官網http://redis.io/ 下載最新的穩定版本,這裏是3.2.0 2. sudo mv 到 /usr/local/ 3.

Redis 客戶端之Redisson 配置使用基於Spring Boot 2.x

開發環境:使用Intellij IDEA + Maven + Spring Boot 2.x + JDK 8 1.在專案的pom.xml檔案下,引入Redis和Redisson在Spring Boot 下的相關Jar包依賴。 <properties>

redis進化五1redis叢集的安裝使用redis-cluster 及其 原理

叢集結構        特點       1、所有redis節點(包括主和從)彼此互聯(兩兩通訊),底層使用內部的二進位制傳輸協議,優化傳輸速度;         &nb

redis叢集部署使用

                                        &nbs

Redis 客戶端之Lettuce配置使用基於Spring Boot 2.x

開發環境:使用Intellij IDEA + Maven + Spring Boot 2.x + JDK 8 Spring Boot 從 2.0版本開始,將預設的Redis客戶端Jedis替換問Lett

自己動手做聊天工具基於 Redis 開發

說起聊天軟體, 你一定會想到微信、QQ。所以聊天軟體總給人給龐大,複雜的感覺。但當我們抽繭剝絲之後,你也會驚呼“哇,原來這麼簡單,我自己也能編寫聊天軟體了!” Redis 號稱“世界上最快的資料庫", 基於 Redis 我們可以開發很多有趣的應用。此 Chat 我們將一起基於 Redis 開發一款

redis-cluster研究使用(轉)

最近研究redis-cluster,正好搭建了一個環境,遇到了很多坑,系統的總結下,等到redis3 release出來後,換掉memCache 叢集. 轉載請註明出處哈:http://hot66hot.iteye.com/admin/blogs/2050676 一:關於redis cluster 1:r

redis-cluster研究使用

最近研究redis-cluster,正好搭建了一個環境,遇到了很多坑,系統的總結下,等到redis3 release出來後,換掉memCache 叢集. 轉載請註明出處哈:http://hot66hot.iteye.com/admin/blogs/2050676 一:關於redis cluster 1:

Redis原始碼剖析註釋二十五--- Redis Cluster 的通訊流程深入剖析載入配置檔案、節點握手、分配槽

Redis Cluster 通訊流程深入剖析 1. Redis Cluster 介紹和搭建 這篇部落格會介紹Redis Cluster的資料分割槽理論和一個三主三從叢集的搭建。 2. Redis Cluster 和 Redis Sentin