干货!Redis集群工作原理解析
作者 |?張小盼
頭圖?|?下載于東方IC
出品 | CSDN云計(jì)算(ID:CSDNcloud)
Redis 緩存因其訪問(wèn)性能高、可靠性更高,作為緩存工具在各大互聯(lián)網(wǎng)公司中廣泛使用。今天我們就來(lái)看看Redis Cluster 的實(shí)現(xiàn)原理。
?
集群建立
Redis集群是由多個(gè)Redis節(jié)點(diǎn)組成,每個(gè)Redis節(jié)點(diǎn)都是相互獨(dú)立的,為了組建一個(gè)redis集群,我們需要使用CLUSTER MEET命令把他們連接起來(lái)。
節(jié)點(diǎn)A通過(guò)接收客戶端發(fā)來(lái)的LUSTER MEET命令將另一個(gè)節(jié)點(diǎn)B加入到集群中,接收到命令的節(jié)點(diǎn)A將與節(jié)點(diǎn)B進(jìn)行握手來(lái)來(lái)確認(rèn)彼此的存在。下圖顯示了它們握手的過(guò)程。
握手完成后,節(jié)點(diǎn)A會(huì)將節(jié)點(diǎn)B的信息通過(guò)Gossip協(xié)議傳播給集群中的其他節(jié)點(diǎn),讓其他節(jié)點(diǎn)與節(jié)點(diǎn)B完成握手,之后節(jié)點(diǎn)B就會(huì)被集群中的所有節(jié)點(diǎn)認(rèn)識(shí)了。
?
槽指派
集群建立之后,那么接下來(lái)要解決的就是數(shù)據(jù)分布問(wèn)題了。Redis緩存信息是使用 Key-Value 的形式來(lái)存儲(chǔ)數(shù)據(jù),Redis集群又將整個(gè)數(shù)據(jù)分布16384個(gè)槽中。在存儲(chǔ)信息的時(shí)候,集群會(huì)對(duì)每個(gè)要存儲(chǔ)的Key計(jì)算CRC16 校驗(yàn)值并對(duì) 16384 取模(slot = CRC16(key)%16384)。由于集群中的槽會(huì)被指派到不同的節(jié)點(diǎn),從而實(shí)現(xiàn)了數(shù)據(jù)的分布式存儲(chǔ)。
每個(gè)節(jié)點(diǎn)都保存著一個(gè)clusterNode結(jié)構(gòu),該結(jié)構(gòu)里有一個(gè)slots屬性記錄了節(jié)點(diǎn)負(fù)責(zé)處理哪些槽。
1struct?clusterNode{ 2?????//......? 3?????unsigned?char?slots[16384/8];? 4?????//......? 5}這個(gè)slots屬性是個(gè)二進(jìn)制位的數(shù)組,數(shù)組長(zhǎng)度為16384/8=2048個(gè)字節(jié),共包含16384個(gè)二進(jìn)制位。每個(gè)二進(jìn)制位代表一個(gè)槽,節(jié)點(diǎn)會(huì)根據(jù)二進(jìn)制位上的值進(jìn)行判斷該節(jié)點(diǎn)是否負(fù)責(zé)處理這個(gè)槽,1代表處理,0代表不處理。
表格中代表的是該節(jié)點(diǎn)負(fù)責(zé)集群中的槽1、3、5、7,這種處理方式可以很快的得出節(jié)點(diǎn)是否負(fù)責(zé)處理某個(gè)槽的數(shù)據(jù)。
?
指令執(zhí)行
在集群中的16384個(gè)槽都進(jìn)行了指派之后,集群就進(jìn)入了上線狀態(tài),這時(shí)客戶端就可以向集群發(fā)送數(shù)據(jù)命令了。
當(dāng)客戶端向節(jié)點(diǎn)發(fā)送GET/SET指令時(shí),收到指令的節(jié)點(diǎn)會(huì)先對(duì)指令操作的key進(jìn)行計(jì)算,得出該key值應(yīng)該存儲(chǔ)在哪個(gè)槽中,并檢查這個(gè)槽是否指派給了自己。
?
故障轉(zhuǎn)移與恢復(fù)
Redis集群中的節(jié)點(diǎn)分為主節(jié)點(diǎn)(master)和從節(jié)點(diǎn)(slave),主節(jié)點(diǎn)主要負(fù)責(zé)處理槽,從節(jié)點(diǎn)則用于復(fù)制某個(gè)主節(jié)點(diǎn)數(shù)據(jù),并在被復(fù)制的主節(jié)點(diǎn)下線時(shí),代替主節(jié)點(diǎn)處理后續(xù)的命令請(qǐng)求。
針對(duì)節(jié)點(diǎn)下線有兩種狀態(tài):
1.主觀下線:當(dāng)節(jié)點(diǎn)A想節(jié)點(diǎn)B發(fā)送了一條PING消息時(shí),節(jié)點(diǎn)B沒(méi)有在規(guī)定的時(shí)間內(nèi)(設(shè)置的cluster-node-timeout參數(shù))返回PONG消息,那么節(jié)點(diǎn)A會(huì)將節(jié)點(diǎn)B標(biāo)記為主觀下線狀態(tài)。
這里的主觀下線只是節(jié)點(diǎn)A主觀的認(rèn)為節(jié)點(diǎn)B下線了,有可能是因?yàn)楣?jié)點(diǎn)A和節(jié)點(diǎn)B之間的網(wǎng)絡(luò)斷了,但是其他節(jié)點(diǎn)依然可以和節(jié)點(diǎn)B通訊,所以主觀下線并不一定是節(jié)點(diǎn)B真的就下線了。
2.客觀下線:由于節(jié)點(diǎn)A與集群內(nèi)的其他節(jié)點(diǎn)仍然保持通訊,因此節(jié)點(diǎn)B的下線消息也通過(guò)Gossip協(xié)議傳遍了集群內(nèi)的其他節(jié)點(diǎn)。
當(dāng)集群內(nèi)半數(shù)以上的節(jié)點(diǎn)都認(rèn)為節(jié)點(diǎn)B主觀下線了,那么節(jié)點(diǎn)B就會(huì)被認(rèn)為客觀下線了,同時(shí)將節(jié)點(diǎn)B標(biāo)記為客觀下線的節(jié)點(diǎn)會(huì)向集群中發(fā)送一條FAIL消息,所有收到這條消息的節(jié)點(diǎn)會(huì)立即將節(jié)點(diǎn)B標(biāo)記為客觀下線。
如果一個(gè)節(jié)點(diǎn)被認(rèn)為客觀下線了,那么就需要從它的從節(jié)點(diǎn)當(dāng)中選出一個(gè)節(jié)點(diǎn)來(lái)代替它成為主節(jié)點(diǎn)。選舉過(guò)程如下:
a.當(dāng)從節(jié)點(diǎn)發(fā)現(xiàn)自己正在復(fù)制的主節(jié)點(diǎn)被標(biāo)記為客觀下線時(shí),從節(jié)點(diǎn)會(huì)向集群中發(fā)送一條CLUSTERMSG_TYPE_FAILOVER_AUTH_REQUEST消息,要求所有收到這條消息的具有投票權(quán)的主節(jié)點(diǎn)向這個(gè)從節(jié)點(diǎn)投票
b.如果一個(gè)主節(jié)點(diǎn)具有投票權(quán),并且未投票給其他從節(jié)點(diǎn),那么這個(gè)主節(jié)點(diǎn)會(huì)向要求投票的從節(jié)點(diǎn)返回一條CLUSTERMSG_TYPE_FAILOVER_AUTH_ACK消息,表示這個(gè)主節(jié)點(diǎn)支持該從節(jié)點(diǎn)成為新的主節(jié)點(diǎn)
c.每個(gè)從節(jié)點(diǎn)都會(huì)接收返回的CLUSTERMSG_TYPE_FAILOVER_AUTH_ACK消息,并會(huì)進(jìn)行統(tǒng)計(jì)自己得到了多少主節(jié)點(diǎn)的支持
d.每個(gè)具有投票權(quán)的主節(jié)點(diǎn)只能投一次票,當(dāng)一個(gè)從節(jié)點(diǎn)獲得了一半以上的主節(jié)點(diǎn)的支持票時(shí),那么這個(gè)節(jié)點(diǎn)就會(huì)成為新的主節(jié)點(diǎn),
e.如果沒(méi)有任何一個(gè)從節(jié)點(diǎn)獲取大于半數(shù)的投票,那么將進(jìn)行新的選舉,直到選出新的主節(jié)點(diǎn)為止。
f.新的主節(jié)點(diǎn)產(chǎn)生后,它會(huì)撤銷所有對(duì)已下線的主節(jié)點(diǎn)的槽指派,并將這些槽指派給自己。
g.新的主節(jié)點(diǎn)會(huì)向集群中廣播一條PONG消息,讓集群中的其他節(jié)點(diǎn)直到這個(gè)從節(jié)點(diǎn)已經(jīng)成為了新的主節(jié)點(diǎn),并且接管了原先主節(jié)點(diǎn)的所有槽。
h.新的主節(jié)點(diǎn)負(fù)責(zé)接收和自己處理的槽相關(guān)的指令,至此故障轉(zhuǎn)移結(jié)束。
?
結(jié)束語(yǔ)
本文通過(guò)對(duì)集群建立、槽指派、指令執(zhí)行、故障轉(zhuǎn)移與恢復(fù)的實(shí)現(xiàn)原理進(jìn)行分析,一步一步的帶大家認(rèn)識(shí)Redis集群。希望對(duì)大家認(rèn)識(shí)和了解Redis集群有所幫助。
作者簡(jiǎn)介:張小盼 中國(guó)農(nóng)業(yè)銀行研發(fā)中心,全棧運(yùn)維研發(fā)工程師。
直播間地址:
https://live.csdn.net/room/csdnnews/B3423dYF
更多精彩推薦 ?三個(gè)月前被 K8S 棄用,Docker 火了!獲 2300 萬(wàn)美元融資?一招上手!這樣設(shè)計(jì)扛住億級(jí)流量活動(dòng)系統(tǒng)?Kubernetes 穩(wěn)定性保障手冊(cè)(極簡(jiǎn)版)點(diǎn)分享點(diǎn)收藏點(diǎn)點(diǎn)贊點(diǎn)在看 創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的干货!Redis集群工作原理解析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 顶级技术大咖,揭秘实时音视频开发的超级风
- 下一篇: 【我想进大厂】Redis夺命连环11问