Redis叢集與插槽分配(動態新增或刪除結點)
通過cluster nodes命令可以檢視當前叢集的資訊:
該資訊反映出了叢集中的每個節點的id、身份、連線數、插槽數等。
當我們執行set abc 123命令時,redis是如何將資料儲存到叢集中的呢?執行步驟:
1、 接收命令set abc 123
2、 通過key(abc)計算出插槽值,然後根據插槽值找到對應的節點。(abc的插槽值為:7638)
3、 重定向到該節點執行命令
整個Redis提供了16384個插槽,也就是說叢集中的每個節點分得的插槽數總和為16384。
./redis-trib.rb 指令碼實現了是將16384個插槽平均分配給了N個節點。
注意:如果插槽數有部分是沒有指定到節點的
4.6. 插槽和Key的關係
計算key的插槽值:
key的有效部分使用CRC16演算法計算出雜湊值,再將雜湊值對16384取餘,得到插槽值。
什麼是有效部分?
1、 如果key中包含了{符號,且在{符號後存在}符號,並且{和}之間至少有一個字元,則有效部分是指{和}之間的部分;
a) key={hello}_tatao的有效部分是hello
2、 如果不滿足上一條情況,整個key都是有效部分;
a) key=hello_taotao的有效部分是全部
4.7. 新增叢集結點
再開啟一個例項的埠為6382
執行指令碼:
./redis-trib.rb add-node 192.168.56.102:6382 192.168.56.102:6379
已經新增成功!檢視叢集資訊:
發現沒有插槽數。
接下來需要給6382這個服務分配插槽,將6379的一部分(1000個)插槽分配給6382:
檢視節點情況:
4.8. 刪除叢集結點
想要刪除叢集節點中的某一個節點,需要嚴格執行2步:
1、 將這個節點上的所有插槽轉移到其他節點上;
a) 假設我們想要刪除6380這個節點
b) 執行指令碼:./redis-trib.rb reshard 192.168.56.102:6380
c)選擇需要轉移的插槽的數量,因為3380有5128個,所以轉移5128個
d) 輸入轉移的節點的id,我們轉移到6382節點:82ed0d63cfa6d19956dca833930977a87d6ddf7
e) 輸入插槽來源id,也就是6380的id
f)輸入done,開始轉移
g)檢視叢集資訊,可以看到6380節點已經沒有插槽了。
2、 使用redis-trib.rb刪除節點
a) ./redis-trib.rb del-node 192.168.56.102:6380 4a9b8886ba5261e82597f5590fcdb49ea47c4c6c
b) del-node host:port node_id
d)檢視叢集資訊,可以看到已經沒有6380這個節點了。
4.9. 故障轉移
如果叢集中的某一節點宕機會出現什麼狀況?我們這裡假設6381宕機。
我們嘗試連線下叢集,並且檢視叢集資訊,發現6381的節點斷開連線:
我們嘗試執行set命令,結果發現無法執行:
什麼情況?叢集不可用了?? 這叢集也太弱了吧??
4.9.1. 故障機制
1、 叢集中的每個節點都會定期的向其它節點發送PING命令,並且通過有沒有收到回覆判斷目標節點是否下線;
2、 叢集中每一秒就會隨機選擇5個節點,然後選擇其中最久沒有響應的節點放PING命令;
3、 如果一定時間內目標節點都沒有響應,那麼該節點就認為目標節點疑似下線;
4、 當叢集中的節點超過半數認為該目標節點疑似下線,那麼該節點就會被標記為下線;
5、 當叢集中的任何一個節點下線,就會導致插槽區有空檔,不完整,那麼該叢集將不可用;
6、 如何解決上述問題?
a) 在Redis叢集中可以使用主從模式實現某一個節點的高可用
b) 當該節點(master)宕機後,叢集會將該節點的從資料庫(slave)轉變為(master)繼續完成叢集服務;
4.9.2. 叢集中的主從複製架構
架構:
出現故障:
4.9.3. 建立主從叢集
需要啟動6個redis例項,分別是:
6379(主) 6479(從)
6380(主) 6480(從)
6381(主) 6481(從)
啟動redis例項:
cd 6379/ && redis-server ./redis.conf && cd ..
cd 6380/ && redis-server ./redis.conf && cd ..
cd 6381/ && redis-server ./redis.conf && cd ..
cd 6479/ && redis-server ./redis.conf && cd ..
cd 6480/ && redis-server ./redis.conf && cd ..
cd 6481/ && redis-server ./redis.conf && cd ..
建立叢集,指定了從庫數量為1,建立順序為主庫(3個)、從庫(3個):
./redis-trib.rb create --replicas 1 192.168.56.102:6379 192.168.56.102:6380 192.168.56.102:6381 192.168.56.102:6479 192.168.56.102:6480 192.168.56.102:6481
建立成功!檢視叢集資訊:
4.9.4. 測試
儲存、讀取資料OK!
檢視下6480的從庫資料:
看到從6480檢視資料也是被重定向到6380.
說明叢集一切執行OK!
4.9.5. 測試叢集中slave結點宕機
我們將6480節點kill掉,檢視情況。
檢視叢集情況:
發現6480節點不可用。
那麼整個叢集可用嗎?
發現叢集可用,可見從資料庫宕機不會影響叢集正常服務。
恢復6480服務: