redis 集群模式的工作原理能說一下么乡小?在集群模式下,redis 的 key 是如何尋址的饵史?分布式尋址都有哪些算法满钟?了解一致性 hash 算法嗎?

面試題

redis 集群模式的工作原理能說一下么胳喷?在集群模式下湃番,redis 的 key 是如何尋址的?分布式尋址都有哪些算法吭露?了解一致性 hash 算法嗎吠撮?

面試官心理分析

在前幾年,redis 如果要搞幾個(gè)節(jié)點(diǎn)讲竿,每個(gè)節(jié)點(diǎn)存儲(chǔ)一部分的數(shù)據(jù)泥兰,得借助一些中間件來實(shí)現(xiàn)弄屡,比如說有 codis,或者 twemproxy鞋诗,都有膀捷。有一些 redis 中間件,你讀寫 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í)例可以掛 redis 從實(shí)例安券,自動(dòng)確保說,如果 redis 主實(shí)例掛了氓英,會(huì)自動(dòng)切換到 redis 從實(shí)例頂上來侯勉。

現(xiàn)在 redis 的新版本,大家都是用 redis cluster 的铝阐,也就是 redis 原生支持的 redis 集群模式址貌,那么面試官肯定會(huì)就 redis cluster 對(duì)你來個(gè)幾連炮。要是你沒用過 redis cluster徘键,正常练对,以前很多人用 codis 之類的客戶端來支持集群,但是起碼你得研究一下 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 都可以掛載多個(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 要放開兩個(gè)端口號(hào),比如一個(gè)是 6379逝嚎,另外一個(gè)就是 加1w 的端口號(hào)扁瓢,比如 16379。

16379 端口號(hào)是用來進(jìn)行節(jié)點(diǎn)間通信的补君,也就是 cluster bus 的東西引几,cluster bus 的通信,用來進(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ī)制

基本通信原理

  • 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

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

集中式好處在于,元數(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è)專門用于節(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ì)開始與其它節(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ù)洛退,互相通過 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)說,某個(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è)最久沒有通信的其它節(jié)點(diǎn)奠货。當(dāng)然如果發(fā)現(xiàn)某個(gè)節(jié)點(diǎn)通信延時(shí)達(dá)到了 cluster_node_timeout / 2,那么立即發(fā)送 ping粘优,避免數(shù)據(jù)交換延時(shí)過長(zhǎng)仇味,落后的時(shí)間太長(zhǎng)了。比如說雹顺,兩個(gè)節(jié)點(diǎn)之間都 10 分鐘沒有交換數(shù)據(jù)了丹墨,那么整個(gè)集群處于嚴(yán)重的元數(shù)據(jù)不一致的情況,就會(huì)有問題嬉愧。所以 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)-2 個(gè)其它節(jié)點(diǎn)的信息挂疆。

分布式尋址算法

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

hash 算法

來了一個(gè) key,首先計(jì)算 hash 值下翎,然后對(duì)節(jié)點(diǎn)數(shù)取模缤言。然后打在不同的 master 節(jié)點(diǎn)上。一旦某一個(gè) master 節(jié)點(diǎn)宕機(jī)视事,所有請(qǐng)求過來胆萧,都會(huì)基于最新的剩余 master 節(jié)點(diǎn)數(shù)去取模,嘗試去取數(shù)據(jù)俐东。這會(huì)導(dǎo)致大部分的請(qǐng)求過來跌穗,全部無法拿到有效的緩存,導(dǎo)致大量的流量涌入數(shù)據(jù)庫虏辫。

hash

一致性 hash 算法

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

來了一個(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í)針方向行走遇到的第一個(gè)節(jié)點(diǎn))之間的數(shù)據(jù),其它不受影響族购。增加一個(gè)節(jié)點(diǎn)也同理壳贪。

燃鵝,一致性哈希算法在節(jié)點(diǎn)太少時(shí)寝杖,容易因?yàn)楣?jié)點(diǎn)分布不均勻而造成緩存熱點(diǎn)的問題违施。為了解決這種熱點(diǎ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

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)部分過去扯键,減少一個(gè) master睦袖,就將它的 hash slot 移動(dòng)到其他 master 上去。移動(dòng) hash slot 的成本是非常低的荣刑∠隗希客戶端的 api,可以對(duì)指定的數(shù)據(jù)厉亏,讓他們走同一個(gè) hash slot董习,通過 hash tag 來實(shí)現(xiàn)。

任何一臺(tái)機(jī)器宕機(jī)爱只,另外兩個(gè)節(jié)點(diǎn)皿淋,不影響的。因?yàn)?key 找的是 hash slot,不是機(jī)器窝趣。


hash-slot

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

redis cluster 的高可用的原理疯暑,幾乎跟哨兵是類似的

判斷節(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)一直沒有返回 pong吏祸,那么就被認(rèn)為 pfail对蒲。

如果一個(gè)節(jié)點(diǎn)認(rèn)為某個(gè)節(jié)點(diǎn) pfail 了,那么會(huì)在 gossip ping 消息中贡翘,ping 給其他節(jié)點(diǎn)蹈矮,如果超過半數(shù)的節(jié)點(diǎn)都認(rèn)為 pfail 了,那么就會(huì)變成 fail鸣驱。

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

對(duì)宕機(jī)的 master node泛鸟,從其所有的 slave node 中,選擇一個(gè)切換成 master node踊东。

檢查每個(gè) slave node 與 master node 斷開連接的時(shí)間北滥,如果超過了 cluster-node-timeout * cluster-slave-validity-factor,那么就沒有資格切換成 master闸翅。

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

每個(gè)從節(jié)點(diǎn)再芋,都根據(jù)自己對(duì) master 復(fù)制數(shù)據(jù)的 offset,來設(shè)置一個(gè)選舉時(shí)間坚冀,offset 越大(復(fù)制數(shù)據(jù)越多)的從節(jié)點(diǎn)济赎,選舉時(shí)間越靠前,優(yōu)先進(jìn)行選舉记某。

所有的 master node 開始 slave 選舉投票司训,給要進(jìn)行選舉的 slave 進(jìn)行投票,如果大部分 master node(N/2 + 1)都投票給了某個(gè)從節(jié)點(diǎn)液南,那么選舉通過壳猜,那個(gè)從節(jié)點(diǎn)可以切換成 master。

從節(jié)點(diǎn)執(zhí)行主備切換滑凉,從節(jié)點(diǎn)切換為主節(jié)點(diǎn)统扳。

與哨兵比較

整個(gè)流程跟哨兵相比喘帚,非常類似,所以說咒钟,redis cluster 功能強(qiáng)大啥辨,直接集成了 replication 和 sentinel 的功能。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末盯腌,一起剝皮案震驚了整個(gè)濱河市溉知,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌腕够,老刑警劉巖级乍,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異帚湘,居然都是意外死亡玫荣,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門大诸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來捅厂,“玉大人,你說我怎么就攤上這事资柔”捍” “怎么了?”我有些...
    開封第一講書人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵贿堰,是天一觀的道長(zhǎng)辙芍。 經(jīng)常有香客問我,道長(zhǎng)羹与,這世上最難降的妖魔是什么故硅? 我笑而不...
    開封第一講書人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮纵搁,結(jié)果婚禮上吃衅,老公的妹妹穿的比我還像新娘。我一直安慰自己腾誉,他們只是感情好徘层,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著妄辩,像睡著了一般惑灵。 火紅的嫁衣襯著肌膚如雪山上。 梳的紋絲不亂的頭發(fā)上眼耀,一...
    開封第一講書人閱讀 49,166評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音佩憾,去河邊找鬼哮伟。 笑死干花,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的楞黄。 我是一名探鬼主播池凄,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼鬼廓!你這毒婦竟也來了肿仑?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤碎税,失蹤者是張志新(化名)和其女友劉穎尤慰,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體雷蹂,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡伟端,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了匪煌。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片责蝠。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖萎庭,靈堂內(nèi)的尸體忽然破棺而出霜医,到底是詐尸還是另有隱情,我是刑警寧澤驳规,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布支子,位于F島的核電站,受9級(jí)特大地震影響达舒,放射性物質(zhì)發(fā)生泄漏值朋。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一巩搏、第九天 我趴在偏房一處隱蔽的房頂上張望昨登。 院中可真熱鬧,春花似錦贯底、人聲如沸丰辣。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽笙什。三九已至,卻和暖如春胚想,著一層夾襖步出監(jiān)牢的瞬間琐凭,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來泰國打工浊服, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留统屈,地道東北人胚吁。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像愁憔,于是被迫代替她去往敵國和親腕扶。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

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