Redis集群通過分片(sharding)進行數據共享,並提供復制和故障轉移功能。
節點
一個Redis集群由多個node組成,連接各節點的命令格式如下:
CLUSTER MEET
127.0.0.1:7000> CLUSTER MEET 127.0.0.1 7001
槽指派
Redis集群通過分片的方式來保存鍵值對:集群的整個數據庫被分為16384的槽(slot)。
通過CLUSTER ADDSLOTS命令,可以將一個或多個槽指派給節點負責:
CLUSTER ADDSLOTS
[slot ...] 127.0.0.1:7000> CLUSTER ADDSLOTS 0 1 2 3 4 ... 5000
OK
執行命令將槽0-5000指派給節點7000負責
記錄節點的槽指派信息
slots屬性是一個二進制位數組,數組長度為16384/8=2048個字節,共包含16384個二進制位。
為什么是16384個?
因為節點之間需要經常互相發送心跳等信息,其中就槽位也是包含在內的,取一個中間值16384能在一定程度
上減少消息的大小,又減少了數據不均衡的問題。
計算鍵屬於哪個槽
節點使用 CRC16(key) & 16383 計算出一個 0-16383之間的整數作為鍵key的槽號。
但是,如果計算出來的槽值不能由當前節點處理,那么,該節點會向客戶端返回MOVED錯誤,指引客戶端轉向可
以處理的節點。
MOVED 10086 127.0.0.1:7002
表示槽10086正由127.0.0.1:7002節點負責。
節點數據庫實現
單機和節點的區別:節點只能使用0號數據庫。
淘汰策略是一樣的,從過期key里淘汰最久未使用的key,volatile-LRU。
重新分片
客戶端訪問key時,key所屬的槽如果正在從舊節點轉移到新節點,會發送ask錯誤(隱藏的)。
復制與故障轉移
Redis集群節點分為master和slave,如果主節點下線,會選擇一個從節點作為新的主節點。
設置從節點
CLUSTER REPLICATE <node_id>
可以讓接收命令的節點變成從節點(和復制反命令過來了)
故障轉移
當一個從節點發現自己正在復制的主節點下線了,從節點開始對下線主節點進行故障轉移,以下步驟:
- 被選中的從節點會執行SLAVEOF no one命令,成為新的主節點。
- 將槽指派給自己。
- 新主節點向集群廣播發送PONG消息,昭告天下。
選舉新的主節點
和領頭哨兵選舉類似,都是基於Raft算法實現的。(見Redis哨兵)
Reference
《Redis設計與實現》