支撐微博億級社交平臺,小白也能玩轉Redis集羣(原理篇)

Redis做爲一款性能優異的內存數據庫,支撐着微博億級社交平臺,也成爲不少互聯網公司的標配。這裏將以Redis Cluster集羣爲核心,基於最新的Redis5版本,從原理再到實戰,玩轉Redis集羣node

常見Redis集羣方案

在介紹Redis Cluster集羣方案以前,爲了方便對比,先簡單瞭解一下業界常見的Redis集羣方案:redis

1 基於客戶端分片

Redis Sharding是Redis Cluster出來以前,業界廣泛使用的多Redis實例集羣方法。其主要思想是基於哈希算法,根據Redis數據的key的哈希值對數據進行分片,將數據映射到各自節點上算法

優勢在於實現簡單,缺點在於當Redis集羣調整,每一個客戶端都須要更新調整數據庫

2 基於代理服務器分片

客戶端發送請求到獨立部署代理組件,代理組件解析客戶端的數據,並將請求轉發至正確的節點,最後將結果回覆給客戶端數組

優勢在於透明接入,容易集羣擴展,缺點在於多了一層代理轉發,性能有所損耗緩存

3 Redis Sentinel(哨兵)

Redis Sentinel是官方從Redis 2.6版本提供的高可用方案,在Redis主從複製集羣的基礎上,增長Sentinel集羣監控整個Redis集羣。當Redis集羣master節點發生故障時,Sentinel進行故障切換,選舉出新的master,同時Sentinel自己支持高可用集羣部署服務器

優勢在於支持集羣高可用,高性能讀寫,缺點在於沒有實現數據分片,每一個節點須要承載完整數據集,負載能力受當個Redis服務器限制,僅支持經過增長機器內存實現垂直擴容,不支持水平擴展markdown

Redis Cluster設計

1 總體設計

Redis Cluster 是 在 3.0 版本正式推出的高可用集羣方案,相比Redis Sentinel,Redis Cluster方案不須要額外部署Sentinel集羣,而是經過集羣內部通訊實現集羣監控,故障時主從切換;同時,支持內部基於哈希實現數據分片,支持動態水平擴容網絡

總體架構以下:架構

集羣中有多個主節點,每一個主節點有多個從節點,主從節點間數據一致,最少須要3個主節點,每一個主節點最少須要1個從節點

  • 高可用:當master節點故障時,自動主從切換
  • 高性能:主節點提供讀寫服務,從節點只讀服務,提升系統吞吐量
  • 可擴展性:集羣的數據分片存儲,主節點間數據各不一樣,各自維護對應數據,能夠爲集羣添加節點進行擴容,也能夠下線部分節點進行水平縮容

2 數據分片

將整個數據集按照必定規則分配到多個節點上,稱爲數據分片,Redis Cluster採用的分片方案是哈希分片

基本原理以下: Redis Cluster首先定義了編號0 ~ 16383的區間,稱爲槽,全部的鍵根據哈希函數映射到0 ~ 16383整數槽內,計算公式:slot=CRC16(key)&16383。每個節點負責維護一部分槽以及槽所映射的鍵值數據

槽是 Redis 集羣管理數據的基本單位,集羣擴容收縮就是槽和數據在節點之間的移動

槽與節點映射關係以下:

  • 每一個集羣節點維護着一個16384 bit (2kB)的位數組,每一個bit對應相同編號的槽,用 0 / 1標識對於某個槽本身是否擁有
  • 集羣節點同時還維護着槽到集羣節點的映射,是由長度爲16384,數組下標表明槽編號,值爲節點信息的數組

3 集羣擴容

Redis Cluster支持不影響集羣對外服務的狀況下,對集羣進行動態擴容或縮容,當Redis 新節點加入現有集羣后,須要爲其遷移槽和數據,確保遷移後每一個節點負責類似數量的槽,使數據分佈均勻在各節點上

整個數據遷移涉及系列操做,Redis提供了集羣管理工具,包括基於Ruby的redis-trib.rb,還Redis5新提供的基於C語言redis-cli,下面的介紹以redis-cli爲例

源節點將指定slot數據遷移到目標節點,基本流程以下:

  • (1) redis-cli設置目標節點指定slot狀態importing,讓目標節點準備遷入slot數據
  • (2) redis-cli設置源節點指定slot狀態migrating,讓讓源節點準備遷出slot的數據
  • (3) redis-cli批量遷移源節點指定slot中的數據到目標節點
  • (4) 數據遷移完後 redis-cli向集羣全部主節點通知槽被分配給目標節點,主節點更新slot與節點映射關係信息

一般狀況下,若是客戶端請求的數據不在節點上,節點會回覆 MOVED 重定向信息,客戶端根據該信息再請求正確的節點。對於正在遷移的slot數據,保證客戶端仍然能正常訪問的設計以下:

  • (1) 遷移完成後才更新slot與節點映射關係信息,若是遷移進行中的映射信息保持與遷移前一致
  • (2) 若是客戶端訪問源節點,訪問的key還沒有遷出,則正常的處理該key
  • (3) 若是客戶端訪問源節點,訪問的key尚已遷出,源節點返回ASK重定向信息
  • (4) 客戶端根據ASK 重定向異常提取出目標節點信息,先向目標節點發送ASKING命令請求操做,再執行鍵命令

ASK 和 MOVED 這2個重定向控制有以下區別:

  • ASK 重定向說明集羣正在進行 slot 數據遷移,客戶端沒法知道何時遷移完成,所以只能是臨時性的重定向,客戶端不會更新 slot 到 Redis 節點的映射緩存。
  • MOVED 重定向說明鍵對應的slot 已經明確指定到新的節點,所以須要更新 slot 到 Redis 節點的映射緩存

4 CAP取捨

CAP包括:一致性(Consistency)、可用性(Availability)、分區容錯性(Partition tolerance),系統若是不能在時限內達成數據一致性,就意味着發生了分區的狀況,必須在C和A之間作出選擇

Redis Cluster選擇了AP架構,爲了保證可用性,Redis並不保證強一致性,在特定條件下會出現數據不一致甚至丟失寫操做

第一個緣由是:爲了在性能和一致性上作出權衡,主從節點間數據同步是異步複製的,當客戶端成功寫入master節點,master返回成功,master節點纔將寫操做異步複製給slave節點

另一個緣由是,當集羣發送網絡分區,集羣可能會分爲兩部分:多數派和少數派,假如masterA節點位於少數派,若是網絡分區發生時間較短,那麼集羣將會繼續正常運做;若是分區的時間足夠長,讓多數派中選舉爲新的master替代matsterA,那麼分區期間寫入masterA的數據就丟失了

在網絡分區期間, 客戶端能夠向matsterA發送寫命令的最大時間是有限制的, 這一時間限制稱爲節點超時時間(cluster-node-timeout),是 Redis集羣的一個重要的配置選項

總結

至此,Redis Cluster集羣原理介紹到這裏,其實還有集羣通訊協議,內存,數據備份,主從複製等特性值得學習,是設計分佈式系統的典範,有機會再展開介紹

下一篇《實戰篇》,介紹Redis Cluster的集羣實戰

參考

微博6年redis實踐 mp.weixin.qq.com/s/dBWIHwfmr…

Redis 官網介紹cluster設計說明 redis.io/topics/clus… redis.io/topics/clus…

相關文章
相關標籤/搜索