集羣:Codis

Codis就是一個Redis代理中間件,其對外協議與Redis協議保持一致,當客戶端向Codis發送指令時,Codis負責將指令轉發到後面的Redis實例來執行並將返回結果再轉回給客戶端。

Codis掛接的所有Redis實例構成一個Redis集羣,當集羣空間不足時,可以通過動態增加Redis實例來實現擴容需求。

問題1:Codis是如何分發客戶端請求的呢???

答:

第一步:Codis將所有的key默認劃分爲1024個槽位(slot),它首先對客戶端傳過來的key進行crc32運算計算哈希值,再將 hash後的整數值對1024這個整數進行取模得到一個餘數,這個餘數就是對應key的槽位。(槽位數量默認是1024,它是可以配置的)

第二步:每個槽位都會唯一映射到後面的唯一一個Redis實例。

問題2:由於Codis也可以組成集羣,那如何把集羣中某個Coids槽位與key映射關係同步到其他Codis中呢?

答:這裏Codis必須使用一個分佈式數據庫來實現這個目標,比如:ZooKeeper、etcd等。

問題3:還有個問題就是,假如1024個槽位映射到N個Redis實例,假如現在變成了(N+M)個Redis實例,那1024個槽位映射關係該怎麼重寫?

答:通過Codis的SLOTSSCAN指令來掃描1024個槽位所對應的key,然後篩選出符合條件的key,最後把這些key映射到新增加的Redis實例。

同時在新映射這個過程中,某些客戶端請求恰恰落在這些待遷移的槽位上,由於當前槽位的數據同時存在於新舊兩個槽位中,Codis無法判定遷移過程中的key究竟在哪個實例中,所以當Codis接收到位於正在遷移槽位中的key後,會立即強制對當前的單個key進行遷移,遷移完成後,再將請求轉發到新的Redis實例。

同時Redis新增實例,手工均衡太繁瑣,Codis提供了自動均衡功能。自動均衡會在系統比較空閒的時候觀察每個Redis實例對應的 Slots數量,如果不平衡,就會自動進行遷移。

問題4:那Codis的缺點是什麼?

答:

①不同key映射到不同的Redis實例,因此無法跨實例來支持事務。

②rename指令變得很危險,如果rename前後名字被映射到不同的Redis實例下,那rename指令無法被正確執行。

③key的數量不能太多,因爲我需要取哈希,再去1024取餘,如果key數量太多,會給遷移帶來卡頓。官方建議單個集合結構的總字節容量不要超過1M。

④Codis作爲中間件,直面客戶端請求,因此網絡開銷比單個Redis大。

⑤如果Codis作爲集羣使用,必須使用分佈式數據庫,例如:ZooKeeper,而爲了維護ZooKeeper也是一定工作量。

⑥Codis作爲非官方Redis集羣方案,當官方Redis有變化的時候它要實時去跟進。

發佈了167 篇原創文章 · 獲贊 10 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章