Redis集群方案原理詳解

之前寫過一篇介紹redis集群的文章瓣戚,那篇可以方便大家入門鸳兽,這篇是對這幾個方案的原理介紹蜓斧,方便對大家對這幾個集群方案有個更加深入的了解献联,下面會分別對codis、sentinel哨鸭、cluster三個集群方案分別進行詳細的核心原理介紹,這里只是對核心原理進行介紹娇妓,讓大家能夠從本質(zhì)上了解它們的區(qū)別方便大家進行選擇像鸡,如果要更加深入的了解還是要看源碼,好了開始哈恰。

Codis

在數(shù)據(jù)量比較大的情況下只估,使用單實例會因為內(nèi)存大小導(dǎo)致空間不足,同時也會因為內(nèi)存過大導(dǎo)致rdb文件過大從而使得master和slave之間數(shù)據(jù)全量同步時間過長着绷,在有新節(jié)點加入時候會非常慢蛔钙,在節(jié)點重啟的時候也會非常慢。

數(shù)據(jù)集中式的方案當然不是我們希望看到的荠医,所以這幾年 各大廠都推出了自己的redis分片方案吁脱,隨著這幾年codis的快速發(fā)展,互聯(lián)網(wǎng)公司使用的redis分布式分片中間件基本都是codis了彬向,對于一些沒有做緩存集中管理或者數(shù)據(jù)量本來就不大的公司兼贡,使用sentinel方案就可以滿足主從互備的要求了,畢竟多了一個中間件多了一份不穩(wěn)定因素娃胆。

下面我們就來詳細看下Codis的實現(xiàn)原理遍希。

Codis使用Go語言開發(fā),是一個在客戶端和redis之間的代理中間件里烦,使用和redis一樣的協(xié)議對外提供key/value服務(wù)凿蒜,所以在客戶端使用的時候完全感覺不到codis中間件的存在。Codis不但可以代理連接很多redis實例進行數(shù)據(jù)分片和互備胁黑,同時Codis因為是無狀態(tài)的废封,也可以啟動多個Codis實例,這樣可以起到Codis實例HA互備的作用丧蘸。


Screenshot 2018-10-10 15.44.00

Codis分片原理

codis最核心的部分就是數(shù)據(jù)分片虱饿,下面我們來看下codis如何實現(xiàn)數(shù)據(jù)分片。

codis作為客戶端和redis之間的代理触趴,主要負責將特定的key轉(zhuǎn)發(fā)到特定的redis實例,并將value返回給客戶端渴肉。

codis將所有的key劃分為1024個slot冗懦,首先對客戶端傳來的key進行crc32計算hash,再將hash值對1024取模仇祭,取模后的余數(shù)就是這個key的slot位置披蕉。每個slot都會唯一影射到一個redis實例,codis會在內(nèi)存中維護slot和redis實例之間的對應(yīng)關(guān)系。

解決了key值存放問題那么還有個問題要解決没讲,就是不同codis實例之間如何同步這個slot和redis實例之間的映射關(guān)系數(shù)據(jù)眯娱,因為要保證客戶端隨便訪問到一個codis實例都能夠查詢到key值對應(yīng)的redis實例,那就要保障每個codis實例在內(nèi)存中都保留一份映射關(guān)系爬凑。為了解決這個問題徙缴,codis使用了zookeeper和etcd來解決這個問題,codis將slot關(guān)系存儲在zookeeper中嘁信,并且提供了codis dashboard來觀察和修改slot關(guān)系于样,當slot關(guān)系發(fā)生變化后,codis proxy會監(jiān)聽到變化并重新同步slot映射關(guān)系到所有codis實例潘靖,從而實現(xiàn)多個codis節(jié)點之間的數(shù)據(jù)同步穿剖。

Codis擴容

大家喜歡使用codis的一個很大的原因就是codis可以根據(jù)業(yè)務(wù)量對于redis做到動態(tài)實例擴容。因為codis是redis分片代理方案有點類似數(shù)據(jù)庫分庫分表方案卦溢,當涉及到擴容那就涉及到slot和redis實例映射關(guān)系調(diào)整和數(shù)據(jù)的遷移糊余,舊節(jié)點需要將數(shù)據(jù)遷移到新節(jié)點。

在有新增redis實例后单寂,codis會掃描出舊節(jié)點中所有待遷移slot中的所有key贬芥,然后逐個將key遷移到新的redis節(jié)點中。在遷移過程中新舊節(jié)點中都有同一個slot凄贩,但是其中的key可能還沒遷移完成誓军,這時候可能有請求待遷移slot中的key,codis使用的方案不是去看這個key有沒有完成遷移疲扎,而是立即強制對當前單個key進行遷移昵时,遷移完成后,將請求轉(zhuǎn)發(fā)到新的redis實例椒丧。

codis的難點不是在使用壹甥,而是在理解其中的分片和擴容的原理,這樣可以方便我們在后續(xù)使用中做到心中有數(shù)壶熏,這里再說明下因為codis不是redis官方的方案句柠,那么必定會存在和官方新版本不兼容的問題,這里需要注意棒假,并且一些新版本的新特性可能不能及時支持溯职。

sentinel

sentinel是官方的一種主從方案,帽哑,他的原理對比上面介紹的codis要簡單很多谜酒,sentinel實現(xiàn)的原理有點類似于zookeeper,主要負責監(jiān)控主從節(jié)點的健康狀況妻枕,當master節(jié)點掛掉后僻族,自動選擇一個最優(yōu)的slave節(jié)點頂替master節(jié)點粘驰,因為master和slave之間的數(shù)據(jù)是完全同步的,并且都是保存了全部數(shù)據(jù)述么,所以不存在數(shù)據(jù)的遷移和分片問題蝌数。客戶端需要配置sentinel集群信息度秘,在每次set和get數(shù)據(jù)的時候顶伞,sentinel都會告訴客戶端去哪個redis節(jié)點進行操作。


Screenshot 2018-10-10 16.12.42

唯一要處理的一個問題就是敷钾,當master節(jié)點切換后枝哄,sentinel會通知所有slave節(jié)點新的master節(jié)點地址,并且主從節(jié)點的數(shù)據(jù)復(fù)制關(guān)系也進行了變更阻荒,這些信息都會保存在sentinel中挠锥,并下發(fā)到所有節(jié)點。

總的來說sentinel的原理非常簡單侨赡,sentinel的集群方案主要解決的是HA的問題蓖租,并不能解決超大緩存數(shù)據(jù)的分片和分散訪問熱點的問題。

Cluster

cluster是redis官方的集群方案羊壹,也是未來大家比較看好的一種集群方案蓖宦,redis cluster內(nèi)部實現(xiàn)了分布式的數(shù)據(jù)一致性,不用通過zookeeper這樣的中間件來保證數(shù)據(jù)一致性油猫。同codis一樣稠茂,cluster方案也是一種數(shù)據(jù)分片方案,每個節(jié)點負責整個集群的一部分數(shù)據(jù)情妖,每個節(jié)點之間通過自定義的二進制協(xié)議來傳遞集群信息睬关。

Screenshot 2018-10-10 16.32.35

redis cluster將所有數(shù)據(jù)分為16384個slot,他比codis的1024個slot劃分更為精細毡证,每個節(jié)點負責一部分slot电爹。slot的映射信息保存在每個節(jié)點中,他和codis不一樣料睛,codis為了保證所有節(jié)點數(shù)據(jù)一致性需要將這些slot映射數(shù)據(jù)保存在zk或者etcd中丐箩,cluster方案因為內(nèi)部已經(jīng)實現(xiàn)分布式存儲,所以不需要再有額外的分布式存儲中間件恤煞。

當cluster的客戶端來連接集群的時候屎勘,會得到一份集群的slot映射信息,這樣客戶端可以直接根據(jù)映射信息定位到key所在的redis節(jié)點居扒。這樣就會比用codis需要先到codis獲取key所在節(jié)點挑秉,再去相應(yīng)節(jié)點獲取數(shù)據(jù)要快。但是這樣也會存在客戶端和服務(wù)器slot映射信息不一致的問題苔货,這就需要cluster有補償機制來保證犀概。

cluster分片原理

cluster的分片原理其實和codis類似,對key使用crc16進行散列得到hash夜惭,然后對hash值對16384進行取模得到具體的slot姻灶。

cluster補償原理

當客戶端根據(jù)本地保存的slot映射信息訪問了錯誤的redis節(jié)點時,就需要cluster有補償機制來保證客戶端可以訪問到正確的節(jié)點诈茧。

當redis節(jié)點收到客戶端這個錯誤的指令后产喉,該節(jié)點會發(fā)現(xiàn)這個key的slot不歸自己管,它會向客戶端發(fā)送一個跳轉(zhuǎn)指令并攜帶正確的目標地址敢会,讓客戶端去正確的地址獲取數(shù)據(jù)曾沈。同時客戶端收到這個指令后會修改本地的slot映射表數(shù)據(jù)。

cluster數(shù)據(jù)遷移原理

和codis一樣鸥昏,當出現(xiàn)redis節(jié)點掛掉或者新增節(jié)點塞俱,那么就需要對redis節(jié)點進行數(shù)據(jù)遷移,cluster提供了人工調(diào)整slot的工具redis-trib,同時也有和codis一樣的自動化遷移的功能吏垮,不需要人工干預(yù)障涯。

redis cluster遷移的單位是slot,一個slot一個slot的遷移膳汪,當一個slot正在遷移的時候唯蝶,這個slot在原節(jié)點的狀態(tài)為migrating,目標節(jié)點的狀態(tài)為importing遗嗽。遷移的過程中粘我,目標節(jié)點會先獲取到原節(jié)點待遷移slot中所有的key,再逐個key遷移痹换,當key保存到目標節(jié)點后征字,就會在源節(jié)點中刪除數(shù)據(jù)。

當在遷移過程中晴音,客戶端訪問cluster的方式也會發(fā)生很大變化并且和codis的方法也會有很大不同柔纵。首先新舊節(jié)點都有這個slot,但是因為遷移成功一個key后原節(jié)點就會刪除锤躁,所以都只存在部分數(shù)據(jù)搁料,這點和codis不同。這時客戶端會先根據(jù)本地記錄的slot映射表訪問舊節(jié)點系羞,如果數(shù)據(jù)還在舊節(jié)點郭计,那么舊節(jié)點返回數(shù)據(jù)。如果數(shù)據(jù)不在舊節(jié)點那么又分為兩種情況椒振,一種是數(shù)據(jù)在新節(jié)點昭伸,另一種是數(shù)據(jù)不在這個slot中。舊節(jié)點不知道是哪種情況澎迎,會返回遷移目標節(jié)點的地址庐杨,客戶端根據(jù)這個新地址重新訪問數(shù)據(jù)选调,如果存在數(shù)據(jù)則返回給客戶端,如果不存在則返回無數(shù)據(jù)灵份。

cluster節(jié)點變更通知原理

當集群中有節(jié)點掛了仁堪,那么應(yīng)該第一時間通知到客戶端要更新本地的slot映射表,cluster是如何處理節(jié)點變更后通知到所有客戶端呢填渠?

cluster采用的是被動的方案弦聂,當目標節(jié)點掛了,客戶端訪問了掛掉的節(jié)點會拋出一個ConnectionError氛什,這時客戶端會在集群中隨機找一個節(jié)點來重試莺葫,這時被重試的節(jié)點會告知客戶端slot已經(jīng)被分配到新的節(jié)點,同時客戶端會關(guān)閉所有連接枪眉,清空本地保存的slot映射信息捺檬,然后重新初始化節(jié)點信息。

HA

cluster和codis一樣不但有數(shù)據(jù)分片功能瑰谜,同時也有HA主從復(fù)制功能欺冀,對于每個分片節(jié)點都可以配置對應(yīng)的從節(jié)點,這樣就可以做到節(jié)點主備萨脑。

總結(jié)

這篇文章主要介紹了主流的redis 3種集群方案的核心原理隐轩,如果大家仔細看了文章中講到的原理后,因為會很清楚自己因該選擇哪種集群方案了渤早,這里簡單總結(jié)下來就是职车,如果數(shù)據(jù)量不大,使用集群只是為了解決HA問題那使用簡單不易出問題的sentinel方案就可以了鹊杖;如果你的緩存數(shù)據(jù)量很大需要能做到靈活動態(tài)擴容那么可以使用codis或者官方的cluster方案悴灵,對于codis和cluster的選擇可以根據(jù)公司的具體情況來選擇,如果公司已經(jīng)有成熟的公用zk和相關(guān)運維人員骂蓖,那么建議使用codis畢竟那么多大廠用了那么多年积瞒,網(wǎng)上也有很多資料可查詢,如果公司還沒有現(xiàn)成的zk集群登下,那么可以考慮使用官方社區(qū)推崇的cluster方案茫孔,畢竟官方社區(qū)會一直維護下去,并且能享受到new feature被芳。

60041535374278_.pic_hd.jpg
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末缰贝,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子畔濒,更是在濱河造成了極大的恐慌剩晴,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,820評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件侵状,死亡現(xiàn)場離奇詭異赞弥,居然都是意外死亡毅整,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評論 3 399
  • 文/潘曉璐 我一進店門绽左,熙熙樓的掌柜王于貴愁眉苦臉地迎上來毛嫉,“玉大人,你說我怎么就攤上這事妇菱。” “怎么了暴区?”我有些...
    開封第一講書人閱讀 168,324評論 0 360
  • 文/不壞的土叔 我叫張陵闯团,是天一觀的道長。 經(jīng)常有香客問我仙粱,道長房交,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,714評論 1 297
  • 正文 為了忘掉前任伐割,我火速辦了婚禮候味,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘隔心。我一直安慰自己白群,他們只是感情好,可當我...
    茶點故事閱讀 68,724評論 6 397
  • 文/花漫 我一把揭開白布硬霍。 她就那樣靜靜地躺著帜慢,像睡著了一般。 火紅的嫁衣襯著肌膚如雪唯卖。 梳的紋絲不亂的頭發(fā)上粱玲,一...
    開封第一講書人閱讀 52,328評論 1 310
  • 那天,我揣著相機與錄音拜轨,去河邊找鬼抽减。 笑死,一個胖子當著我的面吹牛橄碾,可吹牛的內(nèi)容都是我干的卵沉。 我是一名探鬼主播,決...
    沈念sama閱讀 40,897評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼堪嫂,長吁一口氣:“原來是場噩夢啊……” “哼偎箫!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起皆串,我...
    開封第一講書人閱讀 39,804評論 0 276
  • 序言:老撾萬榮一對情侶失蹤淹办,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后恶复,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體怜森,經(jīng)...
    沈念sama閱讀 46,345評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡速挑,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,431評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了副硅。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片姥宝。...
    茶點故事閱讀 40,561評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖恐疲,靈堂內(nèi)的尸體忽然破棺而出腊满,到底是詐尸還是另有隱情,我是刑警寧澤培己,帶...
    沈念sama閱讀 36,238評論 5 350
  • 正文 年R本政府宣布碳蛋,位于F島的核電站,受9級特大地震影響省咨,放射性物質(zhì)發(fā)生泄漏肃弟。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,928評論 3 334
  • 文/蒙蒙 一零蓉、第九天 我趴在偏房一處隱蔽的房頂上張望笤受。 院中可真熱鬧,春花似錦敌蜂、人聲如沸箩兽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,417評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽比肄。三九已至,卻和暖如春囊陡,著一層夾襖步出監(jiān)牢的瞬間芳绩,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,528評論 1 272
  • 我被黑心中介騙來泰國打工撞反, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留妥色,地道東北人。 一個月前我還...
    沈念sama閱讀 48,983評論 3 376
  • 正文 我出身青樓遏片,卻偏偏與公主長得像嘹害,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子吮便,可洞房花燭夜當晚...
    茶點故事閱讀 45,573評論 2 359

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