資料部分
redis cluster採用雜湊分割槽規則,具體為虛擬槽分割槽,使用分散度好的雜湊函式分到一個大範圍的整數,每個節點負責一定數量的槽。slot=CRC16(key)&16383
特點:解耦資料和節點之間的關係;節點自身維護槽的對映關係,不需要客戶端和代理服務維護槽分割槽後設資料;支援節點、槽、鍵之間的對映查詢,用於資料路由、線上伸縮等場景;
限制:1)只支援相同槽的key執行批次讀寫
2)分佈在多個節點上的key無法使用事務
3)不能將hash、list對映到不同的節點
4)只有db0
5)主從結構只有1層
搭建叢集
1)準備節點
劃分為conf、data、log三個目錄,至少6個節點組成叢集,配置開啟叢集模式,設定超時時間和叢集內配置檔案
2)節點握手
客戶端使用meet命令讓其他節點加入到叢集中
3)分配槽
-h ip -p port cluster addslots {0...xxx}分配槽
每個分配了槽的節點需要具有從節點,從節點使用cluster replicate {nodeId}配置主節點
可使用使用redis-trib.rb搭建叢集(相比來說自動化了主從節點和槽分配步驟)
節點通訊
redis 叢集採用P2P的Gossip協議,節點間不斷更換資訊。
訊息通訊模式包括:meet(通知新節點加入,1-1)、ping(高頻交換資訊,1-多)、pong(回應前兩種,1對多)、fail(將某個節點下線資訊廣播)
通訊節點選擇:選擇5個最近沒通訊的節點,如果太久沒受到pong,則立刻向該節點傳送;訊息體開銷和叢集數量有關,並不是越多節點越好
叢集伸縮
不影響對外服務的期刊下,可以為叢集新增節點進行擴容也可以下線部分節點。
新增節點:原每個節點把一部分槽和資料遷移到新的節點
擴容叢集
- 準備新節點
- meet加入叢集(使用工具對新加入節點進行檢查,包括已經加入其他叢集或包含資料)
- 遷移槽和資料
- 槽遷移計劃
- 遷移資料
1)分別準備讓目標節點準備匯入槽資料和源節點準備準備遷出槽資料
2)源節點迴圈執行命令,獲取x個屬於槽的鍵
3)獲取上一步鍵的資料
- 迴圈獲取鍵和鍵的資料
- 通知槽分配給目標節點(傳送給所有主節點更新被遷移的槽指向新節點)
- 新增從節點
請求路由
- 如果請求槽是該節點,則直接返回,否則返回moved來重定向,透過客戶端再次發起請求
redis io最佳化:使用{}包含的內容hash_tag,使具備相同的slot mget user:{10086}:friends user:{100086}:videos 上面兩個鍵具有相同的槽 - 槽節點查詢,有開銷額外的io開銷,採用smart客戶端
smart客戶端:在內部維護slot-node的對映,為每個節點建立連線池,執行鍵命令
執行鍵命令流程如下:
1)計算slot並根據slots快取獲取目標節點連線,傳送命令
2)if 出現錯誤 使用隨機連線重新執行鍵命令,重試次數-1
3)捕獲重定向錯誤,更新slots快取
4)重複1~3,直到成功,當次數<=0時丟擲最大重定向異常
當連線失敗時,可能1、socket錯誤;2、lua指令碼或命令超時;3、連線池獲取物件超時
當故障轉移時,會發生叢集槽風暴,現象:丟擲最大重定向異常;節點操作異常導致頻繁更新槽快取;頻繁更新本地槽快取
以前是Jedis+JedisPool組合。隨著Spring Boot2.x的到來,支援的元件越來越豐富,也越來越成熟,其中對Redis的支援不僅僅是豐富了它的API,更是替換掉底層Jedis的依賴,取而代之換成了Lettuce高階Redis客戶端,用於多執行緒安全同步,非同步和響應使用。Lettuce和Jedis的都是連線Redis Server的客戶端程式。Jedis在實現上是直連redis server,多執行緒環境下非執行緒安全,除非使用連線池JedisPool,為每個Jedis例項增加物理連線。Lettuce基於Netty的連線例項(StatefulRedisConnection),可以在多個執行緒間併發訪問,且執行緒安全,滿足多執行緒環境下的併發訪問,同時它是可伸縮的設計,一個連線例項不夠的情況也可以按需增加連線例項。
故障轉移
類似於redis 哨兵的主客觀下線(只有主節點來發現故障和決策)
故障恢復:1.從節點資格檢查2.準備選舉時間(從節點根據偏移量來作為優先順序)3.發起選舉(更新配置紀元、廣播選舉小心)4、投票選舉,其他主節點來投票5、替換主節點
叢集運維
叢集完整性:設定cluster-require-full-coverage為no,使得未指標節點的槽不會影響其他節點。
頻寬消耗:訊息傳送頻率(cluster-node-timeout)、訊息資料量、節點規模、
1)滿足業務的情況下避免大叢集。根據業務拆分使用多套叢集
2)適當降低訊息傳送頻率
3)避免集中部署
釋出訂閱廣播問題:叢集內會對publish資料在所有節點廣播一次,使用哨兵結構用於廣播功能。
資料傾斜:1、節點和槽分配嚴重不均2、槽對應鍵數量差異過大3、集合物件包含大量元素4、記憶體相關配置不一致
2、請求傾斜:1、合理設定鍵,大集合物件作拆分或用hmget規避全讀取2、不要使用熱鍵作為hash_tag,避免對映到同一槽3)對於一致性要求不高的場景,客戶端使用本地快取
叢集讀寫分離
1、配置為只讀 2、讀寫分離成本較高,更適合直接擴充主節點數量(特殊場景:降低網路延遲,故障轉移時長過大,給從節點保證讀操作可用)
手動故障轉移場景:1、主節點遷移2、強制故障轉移
資料遷移
單機=》叢集 使用工具