前面講解了關(guān)于redis單機(jī)在大 數(shù)據(jù)量情況的所出現(xiàn)的瓶頸問(wèn)題,并講解了通過(guò)redis 主從架構(gòu)和 哨兵集群結(jié)合,實(shí)現(xiàn)99.99% 高可用 、水平擴(kuò)容支持更高QPS的解決方案。
在大數(shù)據(jù)量面前,主從架構(gòu)結(jié)合哨兵集群的解決方案在復(fù)雜的配置下就顯得有些捉襟見(jiàn)肘了;數(shù)據(jù)量越大,就愈明顯。所以本章從海量數(shù)據(jù)出發(fā),redis cluster 集群架構(gòu)以更少的配置做更多的事。
redis cluster 集群架構(gòu) 的優(yōu)勢(shì)在哪呢?
支持水平擴(kuò)容 N個(gè)redis master node,并且每個(gè)master node同樣可以掛載 N 個(gè) slave node
讀寫分離的架構(gòu)(這個(gè)概念其實(shí)在redis cluster就沒(méi)有了,但是可以做,因?yàn)閞edis cluster 更強(qiáng)調(diào)的是水平擴(kuò)容)
高并發(fā)
高可用(無(wú)需sentinel 哨兵監(jiān)控,如果master 掛了,redis cluster 內(nèi)部自動(dòng) 將slave 切換 master)
配置減少(相對(duì) replication + sentinal 而已,就不需要手動(dòng)搭建replication復(fù)制+主從架構(gòu)+讀寫分離+哨兵集群+高可用了)
redis cluster 和 replication + sentinal 比較?
- 兩者都是解決redis 單機(jī)瓶頸問(wèn)題(宕機(jī)不可用,低QPS,性能差等)
- 根據(jù)自身數(shù)據(jù)需求選擇合適解決方案
- 數(shù)據(jù)量很少(幾個(gè)G),redis 單機(jī)就可以解決
- 數(shù)據(jù)量大, 一主多從(1 master N slave ,具體根據(jù)自身讀吞吐量而定) + 哨兵集群(sentinal 保證高可用)
-
海量數(shù)據(jù),redis cluster 集群(N master N slave , 海量數(shù)據(jù) + 高并發(fā)+ 高可用)
replication + sentinal vs redis cluster
redis cluster 數(shù)據(jù)分片
redis cluster 會(huì)對(duì)數(shù)據(jù)進(jìn)行自動(dòng)分片,將數(shù)據(jù)分配到每個(gè)Master 上(自動(dòng)的負(fù)載均衡)
redis cluster 所有節(jié)點(diǎn)直接都是相互連接的,它要求開(kāi)放兩個(gè)端口,一個(gè)端口負(fù)責(zé)對(duì)外數(shù)據(jù)交換(port:6379),另外一個(gè)端口用來(lái)內(nèi)部通信(port : 6379 + 10000 = 16379),也就是集群總線的通信(cluster bus)
- cluster bus 用來(lái)進(jìn)行故障檢測(cè),配置更新,故障轉(zhuǎn)移授權(quán)
- cluster bus 使用一種二進(jìn)制的協(xié)議,主要用于節(jié)點(diǎn)間進(jìn)行高效的數(shù)據(jù)交換,占用更少的網(wǎng)絡(luò)帶寬和處理時(shí)間
redis cluster 使用什么樣的算法保證數(shù)據(jù)分片?
首先講下最原始的的 Hash 算法,如下圖所示:

其次講下一致性 Hash 算法(自動(dòng)緩存遷移) + 虛擬節(jié)點(diǎn)(自動(dòng)負(fù)載均衡)

一致性hash 算法 一定程度上解決了node宕機(jī)后的大部分?jǐn)?shù)據(jù)失效問(wèn)題,但是也會(huì)導(dǎo)致node 的熱點(diǎn)問(wèn)題,降低性能,這個(gè)又該怎么解決呢? 可以通過(guò)增加虛擬節(jié)點(diǎn)的方式 讓 hash 點(diǎn)散落更均勻 ,不光能解決熱點(diǎn)問(wèn)題,還可以達(dá)到自動(dòng)的負(fù)載均衡效果。

redis cluster 采用的是 hash slot 算法
redis cluster 擁有固定的16384個(gè)slot (槽) ;這個(gè)槽是虛擬的,并不是真正存在。slot 被 分布到 各個(gè)master 中,當(dāng) 某個(gè)key 映射到 某個(gè)master 負(fù)責(zé)的槽時(shí),就由對(duì)應(yīng)的master 為key 提供服務(wù)
在redis cluster 中,只有master 才擁有對(duì)slot的所有權(quán),slave 只負(fù)責(zé)使用 slot,并沒(méi)有所有權(quán)。
那么 redis Cluster 又是如何知道哪些槽是由哪些節(jié)點(diǎn)負(fù)責(zé)的呢?Master 又是如何知道哪個(gè)槽是自己的呢?
位序列結(jié)構(gòu)(節(jié)約存儲(chǔ)空間)
每個(gè)Master節(jié)點(diǎn)都維護(hù)著一個(gè)位序列,為16384 / 8 字節(jié);Master 節(jié)點(diǎn) 通過(guò) bit 來(lái)標(biāo)識(shí)哪些槽自己是否擁有。比如對(duì)于編號(hào)為1的槽,Master只要判斷序列的第二位(索引從0開(kāi)始)是不是為1即可。
集群同時(shí)維護(hù)著槽與集群節(jié)點(diǎn)的映射關(guān)系,由16384個(gè)長(zhǎng)度的數(shù)組記錄,槽編號(hào)為數(shù)組的下標(biāo),數(shù)組內(nèi)容為集群節(jié)點(diǎn),這樣就可以很快地通過(guò)槽編號(hào)找到負(fù)責(zé)這個(gè)槽的節(jié)點(diǎn)。
鍵空間分布基本算法
下面看下redis cluster 是通過(guò)什么樣的方式進(jìn)行 分片存儲(chǔ)的
key 與 slot 的映射算法公式如下:
HASH_SLOT=CRC16(key) mod 16384
redis cluster 通過(guò)對(duì)每個(gè)key計(jì)算CRC16值,然后對(duì)16384取模,可以獲取key對(duì)應(yīng)的hash slot,對(duì)于一批量數(shù),如果想讓批量數(shù)據(jù)都在同一個(gè)slot,可以通過(guò)hash tag來(lái)實(shí)現(xiàn)
redis cluster中每個(gè)master都會(huì)持有部分slot,比如有3個(gè)master,那么可能每個(gè)master持有5000多個(gè)hash slot
hash slot 讓 node 的增加和移除很簡(jiǎn)單,增加一個(gè)master,就將其他master的hash slot移動(dòng)部分過(guò)去,減少一個(gè)master,就將它的hash slot移動(dòng)到其他master上去
移動(dòng) hash slot 的成本是非常低的
由于 16384 是固定的,當(dāng)某個(gè)master 宕機(jī)時(shí),不會(huì)影響其他機(jī)器的數(shù)據(jù),因?yàn)閗ey 找得是hash slot ,而不是機(jī)器
好了,本章的 redis cluster 集群分析 就到這里。
以上就是本章內(nèi)容,如有不對(duì)的地方,請(qǐng)多多指教,謝謝!
為了方便有需要的人,本系列全部軟件都在 https://pan.baidu.com/s/1qYsJZfY
下章預(yù)告:主要講解 redis cluster集群部署
作者:逐暗者 (轉(zhuǎn)載請(qǐng)注明出處)
