Redis集群模式在擴容情況下,如何處理客戶端的讀寫請求
Redis的高可用方案主要有三種模式,分別主從復制模式、哨兵模式和集群模式。那么在Redis集群模式下,集群在擴容的時候如何處理客戶端的讀寫請求呢?如下所示的Redis的集群:
圖片
假設現在將集群中3個節點擴充為4個節點,那么新加入1個節點后,節點的槽分布情況如下圖所示:
圖片
1、集群擴容的過程
使用Redis的命令在Redis集群添加1個新的節點(假設為Node_3節點),如下圖所示:
圖片
新加入的Node_3節點由于還沒有分配槽位,所以Node_3節點不會處理任何請求,整個Redis集群的讀寫操作還是按照原先邏輯執行,不會受到新加入節點的影響。那么新加入的節點分配槽位的過程如下所示:
首先要從Node_2節點上遷移槽位到Node_3節點上,此時客戶端會發起migrating指令到Node_2節點上,如下如所示:
圖片
此時的Node_2節點就會處于遷出狀態(代表有槽位需要從這個節點上遷移出去),Node_3節點需要接收遷出的槽位,客戶端會發送importing命令到Node_3節點上,如下圖所示:
圖片
然后Node_2節點就可以將槽位12288遷移到Node_3節點上,通過這樣的步驟依次實現集群中所有的槽位遷移工作,最后的遷移結果如下圖所示:
圖片
2、遷移過程中數據的查詢
(1)槽位還在原先的節點上
當客戶端發送請求(get longxia),假設通過CRC16計算出來其槽位是12288,那么就是去Node_2節點上查詢數據,此時由于Node_2上的槽位還沒有被遷移出去,那么Node_2會返回對應的數據給客戶端,如下如所示:
圖片
(2)槽位遷移到新節點上
當客戶端發送請求(get longxia),假如其槽位是12288并且Node_2節點已經將槽位12288遷移到了Node_3節點上了,如下圖所示:
當客戶端發起查詢請求的時候,Node_2節點由于將槽位12288遷移到新節點Node_3上了,所以Node_2會給客戶端返回臨時的ASK重定向響應(也就是告訴客戶端去Node_3節點上查詢數據),客戶端接收到了臨時的ASK后就會發送請求去目標節點上(Node_3節點)上查詢。
客戶端會發起asking命令到Node_3節點上(asking命令是告訴Node_3節點接下來的命令是Node_2節點轉發的請求,必須要進行處理,即使可能槽位暫時不屬于Node_3節點管理),當Node_3節點收到asking命令之后,會響應ok給客戶端。
最后,客戶端會發起查詢的請求(get longxia)到Node_3節點上,Node_3節點處理請求并返回數據給客戶端。
其實,當槽位成功的遷移的新的節點上后,就會向集群中所有的節點發送一個遷移槽位數據成功的通知,目的就是后面要查詢(如槽位12288)槽位的數據就要去具體的節點上查詢(如Node_3節點),而不需要經過原來的節點進行重定向了。
因此,即使在集群槽位遷移的過程中,Redis集群還是可以正常的提供服務。
總結:
(1)Redis集群遷移中會將源節點置為遷移狀態,然后將目標節點置為遷移中狀態,最后將槽位數據執行遷移動作。
(2)遷移過程中,Redis的集群還是可以正常地提供服務。如果計算出來的槽位還在原先的節點上,那么源節點會直接返回數據給客戶端;如果源節點上的槽位已經被遷移到新節點上,那么源節點會告訴客戶端去新節點上查詢數據。