Zookeeper與Redis哨兵

Redis選舉領頭Sentinel

Sentinel是Redis實現高可用的保證。Sentinel系統作用就是監視Redis服務器集羣,它可以不停的獲得redis集羣狀態,當一個主節點掛了,故障轉移操作會在從節點中選出一個新的主節點,這裏故障轉移就是由Sentinel來主導完成的。

不要把Sentinel想的太複雜,它其實就是一個特殊工作模式的Redis服務器而已,Redis是集羣部署的,這裏的Sentinel也是要集羣部署的,要是非單點部署,你的Sentinel掛了,此時的Redis集羣就GG了。

接着上邊說,當主服務器節點掛了,Sentinel系統就會選出一個領頭的Sentinel來完成故障轉移工作。選舉規則如下: - 監視這個掛了的主節點的所有Sentinel都有被選舉爲領頭的資格

  • 每進行一次選舉,不論是否成功,配置紀元+1,配置紀元就是個計數器
  • 每個Sentinel在每個配置紀元中有且僅有一次選舉機會,一旦選好了該節點認爲的主節點,在這個紀元內,不可以再更改
  • 每個發現服務器掛了的Sentinel都會配置紀元+1並投自己一票,接着發消息要求其他Sentinel設置自己爲領頭人1,每個Sentinel都想成爲領頭的
  • 每個Sentinel會將最先發來請求領頭的節點設爲自己的領頭節點併發送回復,誰先來我選誰
  • 當源Sentinel收到回覆,並且回覆中的配置紀元和自己的一致且領頭Id是自己的Sentinel Id時,表明目標Sentinel已經將自己設爲領頭
  • 在一個配置紀元內,當某個Sentinel收到半數以上的同意回覆時,它就是領頭的了
  • 如果在給定時間內,沒有被成功選舉的Sentinel,那麼過段時間發起新的選舉

選舉領頭Sentinel的過程和規則大概就如上所述,需要注意的是隻有集羣出現節點掛了才需要選舉出領頭Sentinel,平時每個Sentinel還是平等身份~

這裏的選舉其實是raft算法的一個應用,有興趣的小夥伴可以去讀下這篇算法的論文

Zookeeper選舉

Zookeeper是一個很強的分佈式數據一致性解決方案,比如dubbo中的註冊中心就使用的Zookeeper。當然,這也是集羣部署的,但是它沒有采用傳統的Master/Slave結構,而是引入了Leader、Follwer和Observer。Leader和Follower類似於Master/Slave,新增的Observer作用僅僅只是增加集羣的讀性能,它不參與Leader的選舉。

節點的狀態有以下幾種:

  • LOOKING: 節點正處於選主狀態,不對外提供服務,直至選主結束;
  • FOLLOWING: 作爲系統的從節點,接受主節點的更新並寫入本地日誌;
  • LEADING: 作爲系統主節點,接受客戶端更新,寫入本地日誌並複製到從節點

Zookeeper的狀態同步是基於Zab協議實現的,Zab協議有兩種模式,它們分別是崩潰恢復(選主)和消息廣播(同步)。當服務啓動或者在Leader崩潰後,Zab就進入了恢復模式,當Leader被選舉出來,且超過一半機器完成了和 leader的狀態同步以後,恢復模式就結束了。

我們來重點看下選主是怎麼完成的

首先明確幾個概念: - Sid:服務器id;

  • Zxid:服務器的事務id,數據越新,zxid越大;zxid的高32位是epoch,低32位是zpoch內的自增id,由0開始。每次選出新的Leader,epoch會遞增,同時zxid的低32位清0。

整個選主流程如下

  1. 狀態變更。服務器啓動的時候每個server的狀態時Looking,如果是leader掛掉後進入選舉,那麼餘下的非Observer的Server就會將自己的服務器狀態變更爲Looking,然後開始進入Leader的選舉狀態;
  2. 發起投票。每個server會產生一個(sid,zxid)的投票,系統初始化的時候zxid都是0,如果是運行期間,每個server的zxid可能都不同,這取決於最後一次更新的數據。將投票發送給集羣中的所有機器;
  3. 接收並檢查投票。server收到投票後,會先檢查是否是本輪投票,是否來自looking狀態的server;
  4. 處理投票。對自己的投票和接收到的投票進行PK:
先檢查zxid,較大的優先爲leader;如果zxid一樣,sid較大的爲leader;根據PK結果更新自己的投票,再次發送自己的投票
  1. 統計投票。每次投票後,服務器統計投票信息,如果有過半機器接收到相同的投票,那麼leader產生,如果否,那麼進行下一輪投票;
  2. 改變server狀態。一旦確定了Leader,server會更新自己的狀態爲Following或者是Leading。選舉結束。

我們要保證選主完成後,原來的主節點已經提交的事務繼續完成提交;原主節點只是提出而沒提交的事務要拋棄。這也是爲什麼傾向於選zxid最大的從節點爲主節點,因爲它上邊的事務最新,最與原主節點保持一致。

總結

  1. Redis中的Sentinel選主相對來說更簡單,因爲不涉及事務狀態的一致性
  2. Sentinel選主是基於raft協議,Zookeeper則基於Zab協議
  3. 二者都是收到半數的選票就選舉成功
  4. Sentinel投票發消息主要內容是Sentinel id和配置紀元,Zookeeper則是 zxid和 sid
  5. Sentinel誰先來找他投票他就投誰,Zookeeper中則是要細細檢查比較一番,檢查內容包括epoch和節點狀態,檢查完畢後再跟自己的投票進行pk,進而看需不需要更新自己的投票,若是需要,則自己的投票也要廣播出去
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章