天天看點

redis叢集之哈希槽

redis叢集資料結構

redis叢集之哈希槽

clusterNode結構儲存了一個節點的狀态,比如節點的建立時間,名稱。負責處理哪些槽(槽是redis叢集的一個最重要的一個概念,後邊會講到)

redis叢集之哈希槽

clusterLink結構儲存了連接配接節點所需要的資訊,比如套接字描述符,輸入緩存區和輸出緩沖區,主要是用于連接配接其他節點。

redis叢集之哈希槽

每個節點都儲存着一個clusterState結構。這個結構記錄了在目前結點的視角下,叢集的狀态,叢集所包含的節點等資訊

槽指派

redis 叢集通過分片的方式儲存資料庫中的鍵值對:叢集的整個資料庫被分為16384個槽(slot),資料庫中每個鍵都屬于這16384個槽的其中一個,叢集中的每個節點負責0個或者最多16384個槽。

怎麼計算鍵key屬于哪個槽?

節點使用以下方法計算給定的鍵key屬于哪個槽:CRC16(key) & 16383 CRC16(key) 計算鍵key的CRC16校驗和。& 16383 計算出一個0至16383之間的整數作為key的槽号。

節點收到一些指令的時候怎麼高效判斷這個key是否應該由自己處理或者該有其他節點去處理?

首先叢集中每個節點會處理部分槽,所有節點處理完一共16384個槽。節點之間會互相傳播槽指派資訊。節點收到其他節點發送的槽指派資訊之後,會在本節點的clusterState結構的slots數組記錄每個槽由哪個節點負責處理。

假設key 經過計算有槽5000負責,那麼如下圖,節點會以5000為下标取出數組的值,數組的值其實就對應了一個clusterNode結構,取出的值為node2,那麼key會有節點node2代表的節點處理。當然如果通過下标取出的clusterNode為null,表示該槽尚未配置設定。

假設本節點就是node2,那麼本節點會直接執行指令;假設本節點不是node2,那麼節點會根據node2所代表節點的ip 和端口号,向用戶端傳回MOVED錯誤,指引用戶端轉向處理該槽的節點。可以看出找出key 對應的槽有哪個節點處理的複雜度為O(1),是相當高效的。

redis叢集之哈希槽

重新分片

redis叢集的重新分片操作可以将任意數量已經指派給某個節點(源節點)的槽改為指派個另一個節點(目标節點),在重新分片的過程中,叢集不需要下線,并且源節點和目标節點都可以繼續處理指令請求。

當用戶端向一個客戶算發送指令的時候,而對應的槽正被遷移,那麼如果redis在目前節點找到對應的key 就直接執行指令請求,如果沒有找到就會傳回用戶端ASK錯誤(使用者不會感覺)指引用戶端通路目标節點。

繼續閱讀