1. 程式人生 > >redis 叢集配置(基於3.0.5)

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)

這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沒有寫!!!!]

下載不了,請自行FQ。我這次是在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]都可以,我們執行下:

    <