Redis Cluster執行流程

Redis Cluster執行流程

集羣(cluster)是Redis提供的分佈式數據庫解決方案,集羣通過分片(sharding)來進行數據共享,並提供數據複製(replication)和故障轉移(failover)等功能。下面介紹下Cluster的執行流程。

一. 啓動節點

Redis服務器在啓動時,會根據cluster-enabled配置決定是否開啓服務器的集羣模式。如果未開啓,就進入stand alone模式,以普通單機Redis方式運行。否則進入集羣模式。

一個Redis集羣通常由多個節點(node)組成。在初始化時,每個node都是相互獨立的,它們都處於一個只包含自己的集羣當中。要想組成一個真正可用的集羣,必須將多個獨立的節點連接起來。

向一個node發送CLUSTER MEET命令,可以讓node與指定的節點進行握手,握手成功後,指定的節點就加入到node所在的集羣中。

新的節點加入集羣后。node會通過Gossip協議傳播給集羣中的其他節點,讓其他節點也與新加入的節點握手。最終經過一段時間後,集羣中的所有節點就建立起了連接。

二. 槽指派

**Redis通過數據分片的方式保存數據庫中的鍵值對:整個數據庫被分爲16384個槽(slot),數據庫中的每個鍵都位於這16384個槽中的一個,集羣中的每個節點都可以處理0~16384個槽。**可以通過命令爲每個節點分配指定的槽位。

三. 在集羣中執行命令

在對數據庫中的16384個槽都分配成功了之後,集羣就進入上線狀態,就可以正常接收客戶端命令提供服務了。

當客戶端向集羣中的節點發送key相關操作的命令時,接收命令的節點會進行如下操作:

  1. 計算key屬於哪個槽。Redis通過:CRC16(key) % 16383 算法計算出key屬於哪個槽位。
  2. 如果目標槽位正好指派給了當前節點,那麼當前節點直接執行這個命令。
  3. 目標槽位在其他節點上,那麼當前節點會向客戶端返回一個MOVED錯誤,引導客戶端重定向(redirect)到正確的節點上,並再次發送想要執行的命令。

四. 重新分片

Redis集羣可以通過重新分片操作,將任意數量的已經指派給某個節點(源節點)的槽改爲指派給另一個節點(目標節點),並且槽位上所屬的所有鍵值對也會一併被移動過去。

重新分片操作可以在線執行,在重新分片操作執行過程中,集羣不需要下線,並且源節點和目標節點都可以繼續處理客戶端請求。

五. ASK錯誤

在執行重新分片的過程中,可能存在這樣一種情況:在遷移某個槽位上的數據時,一部分數據已經被遷移到了目標節點,而還有一部分數據仍然在源節點上未遷移完成。此時客戶端如果向源節點發送請求,要對這個槽位上的數據進行處理,則會進行如下的操作:

  1. 源節點首先會在自己的數據庫中查找指定的key,如果找到了,則直接在源節點上執行客戶端命令。
  2. 如果未找到,則該key很有可能已經被遷移到了目標節點,此時源節點會向目標節點返回一個ASK錯誤,指引客戶端轉向正在導入槽的目標節點,並再次發送之前要執行的命令。

六. 複製與故障轉移

集羣中的節點分爲主節點(master)和從節點(slave)。主節點用於處理槽相關的操作,而從節點則用於複製主節點,並在主節點下線時,選舉出一個新的主節點,代替下線的主節點繼續處理命令請求。

集羣中的每個節點都會定期向集羣中的其他節點發送PING消息,以此來檢測對方的在線狀態。如果接收PING消息的節點沒有在規定時間內返回PONG響應,則發送PING消息的節點會將接收PONG消息的節點標記爲疑似下線(probable fail, PFAIL)狀態。

集羣中的每個節點都會通過相互發送消息的方式,來交換集羣中各個節點的狀態信息,例如一個節點是在線狀態、疑似下線狀態(PFAIL)還是已下線狀態(FAIL)。

如果一個集羣中,半數以上的處理槽的主節點都認爲一個主節點處於PFAIL狀態,那麼這個主節點就會被標記爲已下線狀態(FAIL),並將這個主節點下線的消息在集羣中進行廣播,所有接受到這條消息的節點都會立即將其標記爲FAIL狀態。

當一個從節點發現它複製的主節點進入下線狀態時,那麼從節點就會對已下線的主節點進行故障轉移,下面是執行故障轉移的步驟:

  1. 從下線的主節點的所有從節點中,選舉一個出來。
  2. 被選中的從節點執行SLAVEOF no one命令,成爲新的主節點。
  3. 新的主節點會撤銷對已下線主節點的所有槽指派,並將這些槽全部指派給自己。
  4. 新的主節點向集羣中廣播一條PONG消息,其他節點接收到消息後會立即知道新主節點的產生,並且這個主節點已經接管了已下線主節點的所有槽。
  5. 新的主節點開始接收和自己負責的槽相關的所有命令,故障轉移完成。

七. 消息

集羣中的各個節點都是通過消息來彼此通信的。發送消息的節點成爲sender,接收消息的節點成爲receiver。節點的消息類型主要有一下五種:

  1. MEET:當sender接收到客戶端發送的CLUSTER MEET命令時,會向receiver發送MEET消息,請求receiver加入到sender所在的集羣中。
  2. PING:集羣中的每個節點默認每秒鐘從已知節點列表中隨機選出5個節點,然後對這5個節點中最長時間沒有發送PING消息的節點發送PING消息,以此來檢測被選中的節點是否在線。此外,如果節點A最後一次收到節點B的PONG消息的時間,距離當前時間已經超過了節點A設置的cluster-node-timeout時間的一半,那麼節點A也會向節點B發送PING消息,這樣可以防止節點A由於長期沒有選擇節點B而導致對節點B的信息更新的滯後。
  3. PONG:當receiver收到sender發來的MEET或PING消息後,爲了向sender確認這條消息已送達,receiver就會向sender響應一條PONG消息。另外,一個幾點也可以通過向集羣中廣播PONG消息,來刷新其他節點對於該節點的認知。例如,當一次故障轉移執行成功後,新的主節點就會向集羣中廣播一條PONG消息,通知其他節點自己變成的新的主節點,並且接管了原來主節點的所有槽。
  4. FAIL:當一個主節點A判斷另一個主節點B已經進入下線狀態時,A就會向集羣中廣播一條關於B的FAIL消息,所有收到這條消息的節點都會立即將節點B標記爲已下線狀態。
  5. PUBlISH:當一個節點接收到PUBLISH命令時,節點會執行這個命令,並向集羣中廣播一條PUBLISH消息,所有接受到這條PUBLISH消息的節點都會執行相同的PUBLISH命令。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章