Redis cluster集羣模式詳解

Redis Cluster 介紹

Redis Cluster是Redis的分佈式解決方案,在Redis 3.0版本正式推出的,集羣通過分片(sharding)來進行數據共享,並提供複製和故障轉移功能,能有效解決了Redis分佈式方面的需求。當遇到單機內存、併發、流量等瓶頸時,都可以採用Cluster架構達到負載均衡的目的。

在redis cluster架構下,每個redis要放開兩個端口號,比如一個是6379,另外一個就是加10000的端口號,比如16379

16379端口號是用來進行節點間通信的,也就是cluster bus的東西,集羣總線。cluster bus的通信,用來進行故障檢測,配置更新,故障轉移授權 gossip 協議

cluster bus用了另外一種二進制的協議,主要用於節點間進行高效的數據交換,佔用更少的網絡帶寬和處理時間

集羣組成

一個Redis集羣通常由多個節點(node)組成,剛開始的時候,每隔節點都是相互獨立的,他們都處於一個只包含自己的集羣當中,要組件一個真正可工作的集羣,我們必須將各個獨立的節點連接起來,構成一個包含多個節點的集羣。

命令如下:CLUSTER MEET <IP> <PORT>

向一個節點node發送CLUSTER MEET命令,讓node節點與指定的<ip>:<port>節點進行握手(handshake),當握手成功時,node節點就會將指定的<ip>:<port>節點添加到node節點當前的集羣,過程如下:

注:

  • clusterNode:clusterNode結構保存了一個節點的當前狀態(注:包含節點的創建時間、節點名字、IP、port等信息),每個節點都使用一個clusterNode來記錄自己的狀態,併爲集羣中的所有節點(包括主節點和從節點)都創建一個相應的clusterNode結構,來記錄其他節點信息
  • clusterState:每個節點node都保存着一個clusterState結構,這個結構記錄了在當前節點的視角下,集羣目前所處的狀態(clusteState中存儲了所有slusterNode信息)

🤔思考:集羣有了,節點也有了,那數據怎麼分佈呢?

槽指派(數據分佈)

Redis集羣通過分片的方式來保存數據庫中的鍵值對,集羣的整個數據庫被分爲16384個槽(slot),數據庫中的每個鍵都屬於這16384個槽的其中一個,集羣中的每個節點可以處理0個或最多16384個槽。每一個節點負責維護一部分槽以及槽所映射的鍵值數據。

下圖展示某個包含5個節點的示意圖:

注:槽指派可以不均勻分佈,計算公式CRC16(KEY)&16383 計算key所屬的槽位

指派槽分佈命令:CLUSTER ADDSLOTS 10001 10002 10003 ... 16383  

詳解可見官網命令介紹:https://redis.io/commands/cluster-addslots 

當數據庫中的16384個槽都有節點在處理時,集羣處於上線狀態(ok);相反地,如果數據庫中有任何一個槽沒有得到處理,那麼集羣處於下線狀態(fail)

注:集羣中每個節點都會傳播槽歸屬信息(傳播當前節點處理哪些槽),讓集羣中每個節點都持有槽指派的元信息,知道槽位分派在哪個節點

注:爲了能快速知道某個槽在哪個節點node上,redis維護了一個槽指派信息在clusterstate.slots數組中

集羣中命令執行流程

(1)計算鍵屬於哪個slot

(2)如果在當前節點,便執行該命令,如果不是,則返回MOVED錯誤

(3)前提是返回MOVED錯誤,客戶端收到MOVED錯誤並根據提供的信息轉向正確的節點進行訪問(該節點會再次執行以上流程)

如下圖:

注:這也是爲什麼有時候客戶端需要訪問兩次redis服務器

詳解參考:Redis cluster 集羣模式 請求重定向 客戶端爲什麼有時會訪問兩次?

複製和故障轉移

Redis集羣中的節點分爲主節點(master)和從節點(slave),其中主節點用於處理槽,從節點則用於複製某個主節點,並在主節點下線時,代替下線主節點繼續處理命令。

如下圖,若主節點掛掉,會在從節點中選出一個節點作爲新的主節點並客戶端發來的命令(可以有多個從機)

Redis cluster集羣模式功能限制

  • key批量操作支持有限。如:MSET``MGET,目前只支持具有相同slot值的key執行批量操作。
  • key事務操作支持有限。支持多key在同一節點上的事務操作,不支持分佈在多個節點的事務功能。
  • key作爲數據分區的最小粒度,因此不能將一個大的鍵值對象映射到不同的節點。如:hash、list。
  • 不支持多數據庫空間。單機下Redis支持16個數據庫,集羣模式下只能使用一個數據庫空間,即db 0。
  • 複製結構只支持一層,不支持嵌套樹狀複製結構。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章