1. 程式人生 > >Redis叢集的原理和搭建

Redis叢集的原理和搭建

前言

Redis 是我們目前大規模使用的快取中介軟體,由於它強大高效而又便捷的功能,得到了廣泛的使用。單節點的Redis已經就達到了很高的效能,為了提高可用性我們可以使用Redis叢集。本文參考了Rdis的官方文件和使用Redis官方提供的Redis Cluster工具搭建Rdis叢集。

注意 :Redis的版本要在3.0以上,截止今天,Redis的版本是3.2.9,本教程也使用3.2.9作為教程

Redis叢集的概念

介紹

Redis 叢集是一個可以在多個 Redis 節點之間進行資料共享的設施(installation)。

Redis 叢集不支援那些需要同時處理多個鍵的 Redis 命令, 因為執行這些命令需要在多個 Redis 節點之間移動資料, 並且在高負載的情況下, 這些命令將降低 Redis 叢集的效能, 並導致不可預測的錯誤。

Redis 叢集通過分割槽(partition)來提供一定程度的可用性(availability): 即使叢集中有一部分節點失效或者無法進行通訊, 叢集也可以繼續處理命令請求。

Redis 叢集提供了以下兩個好處:

  • 將資料自動切分(split)到多個節點的能力。
  • 當叢集中的一部分節點失效或者無法進行通訊時, 仍然可以繼續處理命令請求的能力。

資料分片

Redis 叢集使用資料分片(sharding)而非一致性雜湊(consistency hashing)來實現: 一個 Redis 叢集包含 16384 個雜湊槽(hash slot), 資料庫中的每個鍵都屬於這 16384 個雜湊槽的其中一個, 叢集使用公式 CRC16(key) % 16384 來計算鍵 key 屬於哪個槽, 其中 CRC16(key) 語句用於計算鍵 key 的 CRC16 校驗和 。

叢集中的每個節點負責處理一部分雜湊槽。 舉個例子, 一個叢集可以有三個雜湊槽, 其中:

  • 節點 A 負責處理 0 號至 5500 號雜湊槽。
  • 節點 B 負責處理 5501 號至 11000 號雜湊槽。
  • 節點 C 負責處理 11001 號至 16384 號雜湊槽。

這種將雜湊槽分佈到不同節點的做法使得使用者可以很容易地向叢集中新增或者刪除節點。 比如說:
我現在想設定一個key,叫my_name:

set my_name zhangguoji

按照Redis Cluster的雜湊槽演算法,CRC16('my_name')%16384 = 2412 那麼這個key就被分配到了節點A上
同樣的,當我連線(A,B,C)的任意一個節點想獲取my_name

這個key,都會轉到節點A上
再比如
如果使用者將新節點 D 新增到叢集中, 那麼叢集只需要將節點 A 、B 、 C 中的某些槽移動到節點 D 就可以了。
增加一個D節點的結果可能如下:
* 節點A覆蓋1365-5460
* 節點B覆蓋6827-10922
* 節點C覆蓋12288-16383
* 節點D覆蓋0-1364,5461-6826,10923-1228

與此類似, 如果使用者要從叢集中移除節點 A , 那麼叢集只需要將節點 A 中的所有雜湊槽移動到節點 B 和節點 C , 然後再移除空白(不包含任何雜湊槽)的節點 A 就可以了。
因為將一個雜湊槽從一個節點移動到另一個節點不會造成節點阻塞, 所以無論是新增新節點還是移除已存在節點, 又或者改變某個節點包含的雜湊槽數量, 都不會造成叢集下線。
所以,Redis Cluster的模型大概是這樣的形狀
082248582749859.jpg

主從複製模型

為了使得叢集在一部分節點下線或者無法與叢集的大多數(majority)節點進行通訊的情況下, 仍然可以正常運作, Redis 叢集對節點使用了主從複製功能: 叢集中的每個節點都有 1 個至 N 個複製品(replica), 其中一個複製品為主節點(master), 而其餘的 N-1 個複製品為從節點(slave)。

在之前列舉的節點 A 、B 、C 的例子中, 如果節點 B 下線了, 那麼叢集將無法正常執行, 因為叢集找不到節點來處理 5501 號至 11000號的雜湊槽。

另一方面, 假如在建立叢集的時候(或者至少在節點 B 下線之前), 我們為主節點 B 添加了從節點 B1 , 那麼當主節點 B 下線的時候, 叢集就會將 B1 設定為新的主節點, 並讓它代替下線的主節點 B , 繼續處理 5501 號至 11000 號的雜湊槽, 這樣叢集就不會因為主節點 B 的下線而無法正常運作了。

不過如果節點 B 和 B1 都下線的話, Redis 叢集還是會停止運作。

Redis一致性保證

Redis 並不能保證資料的強一致性. 這意味這在實際中叢集在特定的條件下可能會丟失寫操作:
第一個原因是因為叢集是用了非同步複製. 寫操作過程:
1. 客戶端向主節點B寫入一條命令.
2. 主節點B向客戶端回覆命令狀態.
3. 主節點將寫操作複製給他得從節點 B1, B2 和 B3

主節點對命令的複製工作發生在返回命令回覆之後, 因為如果每次處理命令請求都需要等待複製操作完成的話, 那麼主節點處理命令請求的速度將極大地降低 —— 我們必須在效能和一致性之間做出權衡。 注意:Redis 叢集可能會在將來提供同步寫的方法。 Redis 叢集另外一種可能會丟失命令的情況是叢集出現了網路分割槽, 並且一個客戶端與至少包括一個主節點在內的少數例項被孤立。
舉個例子 假設叢集包含 A 、 B 、 C 、 A1 、 B1 、 C1 六個節點, 其中 A 、B 、C 為主節點, A1 、B1 、C1 為A,B,C的從節點, 還有一個客戶端 Z1 假設叢集中發生網路分割槽,那麼叢集可能會分為兩方,大部分的一方包含節點 A 、C 、A1 、B1 和 C1 ,小部分的一方則包含節點 B 和客戶端 Z1 .
Z1仍然能夠向主節點B中寫入, 如果網路分割槽發生時間較短,那麼叢集將會繼續正常運作,如果分割槽的時間足夠讓大部分的一方將B1選舉為新的master,那麼Z1寫入B中得資料便丟失了.
注意, 在網路分裂出現期間, 客戶端 Z1 可以向主節點 B 傳送寫命令的最大時間是有限制的, 這一時間限制稱為節點超時時間(node timeout), 是 Redis 叢集的一個重要的配置選項

搭建Redis叢集

要讓叢集正常工作至少需要3個主節點,在這裡我們要建立6個redis節點,其中三個為主節點,三個為從節點,對應的redis節點的ip和埠對應關係如下(為了簡單演示都在同一臺機器上面)

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

安裝和啟動Redis

下載安裝包

wget http://download.redis.io/releases/redis-3.2.9.tar.gz

解壓安裝

tar zxvf redis-3.2.9.tar.gz
cd redis-3.2.9
make && make PREFIX=/usr/local/redis install

這裡如果失敗的自行yum安裝gcc和tcl

yum install gcc
yum install tcl

建立目錄

cd /usr/local/redis
mkdir cluster
cd cluster
mkdir 7000 7001 7002 7003 7004 7005

複製和修改配置檔案

將redis目錄下的配置檔案複製到對應埠資料夾下,6個資料夾都要複製一份

cp redis-3.2.9/redis.conf /usr/local/redis/cluster/7000

修改配置檔案redis.conf,將下面的選項修改

# 埠號
port 7000
# 後臺啟動
daemonize yes
# 開啟叢集
cluster-enabled yes
#叢集節點配置檔案
cluster-config-file nodes-7000.conf
# 叢集連線超時時間
cluster-node-timeout 5000
# 程序pid的檔案位置
pidfile /var/run/redis-7000.pid
# 開啟aof
appendonly yes
# aof檔案路徑
appendfilename "appendonly-7005.aof"
# rdb檔案路徑
dbfilename dump-7000.rdb

6個配置檔案安裝對應的埠分別修改配置檔案

建立啟動指令碼

/usr/local/redis目錄下建立一個start.sh

#!/bin/bash
bin/redis-server cluster/7000/redis.conf
bin/redis-server cluster/7001/redis.conf
bin/redis-server cluster/7002/redis.conf
bin/redis-server cluster/7003/redis.conf
bin/redis-server cluster/7004/redis.conf
bin/redis-server cluster/7005/redis.conf

這個時候我們檢視一下程序看啟動情況

ps -ef | grep redis

程序狀態如下:

root      1731     1  1 18:21 ?        00:00:49 bin/redis-server *:7000 [cluster]       
root      1733     1  0 18:21 ?        00:00:29 bin/redis-server *:7001 [cluster]       
root      1735     1  0 18:21 ?        00:00:08 bin/redis-server *:7002 [cluster]       
root      1743     1  0 18:21 ?        00:00:26 bin/redis-server *:7003 [cluster]       
root      1745     1  0 18:21 ?        00:00:13 bin/redis-server *:7004 [cluster]       
root      1749     1  0 18:21 ?        00:00:08 bin/redis-server *:7005 [cluster] 

有6個redis程序在開啟,說明我們的redis就啟動成功了

開啟叢集

這裡我們只是開啟了6個redis程序而已,它們都還只是獨立的狀態,還麼有組成叢集
這裡我們使用官方提供的工具redis-trib,不過這個工具是用ruby寫的,要先安裝ruby的環境

yum install ruby rubygems -y

執行,報錯

[[email protected]]# 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]]#

原來是ruby和redis的連線沒安裝好
安裝gem-redis

gem install redis

安裝到這裡的時候突然卡住很久不動,網上搜了下,這裡需要翻牆或者換映象

gem source -a https://gems.ruby-china.org

這裡可以將映象換成ruby-china的映象,不過我好像更換失敗,最終還是翻牆下載了

[[email protected]]# 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]]# 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...

將redis-3.2.9的src目錄下的trib複製到相應資料夾

cp redis-3.2.9/src/redis-trib.rb /usr/local/redis/bin/redis-trib

建立叢集:

redis-trib 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

命令的意義如下:
* 給定 redis-trib.rb 程式的命令是 create , 這表示我們希望建立一個新的叢集。
* 選項 –replicas 1 表示我們希望為叢集中的每個主節點建立一個從節點。
之後跟著的其他引數則是例項的地址列表, 我們希望程式使用這些地址所指示的例項來建立新叢集。
簡單來說,以上的命令的意思就是讓redis-trib程式幫我們建立三個主節點和三個從節點的叢集
接著, redis-trib 會打印出一份預想中的配置給你看, 如果你覺得沒問題的話, 就可以輸入 yes , redis-trib 就會將這份配置應用到叢集當中:

>>> Creating cluster
>>> 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: bdcddddd3d78a866b44b68c7ae0e5ccf875c446a 127.0.0.1:7000
   slots:0-5460 (5461 slots) master
M: b85519795fa42aa33d4e88d25104cbae895933a6 127.0.0.1:7001
   slots:5461-10922 (5462 slots) master
M: b681e1a151890cbf957d1ff08352ee48f6ae39e6 127.0.0.1:7002
   slots:10923-16383 (5461 slots) master
S: d403713ab9db48aeac5b5393b69e1201026ef479 127.0.0.1:7003
   replicates bdcddddd3d78a866b44b68c7ae0e5ccf875c446a
S: b7ec92919e5bcffa76c8eee338f8ca5155293c64 127.0.0.1:7004
   replicates b85519795fa42aa33d4e88d25104cbae895933a6
S: 8a0d2a3f271b349744a971e1b0a545405de2742e 127.0.0.1:7005
   replicates b681e1a151890cbf957d1ff08352ee48f6ae39e6
Can I set the above configuration? (type 'yes' to accept):

按下yes,叢集就會將配置應用到各個節點,並連線起(join)各個節點,也即是,讓各個節點開始通訊

>>> 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: bdcddddd3d78a866b44b68c7ae0e5ccf875c446a 127.0.0.1:7000
   slots:0-5460 (5461 slots) master
   1 additional replica(s)
S: d403713ab9db48aeac5b5393b69e1201026ef479 127.0.0.1:7003
   slots: (0 slots) slave
   replicates bdcddddd3d78a866b44b68c7ae0e5ccf875c446a
S: 8a0d2a3f271b349744a971e1b0a545405de2742e 127.0.0.1:7005
   slots: (0 slots) slave
   replicates b681e1a151890cbf957d1ff08352ee48f6ae39e6
M: b85519795fa42aa33d4e88d25104cbae895933a6 127.0.0.1:7001
   slots:5461-10922 (5462 slots) master
   1 additional replica(s)
S: b7ec92919e5bcffa76c8eee338f8ca5155293c64 127.0.0.1:7004
   slots: (0 slots) slave
   replicates b85519795fa42aa33d4e88d25104cbae895933a6
M: b681e1a151890cbf957d1ff08352ee48f6ae39e6 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.

Redis叢集的使用

連線叢集

這裡我們使用reids-cli連線叢集,使用時加上-c引數,就可以連線到叢集
連線7000埠的節點

[[email protected] redis]# ./redis-cli -c -p 7000
127.0.0.1:7000> set name zgj
-> Redirected to slot [5798] located at 127.0.0.1:7001
OK
127.0.0.1:7001> get name
"zgj"

前面的理論知識我們知道了,分配key的時候,它會使用CRC16演算法,這裡將keyname分配到了7001節點上

Redirected to slot [5798] located at 127.0.0.1:7001

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

好,現在我們連線7003這個從節點進入

[[email protected] redis]# ./redis-cli -c -p 7003
127.0.0.1:7003> get name
-> Redirected to slot [5798] located at 127.0.0.1:7001
"zgj"

這裡獲取name的值,也同樣跳轉到了7001上
我們再測試一下其他資料

127.0.0.1:7001> set age 20
-> Redirected to slot [741] located at 127.0.0.1:7000
OK
127.0.0.1:7000> set message helloworld
-> Redirected to slot [11537] located at 127.0.0.1:7002
OK
127.0.0.1:7002> set height 175
-> Redirected to slot [8223] located at 127.0.0.1:7001
OK

我們發現數據會在7000-7002這3個節點之間來回跳轉

測試叢集中的節點掛掉

上面我們建立了一個叢集,3個主節點和3個從節點,7000-7002負責存取資料,7003-7005負責把7000-7005的資料同步到自己的節點上來。
我們現在來模擬一下一臺matser伺服器宕機的情況

[[email protected] redis]# ps -ef | grep redis
root      1731     1  0 18:21 ?        00:01:02 bin/redis-server *:7000 [cluster]       
root      1733     1  0 18:21 ?        00:00:43 bin/redis-server *:7001 [cluster]       
root      1735     1  0 18:21 ?        00:00:22 bin/redis-server *:7002 [cluster]       
root      1743     1  0 18:21 ?        00:00:40 bin/redis-server *:7003 [cluster]       
root      1745     1  0 18:21 ?        00:00:27 bin/redis-server *:7004 [cluster]       
root      1749     1  0 18:21 ?        00:00:22 bin/redis-server *:7005 [cluster]       
root     23988     1  0 18:30 ?        00:00:42 ./redis-server *:6379    
root     24491  1635  0 21:55 pts/1    00:00:00 grep redis
[[email protected] redis]# kill 1731
[[email protected] redis]# bin/redis-trib check 127.0.0.1:7001
>>> Performing Cluster Check (using node 127.0.0.1:7001)
M: b85519795fa42aa33d4e88d25104cbae895933a6 127.0.0.1:7001
   slots:5461-10922 (5462 slots) master
   1 additional replica(s)
M: b681e1a151890cbf957d1ff08352ee48f6ae39e6 127.0.0.1:7002
   slots:10923-16383 (5461 slots) master
   1 additional replica(s)
S: b7ec92919e5bcffa76c8eee338f8ca5155293c64 127.0.0.1:7004
   slots: (0 slots) slave
   replicates b85519795fa42aa33d4e88d25104cbae895933a6
S: 8a0d2a3f271b349744a971e1b0a545405de2742e 127.0.0.1:7005
   slots: (0 slots) slave
   replicates b681e1a151890cbf957d1ff08352ee48f6ae39e6
M: d403713ab9db48aeac5b5393b69e1201026ef479 127.0.0.1:7003
   slots:0-5460 (5461 slots) master
   0 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

這裡看得出來,現在已經有了3個節點了,7003被選取成了替代7000成為主節點了。
我們再來模擬 7000節點重新啟動了的情況,那麼它還會自動加入到叢集中嗎?那麼,7000這個節點上充當什麼角色呢? 我們試一下:

[[email protected] redis]# bin/redis-server cluster/7000/redis.conf
[[email protected] redis]# bin/redis-trib check 127.0.0.1:7000
>>> Performing Cluster Check (using node 127.0.0.1:7000)
S: bdcddddd3d78a866b44b68c7ae0e5ccf875c446a 127.0.0.1:7000
   slots: (0 slots) slave
   replicates d403713ab9db48aeac5b5393b69e1201026ef479
S: b7ec92919e5bcffa76c8eee338f8ca5155293c64 127.0.0.1:7004
   slots: (0 slots) slave
   replicates b85519795fa42aa33d4e88d25104cbae895933a6
S: 8a0d2a3f271b349744a971e1b0a545405de2742e 127.0.0.1:7005
   slots: (0 slots) slave
   replicates b681e1a151890cbf957d1ff08352ee48f6ae39e6
M: b681e1a151890cbf957d1ff08352ee48f6ae39e6 127.0.0.1:7002
   slots:10923-16383 (5461 slots) master
   1 additional replica(s)
M: b85519795fa42aa33d4e88d25104cbae895933a6 127.0.0.1:7001
   slots:5461-10922 (5462 slots) master
   1 additional replica(s)
M: d403713ab9db48aeac5b5393b69e1201026ef479 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.

這裡我們可以看到7000節點變成了7003節點的從節點
我們試著將7000和7003兩個節點都關掉

[root@centos1 redis]# ps -ef | grep redis
root      1733     1  0 18:21 ?        00:00:45 bin/redis-server *:7001 [cluster]       
root      1735     1  0 18:21 ?        00:00:24 bin/redis-server *:7002 [cluster]       
root      1743     1  0 18:21 ?        00:00:42 bin/redis-server *:7003 [cluster]       
root      1745     1  0 18:21 ?        00:00:29 bin/redis-server *:7004 [cluster]       
root      1749     1  0 18:21 ?        00:00:24 bin/redis-server *:7005 [cluster]       
root     23988     1  0 18:30 ?        00:00:43 ./redis-server *:6379    
root     24527     1  0 22:04 ?        00:00:00 bin/redis-server *:7000 [cluster]       
root     24541  1635  0 22:07 pts/1    00:00:00 grep redis
[root@centos1 redis] kill 1743
[root@centos1 redis] kill 24527

[root@centos1 redis]# bin/redis-trib check 127.0.0.1:7001
>>> Performing Cluster Check (using node 127.0.0.1:7001)
M: b85519795fa42aa33d4e88d25104cbae895933a6 127.0.0.1:7001
   slots:5461-10922 (5462 slots) master
   1 additional replica(s)
M: b681e1a151890cbf957d1ff08352ee48f6ae39e6 127.0.0.1:7002
   slots:10923-16383 (5461 slots) master
   1 additional replica(s)
S: b7ec92919e5bcffa76c8eee338f8ca5155293c64 127.0.0.1:7004
   slots: (0 slots) slave
   replicates b85519795fa42aa33d4e88d25104cbae895933a6
S: 8a0d2a3f271b349744a971e1b0a545405de2742e 127.0.0.1:7005
   slots: (0 slots) slave
   replicates b681e1a151890cbf957d1ff08352ee48f6ae39e6
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[ERR] Not all 16384 slots are covered by nodes.

這裡我們的叢集就不能工作了,因為兩個節點主節點和從節點都掛掉了,原來7001分配的slot現在無節點接管,需要人工介入重新分配slots。

叢集中加入新的主節點

這裡在cluster目錄下再新建一個7006並修改對應的配置檔案,然後啟動這個這個redis程序
然後再使用redis-trib的add node指令加入節點

bin/redis-trib add-node 127.0.0.1:7006 127.0.0.1:7000

這裡前面的節點表示要加入的節點,第二個節點表示要加入的叢集中的任意一個節點,用來標識這個叢集

[[email protected] redis]# bin/redis-trib 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
>>> Performing Cluster Check (using node 127.0.0.1:7000)
M: bdcddddd3d78a866b44b68c7ae0e5ccf875c446a 127.0.0.1:7000
   slots:0-5460 (5461 slots) master
   1 additional replica(s)
S: d403713ab9db48aeac5b5393b69e1201026ef479 127.0.0.1:7003
   slots: (0 slots) slave
   replicates bdcddddd3d78a866b44b68c7ae0e5ccf875c446a
S: b7ec92919e5bcffa76c8eee338f8ca5155293c64 127.0.0.1:7004
   slots: (0 slots) slave
   replicates b85519795fa42aa33d4e88d25104cbae895933a6
M: b85519795fa42aa33d4e88d25104cbae895933a6 127.0.0.1:7001
   slots:5461-10922 (5462 slots) master
   1 additional replica(s)
S: 8a0d2a3f271b349744a971e1b0a545405de2742e 127.0.0.1:7005
   slots: (0 slots) slave
   replicates b681e1a151890cbf957d1ff08352ee48f6ae39e6
M: b681e1a151890cbf957d1ff08352ee48f6ae39e6 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.
>>> Send CLUSTER MEET to node 127.0.0.1:7006 to make it join the cluster.
[OK] New node added correctly.
[[email protected] redis]# bin/redis-trib check 127.0.0.1:7006
>>> Performing Cluster Check (using node 127.0.0.1:7000)
M: bdcddddd3d78a866b44b68c7ae0e5ccf875c446a 127.0.0.1:7000
   slots:0-5460 (5461 slots) master
   1 additional replica(s)
S: d403713ab9db48aeac5b5393b69e1201026ef479 127.0.0.1:7003
   slots: (0 slots) slave
   replicates bdcddddd3d78a866b44b68c7ae0e5ccf875c446a
S: b7ec92919e5bcffa76c8eee338f8ca5155293c64 127.0.0.1:7004
   slots: (0 slots) slave
   replicates b85519795fa42aa33d4e88d25104cbae895933a6
M: e55599320dabfb31bd22a01407e66121f075e7d3 127.0.0.1:7006
   slots: (0 slots) master
   0 additional replica(s)
M: b85519795fa42aa33d4e88d25104cbae895933a6 127.0.0.1:7001
   slots:5461-10922 (5462 slots) master
   1 additional replica(s)
S: 8a0d2a3f271b349744a971e1b0a545405de2742e 127.0.0.1:7005
   slots: (0 slots) slave
   replicates b681e1a151890cbf957d1ff08352ee48f6ae39e6
M: b681e1a151890cbf957d1ff08352ee48f6ae39e6 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.

這裡我們可以看到7006節點已經變成了一個主節點,然鵝,等等,好像發現了有什麼地方不對

M: e55599320dabfb31bd22a01407e66121f075e7d3 127.0.0.1:7006
   slots: (0 slots) master

裡面0 slots,也就是說節點6沒有分配雜湊槽,即不能進行資料的存取,拿我加上去幹嘛。。
原來redis cluster 不是在新加節點的時候幫我們做好了遷移工作,需要我們手動對叢集進行重新分片遷移,也是這個命令:

/bin/redis-trib reshard 127.0.0.1:7000

這個命令是用來遷移slot節點的,後面的127.0.0.1:7000是表示哪個叢集的,7000-7006都是可以的

[[email protected]]# 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: 30858dbf483b61b9