Redis集群模式在擴(kuò)容情況下,如何處理客戶端的讀寫請求
Redis的高可用方案主要有三種模式,分別主從復(fù)制模式、哨兵模式和集群模式。那么在Redis集群模式下,集群在擴(kuò)容的時候如何處理客戶端的讀寫請求呢?如下所示的Redis的集群:
圖片
假設(shè)現(xiàn)在將集群中3個節(jié)點擴(kuò)充為4個節(jié)點,那么新加入1個節(jié)點后,節(jié)點的槽分布情況如下圖所示:
圖片
1、集群擴(kuò)容的過程
使用Redis的命令在Redis集群添加1個新的節(jié)點(假設(shè)為Node_3節(jié)點),如下圖所示:
圖片
新加入的Node_3節(jié)點由于還沒有分配槽位,所以Node_3節(jié)點不會處理任何請求,整個Redis集群的讀寫操作還是按照原先邏輯執(zhí)行,不會受到新加入節(jié)點的影響。那么新加入的節(jié)點分配槽位的過程如下所示:
首先要從Node_2節(jié)點上遷移槽位到Node_3節(jié)點上,此時客戶端會發(fā)起migrating指令到Node_2節(jié)點上,如下如所示:
圖片
此時的Node_2節(jié)點就會處于遷出狀態(tài)(代表有槽位需要從這個節(jié)點上遷移出去),Node_3節(jié)點需要接收遷出的槽位,客戶端會發(fā)送importing命令到Node_3節(jié)點上,如下圖所示:
圖片
然后Node_2節(jié)點就可以將槽位12288遷移到Node_3節(jié)點上,通過這樣的步驟依次實現(xiàn)集群中所有的槽位遷移工作,最后的遷移結(jié)果如下圖所示:
圖片
2、遷移過程中數(shù)據(jù)的查詢
(1)槽位還在原先的節(jié)點上
當(dāng)客戶端發(fā)送請求(get longxia),假設(shè)通過CRC16計算出來其槽位是12288,那么就是去Node_2節(jié)點上查詢數(shù)據(jù),此時由于Node_2上的槽位還沒有被遷移出去,那么Node_2會返回對應(yīng)的數(shù)據(jù)給客戶端,如下如所示:
圖片
(2)槽位遷移到新節(jié)點上
當(dāng)客戶端發(fā)送請求(get longxia),假如其槽位是12288并且Node_2節(jié)點已經(jīng)將槽位12288遷移到了Node_3節(jié)點上了,如下圖所示:

當(dāng)客戶端發(fā)起查詢請求的時候,Node_2節(jié)點由于將槽位12288遷移到新節(jié)點Node_3上了,所以Node_2會給客戶端返回臨時的ASK重定向響應(yīng)(也就是告訴客戶端去Node_3節(jié)點上查詢數(shù)據(jù)),客戶端接收到了臨時的ASK后就會發(fā)送請求去目標(biāo)節(jié)點上(Node_3節(jié)點)上查詢。
客戶端會發(fā)起asking命令到Node_3節(jié)點上(asking命令是告訴Node_3節(jié)點接下來的命令是Node_2節(jié)點轉(zhuǎn)發(fā)的請求,必須要進(jìn)行處理,即使可能槽位暫時不屬于Node_3節(jié)點管理),當(dāng)Node_3節(jié)點收到asking命令之后,會響應(yīng)ok給客戶端。
最后,客戶端會發(fā)起查詢的請求(get longxia)到Node_3節(jié)點上,Node_3節(jié)點處理請求并返回數(shù)據(jù)給客戶端。
其實,當(dāng)槽位成功的遷移的新的節(jié)點上后,就會向集群中所有的節(jié)點發(fā)送一個遷移槽位數(shù)據(jù)成功的通知,目的就是后面要查詢(如槽位12288)槽位的數(shù)據(jù)就要去具體的節(jié)點上查詢(如Node_3節(jié)點),而不需要經(jīng)過原來的節(jié)點進(jìn)行重定向了。
因此,即使在集群槽位遷移的過程中,Redis集群還是可以正常的提供服務(wù)。
總結(jié):
(1)Redis集群遷移中會將源節(jié)點置為遷移狀態(tài),然后將目標(biāo)節(jié)點置為遷移中狀態(tài),最后將槽位數(shù)據(jù)執(zhí)行遷移動作。
(2)遷移過程中,Redis的集群還是可以正常地提供服務(wù)。如果計算出來的槽位還在原先的節(jié)點上,那么源節(jié)點會直接返回數(shù)據(jù)給客戶端;如果源節(jié)點上的槽位已經(jīng)被遷移到新節(jié)點上,那么源節(jié)點會告訴客戶端去新節(jié)點上查詢數(shù)據(jù)。























