工作十多年的BAT架構師總結的Redis集羣原理,圖文並茂,小白也能輕鬆看懂

Redis作爲一款性能優異的內存數據庫,支撐着衆多億級流量平臺,也成爲很多互聯網公司的標配。這裏將以Redis Cluster集羣爲核心,基於最新的Redis5版本,從原理再到實戰,玩轉Redis集羣

常見Redis集羣方案

在介紹Redis Cluster集羣方案之前,爲了方便對比,先簡單瞭解一下業界常見的Redis集羣方案:

1 基於客戶端分片

Redis Sharding是Redis Cluster出來之前,業界普遍使用的多Redis實例集羣方法。其主要思想是基於哈希算法,根據Redis數據的key的哈希值對數據進行分片,將數據映射到各自節點上

優點在於實現簡單,缺點在於當Redis集羣調整,每個客戶端都需要更新調整

2 基於代理服務器分片

客戶端發送請求到獨立部署代理組件,代理組件解析客戶端的數據,並將請求轉發至正確的節點,最後將結果回覆給客戶端

優點在於透明接入,容易集羣擴展,缺點在於多了一層代理轉發,性能有所損耗

3 Redis Sentinel(哨兵)

Redis Sentinel是官方從Redis 2.6版本提供的高可用方案,在Redis主從複製集羣的基礎上,增加Sentinel集羣監控整個Redis集羣。當Redis集羣master節點發生故障時,Sentinel進行故障切換,選舉出新的master,同時Sentinel本身支持高可用集羣部署

優點在於支持集羣高可用,高性能讀寫,缺點在於沒有實現數據分片,每個節點需要承載完整數據集,負載能力受當個Redis服務器限制,僅支持通過增加機器內存實現垂直擴容,不支持水平擴展

Redis Cluster設計

1 整體設計

Redis Cluster 是 在 3.0 版本正式推出的高可用集羣方案,相比Redis Sentinel,Redis Cluster方案不需要額外部署Sentinel集羣,而是通過集羣內部通信實現集羣監控,故障時主從切換;同時,支持內部基於哈希實現數據分片,支持動態水平擴容

整體架構如下:

集羣中有多個主節點,每個主節點有多個從節點,主從節點間數據一致,最少需要3個主節點,每個主節點最少需要1個從節點

高可用:當master節點故障時,自動主從切換

高性能:主節點提供讀寫服務,從節點只讀服務,提高系統吞吐量

可擴展性:集羣的數據分片存儲,主節點間數據各不同,各自維護對應數據,可以爲集羣添加節點進行擴容,也可以下線部分節點進行水平縮容

2 數據分片

將整個數據集按照一定規則分配到多個節點上,稱爲數據分片,Redis Cluster採用的分片方案是哈希分片

基本原理如下:Redis Cluster首先定義了編號0 ~ 16383的區間,稱爲槽,所有的鍵根據哈希函數映射到0 ~ 16383整數槽內,計算公式:slot=CRC16(key)&16383。每一個節點負責維護一部分槽以及槽所映射的鍵值數據

槽是 Redis 集羣管理數據的基本單位,集羣擴容收縮就是槽和數據在節點之間的移動

槽與節點映射關係如下:

每個集羣節點維護着一個16384 bit (2kB)的位數組,每個bit對應相同編號的槽,用 0 / 1標識對於某個槽自己是否擁有

集羣節點同時還維護着槽到集羣節點的映射,是由長度爲16384,數組下標代表槽編號,值爲節點信息的數組

3 集羣擴容

Redis Cluster支持不影響集羣對外服務的情況下,對集羣進行動態擴容或縮容,當Redis 新節點加入現有集羣后,需要爲其遷移槽和數據,確保遷移後每個節點負責相似數量的槽,使數據分佈均勻在各節點上

整個數據遷移涉及系列操作,Redis提供了集羣管理工具,包括基於Ruby的redis-trib.rb,還Redis5新提供的基於C語言redis-cli,下面的介紹以redis-cli爲例

源節點將指定slot數據遷移到目標節點,基本流程如下:

(1) redis-cli設置目標節點指定slot狀態importing,讓目標節點準備遷入slot數據

(2) redis-cli設置源節點指定slot狀態migrating,讓讓源節點準備遷出slot的數據

(3) redis-cli批量遷移源節點指定slot中的數據到目標節點

(4) 數據遷移完後 redis-cli向集羣所有主節點通知槽被分配給目標節點,主節點更新slot與節點映射關係信息

通常情況下,如果客戶端請求的數據不在節點上,節點會回覆 MOVED 重定向信息,客戶端根據該信息再請求正確的節點。對於正在遷移的slot數據,保證客戶端仍然能正常訪問的設計如下:

(1) 遷移完成後才更新slot與節點映射關係信息,如果遷移進行中的映射信息保持與遷移前一致

(2) 如果客戶端訪問源節點,訪問的key尚未遷出,則正常的處理該key

(3) 如果客戶端訪問源節點,訪問的key尚已遷出,源節點返回ASK重定向信息

(4) 客戶端根據ASK 重定向異常提取出目標節點信息,先向目標節點發送ASKING命令請求操作,再執行鍵命令

ASK 和 MOVED 這2個重定向控制有如下區別:

ASK 重定向說明集羣正在進行 slot 數據遷移,客戶端無法知道什麼時候遷移完成,因此只能是臨時性的重定向,客戶端不會更新 slot 到 Redis 節點的映射緩存。

MOVED 重定向說明鍵對應的slot 已經明確指定到新的節點,因此需要更新 slot 到 Redis 節點的映射緩存

4 CAP取捨

CAP包括:一致性(Consistency)、可用性(Availability)、分區容錯性(Partition tolerance),系統如果不能在時限內達成數據一致性,就意味着發生了分區的情況,必須在C和A之間做出選擇

Redis Cluster選擇了CA架構,爲了保證可用性,Redis並不保證強一致性,在特定條件下會出現數據不一致甚至丟失寫操作

第一個原因是:爲了在性能和一致性上做出權衡,主從節點間數據同步是異步複製的,當客戶端成功寫入master節點,master返回成功,master節點纔將寫操作異步複製給slave節點

另外一個原因是,當集羣發送網絡分區,集羣可能會分爲兩部分:多數派和少數派,假如masterA節點位於少數派,如果網絡分區發生時間較短,那麼集羣將會繼續正常運作;如果分區的時間足夠長,讓多數派中選舉爲新的master替代matsterA,那麼分區期間寫入masterA的數據就丟失了

在網絡分區期間, 客戶端可以向matsterA發送寫命令的最大時間是有限制的, 這一時間限制稱爲節點超時時間(cluster-node-timeout),是 Redis集羣的一個重要的配置選項

總結

至此,Redis Cluster集羣原理介紹到這裏,其實還有集羣通信協議,內存,數據備份,主從複製等特性值得學習,是設計分佈式系統的典範,有機會再展開介紹

下一篇,介紹Redis Cluster的集羣實戰

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章