Redis 基本切換原理

2018-08-03 11:45 更新

在切換中,配置文件是會被動態(tài)修改的,例如當發(fā)生主備切換時候,配置文件中的master會被修改為另外一個slave。這樣,之后sentinel如果重啟時,就可以根據(jù)這個配置來恢復(fù)其之前所監(jiān)控的redis集群的狀態(tài)。 在sentinel切換過程中有三大步驟:

  1. 判斷是否下線(老主是否真的咽氣駕崩) 每個sentinel在監(jiān)控的時候,每秒對主進行一次ping命令,如果多次ping的響應(yīng)時間超過了配置文件中的down-after-milliseconds,那么這個哨兵就會認為被監(jiān)控的實例是SDown狀態(tài)(Subjectively Down,主觀down,SDOWN)。 這個時候此sentinel會判斷此master是否真的掛了——即可以設(shè)置成ODOWN(Objectively Down,客觀down,ODOWN)。設(shè)置成ODOWN的條件是除了當前sentinel認為此master SDOWN,還必須有其他sentinel認為此master SDOWN,當認為SDOWN的sentinel的個數(shù)等于或超過配置文件中monitor master最后的那個參數(shù)quorum后,就sentinel就會認為此master是ODOWN。 被標記為ODOWN的另一個效應(yīng)是:在一般情況下,每個 Sentinel 進程會以每 10 秒一次的頻率向它已知的所有主實例和從實例發(fā)送 INFO 命令。 當一個主實例被 Sentinel實例標記為客觀下線時, Sentinel 向ODOWN Master的所有從實例發(fā)送 INFO 命令的頻率會從 10 秒一次改為每秒一次。
  2. 進行投票選舉主持切換的sentinel(選舉一個長老,由它來欽點新帝王) 當master被認為是ODOWN的時候,可能需要進行failover,但是并不是odown了就可以執(zhí)行failover,因為可能有多個sentinel都認為master是odown了,這時候就需要選舉一個sentiel來執(zhí)行failover。也就是說切換之前要先選舉一個sentinel來主持切換,條件是必須有>=max(quorum, num(sentinels)/2 +1)的sentinel都同意某一個sentinel主持failover,那么這個sentinel就可以主持failover,超過半數(shù)這個條件就能限制住此時刻只有一個sentinel來操作。 這個也是通過is-master-down-by-addr消息進行更新每個sentinel的選舉的leader。每個sentinel都有一個epoch,這個東西相當于一個時間戳,是遞增的值,如果集群正常的話,所有的sentinel的這個值都是一樣的。當master出現(xiàn)異常后,每個sentinel后自增這個值,如果一直沒有選舉出來leader的話,這個值會跟隨這time event的輪詢,每次加一,在設(shè)定的故障遷移超時時間的兩倍之后, 重新嘗試當選。同時is-master-down-by-addr會把這個值發(fā)送到其他的sentinel,其他的sentinel收到這個消息后,會判斷自己的epoch和消息中的epoch,如果自己的epoch小于消息中的epoch,那么其他的sentinel就會選舉傳遞消息的這個sentinel。最終會大部分sentinel都同意一個較大的epoch的sentinel主持failover。
  3. 進行切換,并其他實例同步新Master(新帝王登基,其余藩王宣誓效忠新帝王) 這個主持切換的sentinel選出一個從redis實例,并將它升級為Master。首先是要下面的條件按照如下條件篩選備選node: 1) slave節(jié)點狀態(tài)處于S_DOWN,O_DOWN,DISCONNECTED的除外 2) 最近一次ping應(yīng)答時間不超過5倍ping的間隔(假如ping的間隔為1秒,則最近一次應(yīng)答延遲不應(yīng)超過5秒,redis sentinel默認為1秒) 3) info_refresh應(yīng)答不超過3倍info_refresh的間隔(原理同2,redis sentinel默認為10秒) 4) slave節(jié)點與master節(jié)點失去聯(lián)系的時間不能超過( (now - master->s_down_since_time) + (master->down_after_period * 10))??傮w意思是說,slave節(jié)點與master同步太不及時的(比如新啟動的節(jié)點),不應(yīng)該參與被選舉。 5) Slave priority不等于0(這個是在配置文件中指定,默認配置為100)。

然后再從備選node中,按照如下順序選擇新的master 1) 較低的slave_priority(這個是在配置文件中指定,默認配置為100) 2) 較大的replication offset(每個slave在與master同步后offset自動增加) 3) 較小的runid(每個redis實例,都會有一個runid,通常是一個40位的隨機字符串,在redis啟動時設(shè)置,重復(fù)概率非常?。?4) 如果以上條件都不足以區(qū)別出唯一的節(jié)點,則會看哪個slave節(jié)點處理之前master發(fā)送的command多,就選誰。 主持切換的sentinel向被選中的從redis實例發(fā)送 SLAVEOF NO ONE 命令,讓它轉(zhuǎn)變?yōu)镸aster。然后通過發(fā)布與訂閱功能,將更新后的配置傳播給所有其他 Sentinel,其他 Sentinel 對它們自己的配置進行config-rewrite。隨后sentinel向已下線的Master的從服務(wù)器發(fā)送SLAVEOF命令,讓它們?nèi)?fù)制新Master。

注意:sentinel failover-timeout這個選項有四個含義,有必要在此翻譯一下 1) 對于一個sentinel選出的同一個master進行再次的failover嘗試所需要的時間——這個參數(shù)值的兩倍。 2) 當sentinel發(fā)現(xiàn)一個slave錯誤的復(fù)制了一個錯的主時sentinel會強迫其復(fù)制正確的主的時間。 3) 取消一個已經(jīng)開始但是還沒有引起任何配置改變的failover所需要的時間。 4) 等待所有slave被重新配置為新主的slave而所需要的最大時間。注意即使超過了這個時間sentinel也會最終配置slave去同步最新的master


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號