Redis Cluster配置傳播及故障恢復筆記

本筆記是對Redis Cluster Spec - Configuration handling, propagation, and failovers的歸納總結。

Epoch

  • 可以把Epoch當作是一個版本號,是一個64位無符號整形
  • 每個Node自己有一份Cluster.currentEpoch、MySelf.configEpoch、其他Node.configEpoch,詳見文檔
  • 每個Master有自己的ConfigEpoch且在整個Cluster中唯一
  • Slave的ConfigEpoch隨其Master
  • Cluster.currentEpoch,該值等於所有Node中最大的ConfigEpoch的值
  • Master的ConfigEpoch初始值是0,也就是說Cluster.CurrentEpoch的初始值也是0
  • Node之間Gossip傳輸消息時,Receiver發現Sender的ConfigEpoch比自己大,那麼就更新自己的Cluster.CurrentEpoch爲該值,隨時間收斂,所有Node的Cluster.CurrentEpoch都變成一樣。

Slave Promotion

Slave的動作

下面是總結的在發生Slave Promotion時,Slave做的事情。

clipboard.png

Master的動作

下面是總結的在發生Slave Promotion時,Master做的事情。

clipboard.png

傳播Slots的配置

Slave贏得選舉之後會在己側更新Slots上的歸屬信息,然後在定時的PING/PONG中將這個信息傳播出去。

PING/PONG總是會攜帶上Slots所屬Master的信息(包括ConfigEpoch)

PING的Reciever如果發現Sender的某個Slot上的Master.ConfigEpoch比自己這裏記錄的小,那麼就會返回UPDATE告訴Sender更新Slots歸屬信息。

下面是兩個規則:

  1. 如果一個Slot不屬於任何Master,然後有一個Master宣稱擁有它,那麼就修改己側的Slots信息把這個Slot關聯到這個Master上。
  2. 如果一個Slot已經歸屬一個Master,然後又有一個Master宣稱擁有它,那麼就看誰的ConfigEpoch大,大的那個贏

Node復活後遇到的問題

Node A有兩個Slot,然後它死了,它被頂替了,等它復活時發現兩個Slot一個被Node B接管,另一個被Node C接管了,那麼它:

  1. 因爲自己的ConfigEpoch已經很舊了,所以它復活後不負責任何Slot
  2. 然後它會成爲最後一個Slot的Master的Slave

Slave遷移算法

Slave遷移時一個自動過程。

舉個例子,現在有Master A、B,它們對應的Slave有A1、B1、B2。現在A死了,A1頂替上去,不過這個時候A1就是一個光棍Master(它沒有Slave),B有富餘的Slave(B1和B2),把其中一個勻給A1當Slave。

這個過程不需要共識,因爲只是修改Slave的歸屬,也不會修改ConfigEpoch。

Slave遷移有兩個規則:

  1. 當有多個Slave富餘時,選擇NodeID字典順最小的那個來遷移
  2. 只有當Master的Slave數量>=cluster-migration-barrier時,纔會挑選它的Slave做Migration

兩個跳過共識修改ConfigEpoch的操作

下面兩個操作比較危險,最好確定一個成功後再執行另一個:

  • CLUSTER_FAILOVER TAKEOVER(手動Failover)直接將一個Slave提升爲Master,不需要大多數Master同意。
  • Slot Migration同樣不需要大多數Master同意。

所以就有可能出現同一個Slot有兩個相同ConfigEpoch的Master宣稱由自己負責,這種衝突的解決算法是:

  • 如果Master A發現Master B也宣稱了對Slot X的主權,並且兩者的ConfigEpoch一樣
  • 如果Master A的NodeID的字典順比Master B的小
  • 那麼Master A就把己側的CurrentEpoch+1,同時ConfigEpoch改成和CurrentEpoch一樣

Node重製

略,見文檔

移除Node

略,見文檔

一些自問自答

Q:ConfigEpoch何時變化?

A:Slave Promotion時、手動Failover時、Slot Migration時

Q:ConfigEpoch怎麼變化?

A:Node->ConfigEpoch = Cluster->CurrentEpoch + 1,結果也就是Cluster->CurrentEpoch加1了。源碼見這裏

Q:兩個Master的ConfigEpoch一樣怎麼辦?

A:這個會出現在兩個Slave同時Promotion時,解決辦法是NodeID字典序比較小的那個會再一次Bump ConfigEpoch,源碼見這裏

Q:ConfigEpoch有什麼用?

A:當有兩個Master宣稱自己擁有同一個/批Slot時,ConfigEpoch大的那個贏,因爲大的那個代表最新信息,其他Node只會採用贏的那方所宣稱的信息。

Q:CurrentEpoch有什麼用?

A:1)用來判定Node所獲得的Cluster信息的新舊。2)當Node要變更ConfigEpoch時派用處。

參考資料

官方文檔:

下面是餓了麼工程師寫的文章,比較透徹:

下面是兩篇阿里工程師的:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章