1. 哨兵架構的侷限性
在哨兵架構中,雖然我們可以利用哨兵在主服務器宕機時,快速、自動地選擇一個新的主服務器,但是在選擇的這段時間依然無法進行寫操作。
同時,如果我們想使Redis
的存儲能力達到1T
,那麼主從架構是無法達到的。我所見過的計算機內存最大爲 64G
,和 1T
相差甚遠。
由此,便產生了Redis
的集羣架構。
2. Redis 集羣架構
Redis
的集羣架構圖如下:
Redis
的集羣是Redis
提供的分佈式數據庫方案,集羣通過分片來進行數據共享,並提供複製和故障轉移功能。
優點
存儲容量不受限制,可以進行橫向擴容,新增Master
即可。
數據分片可理解爲hash
的方式,被存儲到不同的Master
中,如果其中一個Master
掛掉,那麼有新的數據進行插入,並不意味着一定插入到掛掉的Master
中,倘若Master
的數量越多,那麼數據插入掛掉的Master
的概率便越小。同時,Sentinel
會快速進行主服務器的重新選舉,數據被丟失的概率極低。可見,可用性非常高,並且讀寫的吞吐量也很高。
3. 槽指派
Redis
集羣通過分片的方式來保存數據庫中的鍵值對:集羣的整個數據庫被分爲16384個槽(slot
),數據庫中的每個鍵都屬於這16384
個槽的其中一個(鍵並不存儲在槽中,還是在 Redis
服務器中,通過槽可以確定其所屬的節點,找到該節點後再節點的數據庫中進行鍵值對操作,而槽的作用是進行分流),集羣中的每個節點可以處理0
個或最多16384
個槽。
當數據庫中的16384
個槽都有節點在處理時,集羣處於上線狀態(ok
);如果數據庫中有任何一個槽沒有得到處理,那麼集羣處於下線狀態( fail
)。
如果集羣啓動後,並沒有分配槽位,所以並不能使用。
槽被指派好後,結構圖如下所示:
4. 在集羣中執行命令
當客戶端向節點發送與數據庫鍵有關的命令時,接收命令的節點會計算出命令要處理的數據庫鍵屬於哪個槽,並檢查這個槽是否指派給了自己:
- 如果鍵所在的槽正好就指派給了當前節點,那麼節點直接執行這個命令。
- 如果鍵所在的槽並沒有指派給當前節點,那麼節點會向客戶端返回一個MOVED錯
誤,指引客戶端轉向( redirect )至正確的節點,並再次發送之前想要執行的命令。
4.1 計算鍵屬於哪個槽
節點使用以下算法來計算給定鍵key
屬於哪個槽:
def slot_number(key):
return CRC16(key) & 16383
其中CRC16(key)
語句用於計算鍵key
的CRC-16
·校驗和,而& 16383
則用於計算出介於0-16383
的整數作爲鍵key
的槽號。