之前我們討論的話題,無(wú)論是主從復(fù)制乖坠,還是哨兵模式搀突,都是單個(gè)redis實(shí)例在工作。在大數(shù)據(jù)高并發(fā)的場(chǎng)景下,這種部署方案會(huì)顯得力不從心仰迁。
首先單個(gè)實(shí)例的內(nèi)存不宜過(guò)大甸昏,過(guò)大的內(nèi)存,會(huì)導(dǎo)致rdb文件過(guò)大徐许,從而導(dǎo)致主從同步時(shí)全量同步時(shí)間過(guò)長(zhǎng)施蜜,重啟時(shí)也需要消耗很長(zhǎng)的時(shí)間加載數(shù)據(jù)。
其次體現(xiàn)在cpu的利用率上雌隅,單個(gè)redis實(shí)例只能利用單個(gè)核心翻默,處理海量數(shù)據(jù)時(shí),壓力很大恰起。
Codis是redis集群解決方案之一修械,它將眾多小內(nèi)存的reids實(shí)例整合起來(lái),將分布在多臺(tái)機(jī)器上的眾多cpu的計(jì)算能力聚集到一起检盼,完成海量數(shù)據(jù)的存儲(chǔ)與高并發(fā)的讀寫(xiě)肯污。
Codis是豌豆莢中間件團(tuán)隊(duì)發(fā)明的,在redis cluster未廣泛使用時(shí)吨枉,codis起到了至關(guān)重要的作用蹦渣。
Codis是Go語(yǔ)言開(kāi)發(fā)的代理中間件,如下圖所示:
Codis也采用redis的協(xié)議貌亭,對(duì)外提供服務(wù)柬唯,但是由于代理的機(jī)制,導(dǎo)致其有些命令是無(wú)法支持的圃庭。
Codis是無(wú)狀態(tài)的锄奢,這意味著我們可以啟用多個(gè)codis實(shí)例提供給client,每個(gè)codis實(shí)例是對(duì)等的冤议,這樣可以提高codis集群的qps斟薇,也可以起到容災(zāi)的作用。
Codis分片機(jī)制
Codis默認(rèn)所有的key劃分為1024個(gè)slot恕酸,對(duì)客戶端傳入的key做crc32運(yùn)算計(jì)算hash值,再將hash后的整數(shù)值對(duì)1024取模獲取key的slot胯陋。codis會(huì)在內(nèi)存中維護(hù)slot與redis實(shí)例的對(duì)應(yīng)關(guān)系蕊温。根據(jù)映射關(guān)系將數(shù)據(jù)轉(zhuǎn)發(fā)到對(duì)應(yīng)的實(shí)例。
slot數(shù)量是可以設(shè)置的遏乔。
不同的codis實(shí)例之間slot關(guān)系是如何同步的义矛?
codis集群通過(guò)對(duì)zk與etcd的支持來(lái)保證數(shù)據(jù)的一致性,如果是依賴zk盟萨,那么codisProxy的slot關(guān)系信息會(huì)存儲(chǔ)在zk節(jié)點(diǎn)上凉翻,通過(guò)zk的監(jiān)聽(tīng)機(jī)制來(lái)共享slot信息。
如下圖:
管理員可以通過(guò)dashboard維護(hù)slot相關(guān)信息捻激,然后再同步到各個(gè)codisProxy制轰。
如何擴(kuò)容前计?
進(jìn)行擴(kuò)容,意味著集群中增加新的redis實(shí)例垃杖,這時(shí)slot與實(shí)例的映射關(guān)系需要調(diào)整男杈,意味著一部分?jǐn)?shù)據(jù)需要進(jìn)行遷移。
首先第一個(gè)問(wèn)題是调俘,我們需要找到槽位對(duì)應(yīng)的所有key伶棒。codis增加了slotsscan命令,可以遍歷指定slot下所有的key彩库。然后挨個(gè)將每個(gè)key遷移到新的redis節(jié)點(diǎn)肤无。遷移過(guò)程中,codis收到新請(qǐng)求骇钦,如果是查詢key宛渐,那么會(huì)強(qiáng)制先完成遷移工作,然后再提供對(duì)外服務(wù)司忱。
最后一點(diǎn)皇忿,遷移操作是一個(gè)move操作,即遷移完成后坦仍,舊實(shí)例中就不存在key了鳍烁。
自動(dòng)均衡機(jī)制
redis新增實(shí)例,手動(dòng)均衡slot比較麻煩繁扎,所以codis提供了自動(dòng)均衡機(jī)制幔荒。自動(dòng)均衡機(jī)制會(huì)在系統(tǒng)空閑時(shí)觀察每個(gè)實(shí)例對(duì)應(yīng)的slot數(shù)量,不平衡會(huì)自動(dòng)進(jìn)行遷移梳玫。
Codis的劣勢(shì)
1.使用codis擴(kuò)容的機(jī)器爹梁,redis不再支持事務(wù)。
2.rename這種危險(xiǎn)的命令也不支持提澎。官方文檔中提供了不支持的命令列表姚垃。
3.為了支持遷移,單個(gè)key對(duì)應(yīng)的value不宜過(guò)大盼忌。過(guò)大會(huì)導(dǎo)致遷移卡頓积糯,官方建議小于1M,所以不適合存放社交關(guān)系數(shù)據(jù)等等谦纱。
4.網(wǎng)絡(luò)開(kāi)銷比單個(gè)實(shí)例要大看成,性能略微下降】缂危可以通過(guò)增加代理數(shù)量來(lái)彌補(bǔ)性能不足川慌。
5.如果依賴zk,那么會(huì)增加zk運(yùn)維成本。
Codis的優(yōu)勢(shì)
1.設(shè)計(jì)上比官方的redis cluster方案要簡(jiǎn)單梦重。
2.托管給zk或者etcd兑燥,省去了分布式一致性邏輯。
問(wèn)題:mget查詢多個(gè)key的場(chǎng)景忍饰,codis會(huì)將key按照映射關(guān)系分組贪嫂,然后對(duì)涉及的redis執(zhí)行mget,最后由codis匯總返回艾蓝。