redis 集群模式的工作原理能說(shuō)一下么?在集群模式下娇斩,redis 的 key 是如何尋址的仁卷?分布式尋址都有哪些算法穴翩?了解一致性 hash 算法嗎?

原文出處:https://github.com/doocs/advanced-java/blob/master/docs/high-concurrency/redis-cluster.md
歡迎 star 關(guān)注 GitHub 項(xiàng)目最新動(dòng)態(tài)锦积!

面試題

redis 集群模式的工作原理能說(shuō)一下么芒帕?在集群模式下,redis 的 key 是如何尋址的丰介?分布式尋址都有哪些算法背蟆?了解一致性 hash 算法嗎?

面試官心理分析

在前幾年哮幢,redis 如果要搞幾個(gè)節(jié)點(diǎn)带膀,每個(gè)節(jié)點(diǎn)存儲(chǔ)一部分的數(shù)據(jù),得借助一些中間件來(lái)實(shí)現(xiàn)橙垢,比如說(shuō)有 codis垛叨,或者 twemproxy,都有柜某。有一些 redis 中間件嗽元,你讀寫(xiě) redis 中間件,redis 中間件負(fù)責(zé)將你的數(shù)據(jù)分布式存儲(chǔ)在多臺(tái)機(jī)器上的 redis 實(shí)例中喂击。

這兩年还棱,redis 不斷在發(fā)展,redis 也不斷有新的版本惭等,現(xiàn)在的 redis 集群模式,可以做到在多臺(tái)機(jī)器上办铡,部署多個(gè) redis 實(shí)例辞做,每個(gè)實(shí)例存儲(chǔ)一部分的數(shù)據(jù),同時(shí)每個(gè) redis 主實(shí)例可以?huà)?redis 從實(shí)例寡具,自動(dòng)確保說(shuō)秤茅,如果 redis 主實(shí)例掛了,會(huì)自動(dòng)切換到 redis 從實(shí)例上來(lái)童叠。

現(xiàn)在 redis 的新版本框喳,大家都是用 redis cluster 的,也就是 redis 原生支持的 redis 集群模式厦坛,那么面試官肯定會(huì)就 redis cluster 對(duì)你來(lái)個(gè)幾連炮五垮。要是你沒(méi)用過(guò) redis cluster,正常杜秸,以前很多人用 codis 之類(lèi)的客戶(hù)端來(lái)支持集群放仗,但是起碼你得研究一下 redis cluster 吧。

如果你的數(shù)據(jù)量很少撬碟,主要是承載高并發(fā)高性能的場(chǎng)景诞挨,比如你的緩存一般就幾個(gè) G莉撇,單機(jī)就足夠了,可以使用 replication惶傻,一個(gè) master 多個(gè) slaves棍郎,要幾個(gè) slave 跟你要求的讀吞吐量有關(guān),然后自己搭建一個(gè) sentinel 集群去保證 redis 主從架構(gòu)的高可用性银室。

redis cluster涂佃,主要是針對(duì)海量數(shù)據(jù)+高并發(fā)+高可用的場(chǎng)景。redis cluster 支撐 N 個(gè) redis master node粮揉,每個(gè) master node 都可以?huà)燧d多個(gè) slave node巡李。這樣整個(gè) redis 就可以橫向擴(kuò)容了。如果你要支撐更大數(shù)據(jù)量的緩存扶认,那就橫向擴(kuò)容更多的 master 節(jié)點(diǎn)侨拦,每個(gè) master 節(jié)點(diǎn)就能存放更多的數(shù)據(jù)了。

面試題剖析

redis cluster 介紹

  • 自動(dòng)將數(shù)據(jù)進(jìn)行分片辐宾,每個(gè) master 上放一部分?jǐn)?shù)據(jù)
  • 提供內(nèi)置的高可用支持狱从,部分 master 不可用時(shí),還是可以繼續(xù)工作的

在 redis cluster 架構(gòu)下叠纹,每個(gè) redis 要放開(kāi)兩個(gè)端口號(hào)季研,比如一個(gè)是 6379,另外一個(gè)就是 加1w 的端口號(hào)誉察,比如 16379与涡。

16379 端口號(hào)是用來(lái)進(jìn)行節(jié)點(diǎn)間通信的,也就是 cluster bus 的東西持偏,cluster bus 的通信驼卖,用來(lái)進(jìn)行故障檢測(cè)、配置更新鸿秆、故障轉(zhuǎn)移授權(quán)酌畜。cluster bus 用了另外一種二進(jìn)制的協(xié)議,gossip 協(xié)議卿叽,用于節(jié)點(diǎn)間進(jìn)行高效的數(shù)據(jù)交換桥胞,占用更少的網(wǎng)絡(luò)帶寬和處理時(shí)間。

節(jié)點(diǎn)間的內(nèi)部通信機(jī)制

基本通信原理

集群元數(shù)據(jù)的維護(hù)有兩種方式:集中式考婴、Gossip 協(xié)議贩虾。redis cluster 節(jié)點(diǎn)間采用 gossip 協(xié)議進(jìn)行通信。

集中式是將集群元數(shù)據(jù)(節(jié)點(diǎn)信息沥阱、故障等等)幾種存儲(chǔ)在某個(gè)節(jié)點(diǎn)上整胃。集中式元數(shù)據(jù)集中存儲(chǔ)的一個(gè)典型代表,就是大數(shù)據(jù)領(lǐng)域的 storm。它是分布式的大數(shù)據(jù)實(shí)時(shí)計(jì)算引擎屁使,是集中式的元數(shù)據(jù)存儲(chǔ)的結(jié)構(gòu)在岂,底層基于 zookeeper(分布式協(xié)調(diào)的中間件)對(duì)所有元數(shù)據(jù)進(jìn)行存儲(chǔ)維護(hù)。

zookeeper-centralized-storage.png

redis 維護(hù)集群元數(shù)據(jù)采用另一個(gè)方式蛮寂, gossip 協(xié)議蔽午,所有節(jié)點(diǎn)都持有一份元數(shù)據(jù),不同的節(jié)點(diǎn)如果出現(xiàn)了元數(shù)據(jù)的變更酬蹋,就不斷將元數(shù)據(jù)發(fā)送給其它的節(jié)點(diǎn)及老,讓其它節(jié)點(diǎn)也進(jìn)行元數(shù)據(jù)的變更。

redis-gossip.png

集中式好處在于范抓,元數(shù)據(jù)的讀取和更新骄恶,時(shí)效性非常好,一旦元數(shù)據(jù)出現(xiàn)了變更匕垫,就立即更新到集中式的存儲(chǔ)中僧鲁,其它節(jié)點(diǎn)讀取的時(shí)候就可以感知到;不好在于象泵,所有的元數(shù)據(jù)的更新壓力全部集中在一個(gè)地方寞秃,可能會(huì)導(dǎo)致元數(shù)據(jù)的存儲(chǔ)有壓力。

gossip 好處在于偶惠,元數(shù)據(jù)的更新比較分散春寿,不是集中在一個(gè)地方,更新請(qǐng)求會(huì)陸陸續(xù)續(xù)打到所有節(jié)點(diǎn)上去更新忽孽,降低了壓力绑改;不好在于,元數(shù)據(jù)的更新有延時(shí)兄一,可能導(dǎo)致集群中的一些操作會(huì)有一些滯后绢淀。

  • 10000 端口:每個(gè)節(jié)點(diǎn)都有一個(gè)專(zhuān)門(mén)用于節(jié)點(diǎn)間通信的端口烧董,就是自己提供服務(wù)的端口號(hào)+10000,比如 7001瑟押,那么用于節(jié)點(diǎn)間通信的就是 17001 端口试溯。每個(gè)節(jié)點(diǎn)每隔一段時(shí)間都會(huì)往另外幾個(gè)節(jié)點(diǎn)發(fā)送 ping 消息,同時(shí)其它幾個(gè)節(jié)點(diǎn)接收到 ping 之后返回 pong况脆。

  • 交換的信息:信息包括故障信息,節(jié)點(diǎn)的增加和刪除,hash slot 信息等等栖雾。

gossip 協(xié)議

gossip 協(xié)議包含多種消息,包含 ping,pong,meet,fail 等等伟众。

  • meet:某個(gè)節(jié)點(diǎn)發(fā)送 meet 給新加入的節(jié)點(diǎn)析藕,讓新節(jié)點(diǎn)加入集群中,然后新節(jié)點(diǎn)就會(huì)開(kāi)始與其它節(jié)點(diǎn)進(jìn)行通信凳厢。
redis-trib.rb add-node

其實(shí)內(nèi)部就是發(fā)送了一個(gè) gossip meet 消息給新加入的節(jié)點(diǎn)账胧,通知那個(gè)節(jié)點(diǎn)去加入我們的集群竞慢。

  • ping:每個(gè)節(jié)點(diǎn)都會(huì)頻繁給其它節(jié)點(diǎn)發(fā)送 ping,其中包含自己的狀態(tài)還有自己維護(hù)的集群元數(shù)據(jù)治泥,互相通過(guò) ping 交換元數(shù)據(jù)筹煮。
  • pong:返回 ping 和 meeet,包含自己的狀態(tài)和其它信息居夹,也用于信息廣播和更新败潦。
  • fail:某個(gè)節(jié)點(diǎn)判斷另一個(gè)節(jié)點(diǎn) fail 之后,就發(fā)送 fail 給其它節(jié)點(diǎn)准脂,通知其它節(jié)點(diǎn)說(shuō)劫扒,某個(gè)節(jié)點(diǎn)宕機(jī)啦。

ping 消息深入

ping 時(shí)要攜帶一些元數(shù)據(jù)狸膏,如果很頻繁沟饥,可能會(huì)加重網(wǎng)絡(luò)負(fù)擔(dān)。

每個(gè)節(jié)點(diǎn)每秒會(huì)執(zhí)行 10 次 ping环戈,每次會(huì)選擇 5 個(gè)最久沒(méi)有通信的其它節(jié)點(diǎn)闷板。當(dāng)然如果發(fā)現(xiàn)某個(gè)節(jié)點(diǎn)通信延時(shí)達(dá)到了 cluster_node_timeout / 2,那么立即發(fā)送 ping院塞,避免數(shù)據(jù)交換延時(shí)過(guò)長(zhǎng)遮晚,落后的時(shí)間太長(zhǎng)了。比如說(shuō)拦止,兩個(gè)節(jié)點(diǎn)之間都 10 分鐘沒(méi)有交換數(shù)據(jù)了县遣,那么整個(gè)集群處于嚴(yán)重的元數(shù)據(jù)不一致的情況,就會(huì)有問(wèn)題汹族。所以 cluster_node_timeout 可以調(diào)節(jié)萧求,如果調(diào)得比較大,那么會(huì)降低 ping 的頻率顶瞒。

每次 ping夸政,會(huì)帶上自己節(jié)點(diǎn)的信息,還有就是帶上 1/10 其它節(jié)點(diǎn)的信息榴徐,發(fā)送出去守问,進(jìn)行交換。至少包含 3 個(gè)其它節(jié)點(diǎn)的信息坑资,最多包含 總節(jié)點(diǎn)數(shù)減 2 個(gè)其它節(jié)點(diǎn)的信息耗帕。

分布式尋址算法

  • hash 算法(大量緩存重建)
  • 一致性 hash 算法(自動(dòng)緩存遷移)+ 虛擬節(jié)點(diǎn)(自動(dòng)負(fù)載均衡)
  • redis cluster 的 hash slot 算法

hash 算法

來(lái)了一個(gè) key,首先計(jì)算 hash 值袱贮,然后對(duì)節(jié)點(diǎn)數(shù)取模仿便。然后打在不同的 master 節(jié)點(diǎn)上。一旦某一個(gè) master 節(jié)點(diǎn)宕機(jī),所有請(qǐng)求過(guò)來(lái)嗽仪,都會(huì)基于最新的剩余 master 節(jié)點(diǎn)數(shù)去取模荒勇,嘗試去取數(shù)據(jù)。這會(huì)導(dǎo)致大部分的請(qǐng)求過(guò)來(lái)钦幔,全部無(wú)法拿到有效的緩存枕屉,導(dǎo)致大量的流量涌入數(shù)據(jù)庫(kù)。

hash.png

一致性 hash 算法

一致性 hash 算法將整個(gè) hash 值空間組織成一個(gè)虛擬的圓環(huán)鲤氢,整個(gè)空間按順時(shí)針?lè)较蚪M織搀擂,下一步將各個(gè) master 節(jié)點(diǎn)(使用服務(wù)器的 ip 或主機(jī)名)進(jìn)行 hash。這樣就能確定每個(gè)節(jié)點(diǎn)在其哈希環(huán)上的位置卷玉。

來(lái)了一個(gè) key哨颂,首先計(jì)算 hash 值,并確定此數(shù)據(jù)在環(huán)上的位置相种,從此位置沿環(huán)順時(shí)針“行走”威恼,遇到的第一個(gè) master 節(jié)點(diǎn)就是 key 所在位置。

在一致性哈希算法中寝并,如果一個(gè)節(jié)點(diǎn)掛了箫措,受影響的數(shù)據(jù)僅僅是此節(jié)點(diǎn)到環(huán)空間前一個(gè)節(jié)點(diǎn)(沿著逆時(shí)針?lè)较蛐凶哂龅降牡谝粋€(gè)節(jié)點(diǎn))之間的數(shù)據(jù),其它不受影響衬潦。增加一個(gè)節(jié)點(diǎn)也同理斤蔓。

燃鵝,一致性哈希算法在節(jié)點(diǎn)太少時(shí)镀岛,容易因?yàn)楣?jié)點(diǎn)分布不均勻而造成緩存熱點(diǎn)的問(wèn)題弦牡。為了解決這種熱點(diǎn)問(wèn)題,一致性 hash 算法引入了虛擬節(jié)點(diǎn)機(jī)制漂羊,即對(duì)每一個(gè)節(jié)點(diǎn)計(jì)算多個(gè) hash驾锰,每個(gè)計(jì)算結(jié)果位置都放置一個(gè)虛擬節(jié)點(diǎn)。這樣就實(shí)現(xiàn)了數(shù)據(jù)的均勻分布走越,負(fù)載均衡椭豫。

consistent-hashing-algorithm.png

redis cluster 的 hash slot 算法

redis cluster 有固定的 16384 個(gè) hash slot,對(duì)每個(gè) key 計(jì)算 CRC16 值旨指,然后對(duì) 16384 取模赏酥,可以獲取 key 對(duì)應(yīng)的 hash slot。

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 的成本是非常低的≈砗迹客戶(hù)端的 api餐塘,可以對(duì)指定的數(shù)據(jù),讓他們走同一個(gè) hash slot皂吮,通過(guò) hash tag 來(lái)實(shí)現(xiàn)戒傻。

任何一臺(tái)機(jī)器宕機(jī),另外兩個(gè)節(jié)點(diǎn)蜂筹,不影響的需纳。因?yàn)?key 找的是 hash slot,不是機(jī)器艺挪。

hash-slot.png

redis cluster 的高可用與主備切換原理

redis cluster 的高可用的原理不翩,幾乎跟哨兵是類(lèi)似的。

判斷節(jié)點(diǎn)宕機(jī)

如果一個(gè)節(jié)點(diǎn)認(rèn)為另外一個(gè)節(jié)點(diǎn)宕機(jī)麻裳,那么就是 pfail口蝠,主觀宕機(jī)。如果多個(gè)節(jié)點(diǎn)都認(rèn)為另外一個(gè)節(jié)點(diǎn)宕機(jī)了津坑,那么就是 fail妙蔗,客觀宕機(jī),跟哨兵的原理幾乎一樣国瓮,sdown灭必,odown。

cluster-node-timeout 內(nèi)乃摹,某個(gè)節(jié)點(diǎn)一直沒(méi)有返回 pong禁漓,那么就被認(rèn)為 pfail

如果一個(gè)節(jié)點(diǎn)認(rèn)為某個(gè)節(jié)點(diǎn) pfail 了孵睬,那么會(huì)在 gossip ping 消息中播歼,ping 給其他節(jié)點(diǎn),如果超過(guò)半數(shù)的節(jié)點(diǎn)都認(rèn)為 pfail 了掰读,那么就會(huì)變成 fail秘狞。

從節(jié)點(diǎn)過(guò)濾

對(duì)宕機(jī)的 master node,從其所有的 slave node 中蹈集,選擇一個(gè)切換成 master node烁试。

檢查每個(gè) slave node 與 master node 斷開(kāi)連接的時(shí)間,如果超過(guò)了 cluster-node-timeout * cluster-slave-validity-factor拢肆,那么就沒(méi)有資格切換成 master减响。

從節(jié)點(diǎn)選舉

每個(gè)從節(jié)點(diǎn)靖诗,都根據(jù)自己對(duì) master 復(fù)制數(shù)據(jù)的 offset,來(lái)設(shè)置一個(gè)選舉時(shí)間支示,offset 越大(復(fù)制數(shù)據(jù)越多)的從節(jié)點(diǎn)刊橘,選舉時(shí)間越靠前,優(yōu)先進(jìn)行選舉颂鸿。

所有的 master node 開(kāi)始 slave 選舉投票促绵,給要進(jìn)行選舉的 slave 進(jìn)行投票,如果大部分 master node(N/2 + 1)都投票給了某個(gè)從節(jié)點(diǎn)嘴纺,那么選舉通過(guò)败晴,那個(gè)從節(jié)點(diǎn)可以切換成 master。

從節(jié)點(diǎn)執(zhí)行主備切換颖医,從節(jié)點(diǎn)切換為主節(jié)點(diǎn)位衩。

與哨兵比較

整個(gè)流程跟哨兵相比,非常類(lèi)似熔萧,所以說(shuō)糖驴,redis cluster 功能強(qiáng)大,直接集成了 replication 和 sentinel 的功能佛致。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末贮缕,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子俺榆,更是在濱河造成了極大的恐慌感昼,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,682評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件罐脊,死亡現(xiàn)場(chǎng)離奇詭異定嗓,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)萍桌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)宵溅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人上炎,你說(shuō)我怎么就攤上這事恃逻。” “怎么了藕施?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,083評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵寇损,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我裳食,道長(zhǎng)矛市,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,763評(píng)論 1 295
  • 正文 為了忘掉前任诲祸,我火速辦了婚禮浊吏,結(jié)果婚禮上憨愉,老公的妹妹穿的比我還像新娘。我一直安慰自己卿捎,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,785評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布径密。 她就那樣靜靜地躺著午阵,像睡著了一般。 火紅的嫁衣襯著肌膚如雪享扔。 梳的紋絲不亂的頭發(fā)上底桂,一...
    開(kāi)封第一講書(shū)人閱讀 51,624評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音惧眠,去河邊找鬼籽懦。 笑死,一個(gè)胖子當(dāng)著我的面吹牛氛魁,可吹牛的內(nèi)容都是我干的暮顺。 我是一名探鬼主播,決...
    沈念sama閱讀 40,358評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼秀存,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼捶码!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起或链,我...
    開(kāi)封第一講書(shū)人閱讀 39,261評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤惫恼,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后澳盐,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體祈纯,經(jīng)...
    沈念sama閱讀 45,722評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年叼耙,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了腕窥。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,030評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡旬蟋,死狀恐怖油昂,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情倾贰,我是刑警寧澤冕碟,帶...
    沈念sama閱讀 35,737評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站匆浙,受9級(jí)特大地震影響安寺,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜首尼,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,360評(píng)論 3 330
  • 文/蒙蒙 一挑庶、第九天 我趴在偏房一處隱蔽的房頂上張望言秸。 院中可真熱鬧,春花似錦迎捺、人聲如沸举畸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,941評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)抄沮。三九已至,卻和暖如春岖瑰,著一層夾襖步出監(jiān)牢的瞬間叛买,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,057評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工蹋订, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留率挣,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,237評(píng)論 3 371
  • 正文 我出身青樓露戒,卻偏偏與公主長(zhǎng)得像椒功,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子智什,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,976評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容