Redis集群是Redis提供的分布式數據庫方案,集群通過分片來進行數據共享,並提供復制和故障轉移功能
節點
一個Redis集群通常由多個節點Node組成,節點與節點之間通過握手(CLUSTER MEET)建立連接
127.0.0.1:7000>cluster meet 127.0.0.1:7001
槽指派
Redis集群通過分片的方式來保存數據庫中的鍵值對:集群的整個數據庫被分為16384個槽,數據庫中的每個鍵都屬於這16384個槽中的其中一個,集群中的每個節點都可以處理0個或者最多16384個槽
ps:為什么需要16384個槽,redis采用的哈希算法(crc)產生了16位的數,為什么不是65536個槽?
原因在於redis集群節點之間需要定期發送心跳包,心跳包包括槽位信息,如果是65536個槽需要65536/8=8K字節的大小,而16384個槽需要2K字節的大小,綜合考慮redis采用了16384個槽
只有所有的槽都有節點在處理時,集群叫做上線(ok)狀態否則叫做下線(fail)狀態。
每個節點會將自己的slots(記錄了自己的槽指派信息)發送給其他節點,以此來告知對方自己負責哪些槽,同時節點也會記錄集群中其他節點的slots信息
當客戶端向節點發送與數據庫鍵有關的命令時,節點會先判斷該鍵屬於哪個槽,該槽由哪個節點處理,如果由自己處理則會直接執行這個命令,否則會返回MOVED錯誤指引客戶端轉向正確的節點,並在此發送想要執行的命令。
需要注意的是集群模式的redis-cli客戶端在接收到MOVED錯誤后,並不會打印MOVED錯誤,而是根據MOVED錯誤自動進行節點轉向,並打印節點轉向信息。
如何計算鍵屬於哪個槽?
CRC16(key) & 16384 ,該方法表示先計算key的CRC-16校驗和,在把它映射到0-16383之間
重新分片
Redis集群重新分片操作可以將任意數量已經指派給某個節點的槽,分配給另一個節點,且這個操作可以在線進行,集群不需要下線
遷移工作,可以使用redis-trib管理軟件進行遷移,具體原理如下:
1、對目標節點,即是D節點發送cluster setslot import 命令,讓目標節點做好准備接收遷移准備。
2、對源節點,即是C節點,發送cluster setslot migrating命令,讓源節點做好准備遷移准備。
3、對源節點,發送cluster getkeysinslot
4、對於步驟3中獲取的key,向源節點發送命令migrate
5、重復上述3,4步驟,直到所有key都遷移成功
在分片過程中,如果客戶端向源節點發送一個跟數據庫鍵有關的命令,而這個鍵已經被遷移到了目標節點,源節點會返回一個ASK錯誤,指引客戶端跳轉到目標節點中,同MOVED錯誤一樣,該ASK錯誤也是被隱藏的
ASK錯誤和MOVED錯誤:

復制和故障轉移
節點之間會定期發送PING包來檢測對方是否在線,如果發現對方節點故障,則節點會發送消息給其他節點,但半數節點都認為該節點故障,則會真正認為該節點故障
當主節點發生故障后,會進行故障轉移,在從節點中選舉出新的主節點,選舉過程和選舉領頭Sentinel的過程類似:
叢節點發現主節點故障后,會向集群廣播這個消息,收到消息且具有投票權(正在負責處理槽)主節點會投票個這個從節點(每個主節點只能支持它最先收到的那個從節點),當從節點收到半數以上投票時當選主節點
