1.為什麼要有叢集
由於Redis主從複製架構每個資料庫都要儲存整個叢集中的所有資料,容易形成木桶效應,所以Redis3.0之後的版本新增特性就是叢集(Cluster)

2.Redis叢集架構說明
Redis叢集架構說明

架構細節:
(1)所有的redis節點彼此互聯(PING-PONG機制),內部使用二進位制協議優化傳輸速度和頻寬.
(2)節點的fail是通過叢集中超過半數的master節點檢測失效時才生效.
(3)客戶端與redis節點直連,不需要中間proxy層.客戶端不需要連線叢集所有節點,連線叢集中任何一個可用節點即可
(4)redis-cluster把所有的物理節點對映到[0-16383]slot上,cluster 負責維護node<->slot<->key

3.Redis Cluster環境搭建
3.1 分別修改配置檔案,將埠分別設定為:6379、6380、6381,同時要設定pidfile檔案為不同的路徑。並且允許叢集模式,修改叢集配置檔案指向地址,並且開啟遠端訪問

修改配置檔案
# vim /opt/redis/6379/6379.conf

# 開啟守護程序模式
daemonize yes

# 修改啟動埠為6379
port 6379

# 修改pidfile指向路徑
pidfile /opt/redis/6379/redis_6379.pid

# 開啟允許叢集 
cluster-enabled yes

# 修改叢集配置檔案指向路徑
cluster-config-file nodes-6379.conf

# 註釋一下內容開啟遠端訪問
# bind 127.0.0.1

# 關閉保護模式
protected-mode no

以此類推,修改埠63806381配置。

3.2 分別啟動redis例項

# cd /opt/redis/redis-3.2.8/bin
# ./redis-server /opt/redis/6379/6379.conf 
# ./redis-server /opt/redis/6380/6380.conf     
# ./redis-server /opt/redis/6381/6381.conf 

3.3 檢視redis狀態
檢視redis狀態
說明redis已經是以叢集方式啟動了,但是redis之間關係還沒確定下來

3.4 因為redis-trib.rb是由ruby語言編寫的所以需要安裝ruby環境

安裝ruby環境
# yum -y install zlib ruby rubygems

自行上傳redis-3.2.1.gem然後安裝
# gem install -l redis-3.2.1.gem

3.5 建立叢集Redis關係

首先,進入redis的安裝包路徑下
# cd /opt/redis/redis-3.2.8/src

執行命令:
# ./redis-trib.rb create --replicas 0 192.168.29.128:6379 192.168.29.128:6380 192.168.29.128:6381

說明:--replicas 0:指定了從資料的數量為0
注意:這裡不能使用127.0.0.1,否則在Jedis客戶端使用時無法連線到!

3.6 如果出現如下異常

/usr/local/share/gems/gems/redis-3.2.1/lib/redis/client.rb:113:in `call': ERR Slot 0 is already busy (Redis::CommandError)
        from /usr/local/share/gems/gems/redis-3.2.1/lib/redis.rb:2556:in `block in method_missing'
        from /usr/local/share/gems/gems/redis-3.2.1/lib/redis.rb:37:in `block in synchronize'
        from /usr/share/ruby/monitor.rb:211:in `mon_synchronize'
        from /usr/local/share/gems/gems/redis-3.2.1/lib/redis.rb:37:in `synchronize'
        from /usr/local/share/gems/gems/redis-3.2.1/lib/redis.rb:2555:in `method_missing'
        from ./redis-trib.rb:212:in `flush_node_config'
        from ./redis-trib.rb:776:in `block in flush_nodes_config'
        from ./redis-trib.rb:775:in `each'
        from ./redis-trib.rb:775:in `flush_nodes_config'
        from ./redis-trib.rb:1296:in `create_cluster_cmd'
        from ./redis-trib.rb:1701:in `<main>'

經檢查,這是由於上一次配置叢集失敗時留下的配置資訊導致的。 只要把redis.conf中定義的 cluster-config-file 所在的檔案刪除,重新啟動redis-server及執行redis-trib即可。

3.7 建立叢集Redis關係正常執行響應如下

>>> Creating cluster
>>> Performing hash slots allocation on 3 nodes...
Using 3 masters:
192.168.29.128:6379
192.168.29.128:6380
192.168.29.128:6381
M: d5d0951bb185a67a44d29dd2142170dbce84d977 192.168.29.128:6379
   slots:0-5460 (5461 slots) master
M: e41fe58ef571836d891656b482307628b3f7ab35 192.168.29.128:6380
   slots:5461-10922 (5462 slots) master
M: ddbc810661f81500059e0b22b1550713a0e3766d 192.168.29.128:6381
   slots:10923-16383 (5461 slots) master
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 192.168.29.128:6379)
M: d5d0951bb185a67a44d29dd2142170dbce84d977 192.168.29.128:6379
   slots:0-5460 (5461 slots) master
   0 additional replica(s)
M: ddbc810661f81500059e0b22b1550713a0e3766d 192.168.29.128:6381
   slots:10923-16383 (5461 slots) master
   0 additional replica(s)
M: e41fe58ef571836d891656b482307628b3f7ab35 192.168.29.128:6380
   slots:5461-10922 (5462 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.8 檢視叢集節點資訊
檢視叢集節點資訊

3.9 測試
3.9.1 測試插入資料
插入資料
因為abc的hash槽資訊是在6380上,現在使用redis-cli連線的6379,無法完成set操作,需要客戶端跟蹤重定向。使用redis-cli -c

3.9.2 重新測試插入資料
重新測試插入資料

4. 插槽的概念及插槽分配
整個Redis提供了16384個插槽,也就是說叢集中的每個節點分得的插槽數總和為16384。./redis-trib.rb 指令碼實現了是將16384個插槽平均分配給了N個節點。當我們執行set abc 123命令時,redis是如何將資料儲存到叢集中的呢?執行步驟:

i.接收命令set abc 123
ii.通過key(abc)計算出插槽值,然後根據插槽值找到對應的節點。abc的插槽值為:7638
iii.重定向到該節點執行命令

注意:如果插槽數有部分是沒有指定到節點的,那麼這部分插槽所對應的key將不能使用。

5.新增叢集節點
5.1 再開啟一個例項的埠為6382 配置同上
再開啟一個例項的埠為6382

5.2 執行指令碼建立6382節點與叢集的關係
執行指令碼建立6382節點與叢集的關係

5.3 檢視叢集狀態,發現新增的節點沒有插槽
這裡寫圖片描述

5.4 給6382節點分配插槽
給6382節點分配插槽

5.5 檢視叢集節點狀態
檢視叢集節點狀態

6.刪除叢集節點
想要刪除叢集節點中的某一個節點,需要嚴格執行2步:

6.1.將這個節點上的所有插槽轉移到其他節點上
6.1.1執行指令碼:./redis-trib.rb reshard 192.168.29.128:6382

6.1.2選擇需要轉移的插槽的數量,因為6382有100個,所以轉移100個

6.1.3輸入轉移的節點的id,我們轉移到6379節點

6.1.4輸入插槽來源id,也就是6382的id

6.1.5輸入done,開始轉移
轉移插槽

6.1.6檢視叢集節點資訊,可以看到6380節點已經沒有插槽了
檢視叢集資訊

6.2.刪除節點
6.2.1 刪除節點
刪除節點

6.2.2 檢視叢集節點資訊
檢視叢集資訊

7. Redis Cluster高可用
7.1 假設叢集中某一節點宕機 測試資料寫入操作
關閉6380節點

測試叢集狀態

我們嘗試執行set命令,結果發現無法執,行叢集不可用了?? 這叢集也太弱了吧??

7.2 叢集中的主從複製架構
叢集中的主從複製架構

7.3 本教程不詳細介紹叢集中主從複製架構的具體安裝,只提一下過程

7.3.1 為每個叢集節點新增Slave,形成主從複製架構,主從複製架構可參考:主從複製架構,搭建結構如下所示

6379(Master)     6479(Slave of 6379)     6579(Slave of 6379)
6380(Master)     6480(Slave of 6380)     6580(Slave of 6380)
6381(Master)     6481(Slave of 6381)     6581(Slave of 6381)

7.3.2 為每個主從複製架構新增哨兵叢集,哨兵模式叢集可參考:哨兵模式叢集

7.3.3 建立叢集 使用如下命令

./redis-trib.rb create --replicas 2 192.168.29.128:6379 192.168.29.128:6380 192.168.29.128:6381 192.168.29.128:6479 192.168.29.128:6480 192.168.29.128:6481 192.168.29.128:6579 192.168.29.128:6580 192.168.29.128:6581 

7.4.4 自行測試高可用Cluster環境

注意在叢集環境中:
多鍵的命令操作(如MGET、MSET),如果每個鍵都位於同一個節點,則可以正常支援,否則會提示錯誤。

叢集中的節點只能使用0號資料庫,如果執行SELECT切換資料庫會提示錯誤。