與memcached用戶端支援分布式方案不同,Redis更傾向于在服務端建構分布式存儲
- Redis分布式叢集圖1

- Redis分布式叢集
Redis Cluster是一個實作了分布式且允許單點故障的Redis進階版本,沒有中心節點,具有線性可伸縮的功能。節點與節點之間通過二進制協定進行通信,節點與用戶端之間通過ascii協定進行通信。
在資料的放置政策上,Redis Cluster将整個key的數值域分成4096個hash槽,每個節點上可以存儲一個或多個hash槽,也就是說目前Redis Cluster支援的最大節點數就是4096。
Redis Cluster使用的分布式算法也很簡單:crc16( key ) % HASH_SLOTS_NUMBER
整體設計可總結為:
- 資料hash分布在不同的Redis節點執行個體上
- M/S的切換采用Sentinel
- 寫:隻會寫master Instance,從sentinel擷取目前的master Instance
- 讀:從Redis Node中基于權重選取一個Redis Instance讀取,失敗/逾時則輪詢其他Instance;Redis本身就很好的支援讀寫分離,在單程序的I/O場景下,可以有效的避免主庫的阻塞風險
- 通過RPC服務通路,RPC server端封裝了Redis用戶端,用戶端基于Jedis開發
在資料一緻性問題上,Redis沒有提供CAS操作指令來保障高并發場景下的資料一緻性問題,不過它卻提供了事務的功能
Redis的Transactions提供的并不是嚴格的ACID的事務(比如一串用EXEC送出執行的指令,在執行中伺服器當機,那麼會有一部分指令執行了,剩下的沒執行)。
但是這個Transactions還是提供了基本的指令打包執行的功能(在伺服器不出問題的情況下,可以保證一連串的指令是順序在一起執行的,中間有會有其它用戶端指令插進來執行)
Redis還提供了一個Watch功能,你可以對一個key進行Watch,然後再執行Transactions,在這過程中,如果這個Watched的值進行了修改,那麼這個Transactions會發現并拒絕執行
1 資料分布算法
決定了在多master節點時,資料如何分布到這些節點。
- 自動将資料分片,每個master放部分資料
- 提供内置的高可用,部分master不可用時,還可繼續工作
Redis cluster下,每個Redis要開放兩個端口,比如:
- 一個是6379
-
另一個就是加10000的端口号16379
16379端口用于節點間通信,即cluster bus叢集總線。
cluster bus的通信,用來故障檢測,配置更新,故障轉移授權。cluster bus用另一種二進制協定 - gossip,用于節點間高效資料交換,占用更少網絡帶寬和處理時間。
1.1 hash
計算指定 key 的 hash值,然後對節點數量(3)取模。0、1、2三個結果打到對應mater node。
一個mater當機,所有請求過來,會發現都基于最新的2個master取模,嘗試去取資料。導緻大部分請求無法拿到有效緩存,流量湧入DB。
高井發場景 下不可接受。并發下對節點3的流量無法走緩存,導緻全部走DB,DB就會被壓垮。
任一master當機,大量資料就需重新計算再寫入緩存。
某mater當機,就導緻資料全部失效。全部要重新對剩下2台master取模,再分布到其它節點。
1.2 一緻性hash
自動緩存遷移、自動負載均衡。
可能集中在某個hash區間值多,導緻大量資料湧入同個master,造成master熱點問題,導緻性能瓶頸。
同樣是計算指定 key 的 hash值,然後用hash值在圓環對應各點(每點都有個hash值)對比,看hash值該落在這圓環的哪個部位。
key落在圓環後,順時針尋找距離自己最近節點。
一緻性hash算法保證任一master當機,隻有之前在那master上的資料會受影響,因為順時針走,全部在之前master上找不到了。會順時走到下個master,也找不到。
1/3的流量瞬間湧入DB,重新查詢。幾乎接近100%流量全部失效。
虛拟節點
給每個master做均勻分布的虛拟節點。
這樣在每個區間内,大量資料均勻分布到不同節點内,而非按順時針順序,全部湧入同一master。