Redis cluster是Redis的分布式解決方案,在3.0版本正式推出耗绿,有效地解決了Redis分布式方面的需求。當(dāng)遇到單機(jī)內(nèi)存砾隅、并發(fā)误阻、流量等瓶頸時(shí),可以采用Cluster架構(gòu)方案達(dá)到負(fù)載均衡的目的晴埂。之前究反,Redis分布式方案一般有兩種:
客戶端分區(qū)方案,優(yōu)點(diǎn)是分區(qū)邏輯可控儒洛,缺點(diǎn)是需要自己處理數(shù)據(jù)路由精耐、高可用、故障轉(zhuǎn)移等問(wèn)題琅锻。
代理方案卦停,優(yōu)點(diǎn)是簡(jiǎn)化客戶端分布式邏輯和升級(jí)維護(hù)便利,缺點(diǎn)是家中架構(gòu)部署復(fù)雜度和性能損耗浅浮。
現(xiàn)在官方為我們提供了專有的集群方案:Redis Cluster沫浆,它非常優(yōu)雅地解決了Redis集群方面的問(wèn)題,因此理解好Redis Cluster將極大地解放我們使用分布式Redis的工作量滚秩,同時(shí)他也是學(xué)習(xí)分布式存儲(chǔ)的絕佳案例。
本章將從數(shù)據(jù)分布淮捆、搭建集群郁油、節(jié)點(diǎn)通信、集群伸縮攀痊、請(qǐng)求路由桐腌、故障轉(zhuǎn)移、集群運(yùn)維幾個(gè)方面介紹Redis Cluster苟径。
數(shù)據(jù)分布
-
數(shù)據(jù)分布理論
分布式數(shù)據(jù)庫(kù)首先要解決把整個(gè)數(shù)據(jù)集按照分區(qū)規(guī)則映射到多個(gè)節(jié)點(diǎn)的問(wèn)題案站,即把數(shù)據(jù)集劃分到多個(gè)節(jié)點(diǎn)上,每個(gè)節(jié)點(diǎn)負(fù)責(zé)整體數(shù)據(jù)的一個(gè)自己
需要重點(diǎn)關(guān)注的是數(shù)據(jù)分區(qū)規(guī)則棘街。常見(jiàn)的分區(qū)規(guī)則有哈希分區(qū)和順序分區(qū)兩種蟆盐,下表對(duì)這兩種分區(qū)規(guī)則進(jìn)行了對(duì)比承边。
分區(qū)方式 特點(diǎn) 代表產(chǎn)品 哈希分區(qū) 1.離散度好;2.數(shù)據(jù)分布業(yè)務(wù)無(wú)關(guān)石挂;3.無(wú)法順序訪問(wèn) Redis Cluster博助;Cassandra;Dynamo 順序分區(qū) 1.離散度易傾斜痹愚;2.數(shù)據(jù)分布業(yè)務(wù)相關(guān)富岳;3.可順序訪問(wèn) Bigtable;HBase拯腮;Hypertable 由于Redis Cluster采用哈希分區(qū)規(guī)則窖式,這里我們重點(diǎn)討論哈希分區(qū),常見(jiàn)的哈希分區(qū)規(guī)則有幾種动壤,下面分別介紹:
-
節(jié)點(diǎn)取余分區(qū)
使用特定的數(shù)據(jù)脖镀,如Redis的鍵或用戶ID,再根據(jù)節(jié)點(diǎn)數(shù)量N使用公式:hash(key)%N計(jì)算出哈希值狼电,用來(lái)決定數(shù)據(jù)映射到哪一個(gè)節(jié)點(diǎn)上蜒灰。這種方案存在一個(gè)問(wèn)題:當(dāng)節(jié)點(diǎn)數(shù)量變化時(shí),如擴(kuò)容或收縮節(jié)點(diǎn)肩碟,數(shù)據(jù)節(jié)點(diǎn)映射關(guān)系需要重新計(jì)算强窖,會(huì)導(dǎo)致數(shù)據(jù)的重新遷移。
這種方式的突出優(yōu)點(diǎn)是簡(jiǎn)單性削祈,常用語(yǔ)數(shù)據(jù)庫(kù)的分庫(kù)分表會(huì)澤翅溺,一般采用預(yù)分區(qū)的方式,提前根據(jù)數(shù)據(jù)量規(guī)劃好分區(qū)數(shù)髓抑,比如劃分為512或1024章表咙崎,保證可支撐未來(lái)一段時(shí)間的數(shù)據(jù)量,再根據(jù)負(fù)載情況將表遷移到其他數(shù)據(jù)庫(kù)中吨拍。擴(kuò)容是通常采用翻倍擴(kuò)容褪猛,避免數(shù)據(jù)映射全部被打亂導(dǎo)致全量遷移的情況。
-
一致性哈希分區(qū)
一致性哈希分區(qū)(Distributed Hash Table)實(shí)現(xiàn)思路是為系統(tǒng)中每個(gè)節(jié)點(diǎn)分配一個(gè)token羹饰,范圍一般在0~2^32伊滋,這些token構(gòu)成一個(gè)哈希環(huán)。數(shù)據(jù)讀寫(xiě)執(zhí)行節(jié)點(diǎn)查找操作時(shí)队秩,先根據(jù)key計(jì)算hash值笑旺,然后順時(shí)針找到第一個(gè)大于等于該哈希值的token節(jié)點(diǎn)。
這種方式相比節(jié)點(diǎn)取余最大的好處在于加入和刪除節(jié)點(diǎn)只影響哈希環(huán)中相鄰的節(jié)點(diǎn)馍资,對(duì)其他節(jié)點(diǎn)無(wú)影響筒主。但一致性哈希分區(qū)存在幾個(gè)問(wèn)題:
加減節(jié)點(diǎn)會(huì)造成哈希環(huán)中部分?jǐn)?shù)據(jù)無(wú)法命中,需要手動(dòng)處理或者忽略這部分?jǐn)?shù)據(jù),因此一致性哈希常用于緩存場(chǎng)景乌妙。
當(dāng)時(shí)用少量節(jié)點(diǎn)是使兔,節(jié)點(diǎn)變化將大范圍影響哈希環(huán)中數(shù)據(jù)映射,因此這種方式不適合少量數(shù)據(jù)節(jié)點(diǎn)的分布式方案冠胯。
普通的一致性哈希分區(qū)在增減節(jié)點(diǎn)是需要增加一倍或者減去一半節(jié)點(diǎn)才能保證數(shù)據(jù)和負(fù)載的均衡火诸。
正因?yàn)橐恢滦怨7謪^(qū)的這些缺點(diǎn),一些分布式系統(tǒng)采用虛擬槽對(duì)一致性哈希進(jìn)行改進(jìn)荠察,比如Dynamo系統(tǒng)置蜀。
-
虛擬槽分區(qū)
虛擬槽分區(qū)巧妙地使用了哈希空間悉盆,使用分散度良好的哈希函數(shù)把所有數(shù)據(jù)映射到一個(gè)固定范圍的整數(shù)集合中盯荤,整數(shù)定義為槽(slot)。這個(gè)范圍一般遠(yuǎn)遠(yuǎn)大于節(jié)點(diǎn)數(shù)焕盟,比如Redis Cluster槽范圍是0~16383.槽是集群內(nèi)數(shù)據(jù)管理和遷移的基本單位秋秤。采用大范圍槽的主要目的是為了方便數(shù)據(jù)拆分和集群擴(kuò)展。每個(gè)節(jié)點(diǎn)會(huì)負(fù)責(zé)一定數(shù)量的槽脚翘。
-
-
Redis數(shù)據(jù)分區(qū)
Redis Cluster采用虛擬槽分區(qū)灼卢,所有的鍵根據(jù)哈希函數(shù)映射到0~16383整數(shù)槽內(nèi),計(jì)算公式:slot=CRC16(key)&16383来农。每一個(gè)節(jié)點(diǎn)負(fù)責(zé)維護(hù)一部分槽以及槽所映射的鍵值數(shù)據(jù)鞋真。
Redis虛擬槽的分區(qū)的特點(diǎn):
解耦數(shù)據(jù)和節(jié)點(diǎn)之間的關(guān)系,簡(jiǎn)化了節(jié)點(diǎn)擴(kuò)容和收縮難度沃于。
節(jié)點(diǎn)自身維護(hù)槽的映射關(guān)系涩咖,不需要客戶端或者代理服務(wù)維護(hù)槽分區(qū)元數(shù)據(jù)。
支持節(jié)點(diǎn)繁莹、槽檩互、鍵之間的映射查詢,用于數(shù)據(jù)路由咨演、在線伸縮等場(chǎng)景闸昨。
數(shù)據(jù)分區(qū)是分布式存儲(chǔ)的核心,理解和靈活運(yùn)用數(shù)據(jù)分區(qū)規(guī)則對(duì)于掌握Redis Cluster非常有幫助雪标。
-
集群功能限制
Redis集群相對(duì)單機(jī)在功能上存在一些限制零院,需要開(kāi)發(fā)人員提前了解,在使用時(shí)做好規(guī)避村刨。限制如下:
key批量操作支持有限。如mset撰茎、mget嵌牺,目前只支持具有相同slot值的key執(zhí)行批量操作。對(duì)于映射為不同slot值的key由于執(zhí)行mset、mget等操作可能存在于多個(gè)節(jié)點(diǎn)上因此不被支持逆粹。
key事務(wù)操作支持有限募疮。同理只支持多key在同一節(jié)點(diǎn)上的事務(wù)操作,當(dāng)多個(gè)key分布在不同的節(jié)點(diǎn)上時(shí)無(wú)法使用事務(wù)功能僻弹。
key作為數(shù)據(jù)分區(qū)的最小粒度阿浓,因此不能將一個(gè)大的鍵值對(duì)象如hash、list等映射到不同的節(jié)點(diǎn)蹋绽。
不支持多數(shù)據(jù)庫(kù)空間芭毙。單機(jī)下的Redis可以支持16個(gè)數(shù)據(jù)庫(kù),集群模式下只能使用一個(gè)數(shù)據(jù)庫(kù)空間卸耘,即 db 0退敦。
復(fù)制結(jié)構(gòu)支持一層,從節(jié)點(diǎn)只能復(fù)制主節(jié)點(diǎn)蚣抗,不支持嵌套樹(shù)狀復(fù)制結(jié)構(gòu)侈百。