工作十多年的BAT架構(gòu)師總結(jié)的Redis集群原理,圖文并茂,小白也能輕松看懂

Redis作為一款性能優(yōu)異的內(nèi)存數(shù)據(jù)庫,支撐著眾多億級流量平臺,也成為很多互聯(lián)網(wǎng)公司的標(biāo)配。這里將以Redis Cluster集群為核心,基于最新的Redis5版本,從原理再到實戰(zhàn),玩轉(zhuǎn)Redis集群

常見Redis集群方案

在介紹Redis Cluster集群方案之前,為了方便對比,先簡單了解一下業(yè)界常見的Redis集群方案:

1 基于客戶端分片

Redis Sharding是Redis Cluster出來之前,業(yè)界普遍使用的多Redis實例集群方法。其主要思想是基于哈希算法,根據(jù)Redis數(shù)據(jù)的key的哈希值對數(shù)據(jù)進(jìn)行分片,將數(shù)據(jù)映射到各自節(jié)點上

優(yōu)點在于實現(xiàn)簡單,缺點在于當(dāng)Redis集群調(diào)整,每個客戶端都需要更新調(diào)整

2 基于代理服務(wù)器分片

客戶端發(fā)送請求到獨立部署代理組件,代理組件解析客戶端的數(shù)據(jù),并將請求轉(zhuǎn)發(fā)至正確的節(jié)點,最后將結(jié)果回復(fù)給客戶端

優(yōu)點在于透明接入,容易集群擴(kuò)展,缺點在于多了一層代理轉(zhuǎn)發(fā),性能有所損耗

3 Redis Sentinel(哨兵)

Redis Sentinel是官方從Redis 2.6版本提供的高可用方案,在Redis主從復(fù)制集群的基礎(chǔ)上,增加Sentinel集群監(jiān)控整個Redis集群。當(dāng)Redis集群master節(jié)點發(fā)生故障時,Sentinel進(jìn)行故障切換,選舉出新的master,同時Sentinel本身支持高可用集群部署

優(yōu)點在于支持集群高可用,高性能讀寫,缺點在于沒有實現(xiàn)數(shù)據(jù)分片,每個節(jié)點需要承載完整數(shù)據(jù)集,負(fù)載能力受當(dāng)個Redis服務(wù)器限制,僅支持通過增加機(jī)器內(nèi)存實現(xiàn)垂直擴(kuò)容,不支持水平擴(kuò)展

Redis Cluster設(shè)計

1 整體設(shè)計

Redis Cluster 是 在 3.0 版本正式推出的高可用集群方案,相比Redis Sentinel,Redis Cluster方案不需要額外部署Sentinel集群,而是通過集群內(nèi)部通信實現(xiàn)集群監(jiān)控,故障時主從切換;同時,支持內(nèi)部基于哈希實現(xiàn)數(shù)據(jù)分片,支持動態(tài)水平擴(kuò)容

整體架構(gòu)如下:

集群中有多個主節(jié)點,每個主節(jié)點有多個從節(jié)點,主從節(jié)點間數(shù)據(jù)一致,最少需要3個主節(jié)點,每個主節(jié)點最少需要1個從節(jié)點

高可用:當(dāng)master節(jié)點故障時,自動主從切換

高性能:主節(jié)點提供讀寫服務(wù),從節(jié)點只讀服務(wù),提高系統(tǒng)吞吐量

可擴(kuò)展性:集群的數(shù)據(jù)分片存儲,主節(jié)點間數(shù)據(jù)各不同,各自維護(hù)對應(yīng)數(shù)據(jù),可以為集群添加節(jié)點進(jìn)行擴(kuò)容,也可以下線部分節(jié)點進(jìn)行水平縮容

2 數(shù)據(jù)分片

將整個數(shù)據(jù)集按照一定規(guī)則分配到多個節(jié)點上,稱為數(shù)據(jù)分片,Redis Cluster采用的分片方案是哈希分片

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

槽是 Redis 集群管理數(shù)據(jù)的基本單位,集群擴(kuò)容收縮就是槽和數(shù)據(jù)在節(jié)點之間的移動

槽與節(jié)點映射關(guān)系如下:

每個集群節(jié)點維護(hù)著一個16384 bit (2kB)的位數(shù)組,每個bit對應(yīng)相同編號的槽,用 0 / 1標(biāo)識對于某個槽自己是否擁有

集群節(jié)點同時還維護(hù)著槽到集群節(jié)點的映射,是由長度為16384,數(shù)組下標(biāo)代表槽編號,值為節(jié)點信息的數(shù)組

3 集群擴(kuò)容

Redis Cluster支持不影響集群對外服務(wù)的情況下,對集群進(jìn)行動態(tài)擴(kuò)容或縮容,當(dāng)Redis 新節(jié)點加入現(xiàn)有集群后,需要為其遷移槽和數(shù)據(jù),確保遷移后每個節(jié)點負(fù)責(zé)相似數(shù)量的槽,使數(shù)據(jù)分布均勻在各節(jié)點上

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

源節(jié)點將指定slot數(shù)據(jù)遷移到目標(biāo)節(jié)點,基本流程如下:

(1) redis-cli設(shè)置目標(biāo)節(jié)點指定slot狀態(tài)importing,讓目標(biāo)節(jié)點準(zhǔn)備遷入slot數(shù)據(jù)

(2) redis-cli設(shè)置源節(jié)點指定slot狀態(tài)migrating,讓讓源節(jié)點準(zhǔn)備遷出slot的數(shù)據(jù)

(3) redis-cli批量遷移源節(jié)點指定slot中的數(shù)據(jù)到目標(biāo)節(jié)點

(4) 數(shù)據(jù)遷移完后 redis-cli向集群所有主節(jié)點通知槽被分配給目標(biāo)節(jié)點,主節(jié)點更新slot與節(jié)點映射關(guān)系信息

通常情況下,如果客戶端請求的數(shù)據(jù)不在節(jié)點上,節(jié)點會回復(fù) MOVED 重定向信息,客戶端根據(jù)該信息再請求正確的節(jié)點。對于正在遷移的slot數(shù)據(jù),保證客戶端仍然能正常訪問的設(shè)計如下:

(1) 遷移完成后才更新slot與節(jié)點映射關(guān)系信息,如果遷移進(jìn)行中的映射信息保持與遷移前一致

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

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

(4) 客戶端根據(jù)ASK 重定向異常提取出目標(biāo)節(jié)點信息,先向目標(biāo)節(jié)點發(fā)送ASKING命令請求操作,再執(zhí)行鍵命令

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

ASK 重定向說明集群正在進(jìn)行 slot 數(shù)據(jù)遷移,客戶端無法知道什么時候遷移完成,因此只能是臨時性的重定向,客戶端不會更新 slot 到 Redis 節(jié)點的映射緩存。

MOVED 重定向說明鍵對應(yīng)的slot 已經(jīng)明確指定到新的節(jié)點,因此需要更新 slot 到 Redis 節(jié)點的映射緩存

4 CAP取舍

CAP包括:一致性(Consistency)、可用性(Availability)、分區(qū)容錯性(Partition tolerance),系統(tǒng)如果不能在時限內(nèi)達(dá)成數(shù)據(jù)一致性,就意味著發(fā)生了分區(qū)的情況,必須在C和A之間做出選擇

Redis Cluster選擇了CA架構(gòu),為了保證可用性,Redis并不保證強(qiáng)一致性,在特定條件下會出現(xiàn)數(shù)據(jù)不一致甚至丟失寫操作

第一個原因是:為了在性能和一致性上做出權(quán)衡,主從節(jié)點間數(shù)據(jù)同步是異步復(fù)制的,當(dāng)客戶端成功寫入master節(jié)點,master返回成功,master節(jié)點才將寫操作異步復(fù)制給slave節(jié)點

另外一個原因是,當(dāng)集群發(fā)送網(wǎng)絡(luò)分區(qū),集群可能會分為兩部分:多數(shù)派和少數(shù)派,假如masterA節(jié)點位于少數(shù)派,如果網(wǎng)絡(luò)分區(qū)發(fā)生時間較短,那么集群將會繼續(xù)正常運(yùn)作;如果分區(qū)的時間足夠長,讓多數(shù)派中選舉為新的master替代matsterA,那么分區(qū)期間寫入masterA的數(shù)據(jù)就丟失了

在網(wǎng)絡(luò)分區(qū)期間, 客戶端可以向matsterA發(fā)送寫命令的最大時間是有限制的, 這一時間限制稱為節(jié)點超時時間(cluster-node-timeout),是 Redis集群的一個重要的配置選項

總結(jié)

至此,Redis Cluster集群原理介紹到這里,其實還有集群通信協(xié)議,內(nèi)存,數(shù)據(jù)備份,主從復(fù)制等特性值得學(xué)習(xí),是設(shè)計分布式系統(tǒng)的典范,有機(jī)會再展開介紹

下一篇,介紹Redis Cluster的集群實戰(zhàn)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容