Redis16:兩種redis集群解決方案:codis和cluster


兩種redis集群解決方案:codis和cluster

1、Codis

codis是一個代理中間件,當客戶端向codis發送指令時,codis負責將指令轉發到后面的redis來執行,並將結果返回給客戶端。

一個codis實例可以連接多個redis實例,也可以啟動多個codis實例來支撐,每個codis節點都是對等的,這樣可以增加整體的QPS需求,還能起到容災功能。

槽位關系

codis根據key直接hash到1024個槽位,每個槽位對應后面的一個redis。計算出key的槽位就能將key轉發到正確的redis實例。

槽位關系一旦變化,就會涉及所有redis實例,codis用zookeeper來存儲槽位關系(集群配置中心),還提供了一個dashboard模塊來觀察和修改槽位關系。

槽位關系發生變化時,codis會用一個新的命令來查找指定槽位中的所有key,然后遷移每個key到正確的槽位。當請求打在正在遷移的槽位上時,codis會強制對該key進行遷移。

codis有自動均衡功能,在系統空閑時觀察每個redis實例對應的槽位數量,不均衡時就會自動遷移。

codis命令

對於批量獲取多個key的命令,codis會向每一個redis發送命令,然后匯總。

codis損失了redis的一些特性,因為原來存在一個redis里的key現在分散了,所以事務不支持了,rename這種涉及兩個key的命令也不支持了。

codis優缺點

codis增加了一層代理,網絡開銷變大。

codis優點:分布式交給了第三方處理,dashboard功能強大,但是調優參數多。

2、Cluster

cluster是redis官方提供的集群化方案,它與codis不同,它是去中心化的,集群的每個節點負責一部分數據,相互連接形成一個對等的集群,它們之間通過一種特殊的二進制協議相互交互集群信息。

cluster的槽位划分更細,槽位的信息存儲於每個節點上,不需要另外的分布式存儲來存節點的信息。客戶端也存有關於槽位的信息,它可以直接定位到目標節點。

槽位和遷移

cluster允許用戶強制將某個key掛在特定槽位上。

當客戶端向一個節點發送指令,但是節點已經沒有這個key了,此時就會返回-moved,告知客戶端應該去這個節點查找,同時客戶端修改本地槽位映射表。

遷移時按槽遷移,一次性獲取槽位所有key,然后一個key一個key遷移,每個key的遷移過程都是以原節點作為目標節點的客戶端,key是先序列化發送,然后接收端再反序列化存入內存,然后返回ok,最后原節點刪除該key。

遷移的過程是同步的,原節點的線程一直阻塞,直到遷移成功。

在遷移時請求,客戶端會先訪問舊節點,如果不在,舊節點返回重定向指令,然后客戶端發送asking命令給目標節點,然后再向目標節點請求。因為目標節點在遷移完成之前不屬於該槽位,所以直接訪問會被拒絕,發出moved命令,所以先發送asking告知下一條命令必須處理才行。

這樣遷移時的訪問效率由一次ttl變為了三次。

如果在遷移時訪問舊節點得到一個moved,然后如果此時新節點也要進行遷移,那么訪問新節點還是會得到一個moved,這就是多次重試,可以控制這個次數,如果超過一定次數直接認為失敗拋出異常。

( 無論是哪種集群方案,大key總是會大大降低遷移速度影響性能。)

gossip協議和節點失聯

redis集群使用gossip協議來廣播自己的狀態以及接受其他實例的信息。一個節點發現另一個節點失聯會把這條信息廣播出去,其他節點也收到該信息,如果發現該節點失聯的信息發生了很多,就標記該節點下線,然后進行主從切換,這就是一個節點失聯不代表失效,必須經過一個集群協商的過程。

有時發生網絡抖動,會導致節點失聯,頻繁的主從切換,此時可以設置timeout時間,還可以設置關於該時間的放大系數。以確保網絡抖動時主從切換不那么明顯。

如果服務器節點變更,客戶端訪問掛掉的節點,會拋出一個錯誤,此時會隨機訪問某個節點以確定原來槽位對應的位置。修改集群信息后,客戶端訪問會被告知集群不可用,此時就會重新初始化節點信息。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM