天天看點

Zookeeper叢集選舉機制以及資料同步機制

Zookeeper叢集選舉機制以及資料同步機制

每天多學一點點~

話不多說,這就開始吧…進擊的爆裂無球~

文章目錄

    • Zookeeper叢集選舉機制以及資料同步機制
    • 1.前文
    • 2.Zookeeper的選舉機制
    • 3.Zookeeper的資料同步機制
    • 4.關于Zookeeper的一些面試題
    • 5.結語

1.前文

國慶快樂,舉國同慶~

之前寫過zookeeper的叢集搭建以及

Zookeeper的選舉及運維可視化檢視器及容災,因有點時間沒用Zookeeper,最近又深入學習了一下,研究研究它的選舉機制和資料同步機制,以便以後複習用~

2.Zookeeper的選舉機制

Zookeeper叢集選舉機制以及資料同步機制

投票機制說明:

選舉分5個步驟:

  1. 初始化leader選舉,投票

    給自己投票 myid zxid 0

  2. 每個伺服器接受投票

    (1 0) (2,0) (3,0) >myid 誰最大誰就是leader

  3. 處理投票

    别的伺服器 pk

  4. 統計投票
  5. 過半票數n=n/2+1;

    伺服器狀态變更

    Leader,其他票數低 f

依次啟動三個zk,發現192.168.73.132是leader,其餘兩個是follower,這是因為

1: 三個伺服器的myid分别是 1 2 3

2: 滿足過半統計,即一共三個,啟動第二個時候已經滿足過半,是以第二個自動是leader

若反過來啟動,即 按照 133-132-131的順序,則133是leader,因為 133的myid最大,且啟動132時候已經滿足過半,是以133是leader

選舉觸發:

那麼何時才會觸發選舉呢?

  1. 服務節點初始化啟動
  2. 半數以上的節點無法和Leader建立連接配接

當節點初始起動時會在叢集中尋找Leader節點,如果找到則與Leader建立連接配接,其自身狀态變化follower或observer。如果沒有找到Leader,目前節點狀态将變化LOOKING,進入選舉流程。

在叢集運作其間如果有follower或observer節點當機隻要不超過半數并不會影響整個叢集服務的正常運作。但如果leader當機,将暫停對外服務,所有follower将進入LOOKING 狀态,進入選舉流程。

3.Zookeeper的資料同步機制

Zookeeper 的資料同步是為了保證各節點中資料的一緻性,同步時涉及兩個流程,一個是正常的用戶端資料送出,另一個是叢集某個節點當機在恢複後的資料同步。

  • 用戶端寫入請求:

    寫入請求的大至流程是,收leader接收用戶端寫請求,并同步給各個子節點。如下圖:

    Zookeeper叢集選舉機制以及資料同步機制
    但實際情況要複雜的多,比如 client 它并不知道哪個節點是leader ,有可能寫的請求會發給follower ,由follower在轉發給leader進行同步處理
    Zookeeper叢集選舉機制以及資料同步機制
    用戶端寫入流程說明:
  1. client向zk中的server發送寫請求,如果該server不是leader,則會将該寫請求轉發給leader server,leader将請求事務以proposal形式分發給follower;
  2. 當follower收到收到leader的proposal時,根據接收的先後順序處理proposal;
  3. 當Leader收到follower針對某個proposal過半的ack後,則發起事務送出,重新發起一個commit的proposal
  4. Follower收到commit的proposal後,記錄事務送出,并把資料更新到記憶體資料庫;
  5. 當寫成功後,回報給client。
  • 服務節點初始化同步:

    在叢集運作過程當中如果有一個follower節點當機,由于當機節點沒過半,叢集仍然能正常服務。當leader 收到新的用戶端請求,此時無法同步給當機的節點。造成資料不一緻。為了解決這個問題,當節點啟動時,第一件事情就是找目前的Leader,比對資料是否一緻。不一緻則開始同步,同步完成之後在進行對外提供服務。

    如何比對Leader的資料版本呢,這裡通過ZXID(事物ID)來确認。比Leader就需要同步。

    ZXID說明:

    ZXID是一個長度64位的數字,其中低32位是按照數字遞增,任何資料的變更都會導緻,低32位的數字簡單加1。高32位是leader周期編号,每當選舉出一個新的leader時,新的leader就從本地事物日志中取出ZXID,然後解析出高32位的周期編号,進行加1,再将低32位的全部設定為0。這樣就保證了每次新選舉的leader後,保證了ZXID的唯一性而且是保證遞增的。

    可以用運維四字指令檢視,之前文章中也說過

    echo stat|nc 127.0.0.1:2181

    比如 :0x200000002 是目前的zxid,當leader變化時,高32變化,變成0x3 ,+1

    當資料變化時候,低32變化 +1 變成00000003

4.關于Zookeeper的一些面試題

  1. 如果leader 節點當機,在恢複後它還能被選為leader嗎?

    不能,因為會重新選舉(選舉期間暫停對外服務,直到新的leader産生),然後再次加進來,原來的leader會跟新的leader進行資料同步,變成follwer

  2. 現在有三個節點, zk1,zk2,zk3, zk2是leader,zk2挂了的同時在zk1進行了delete操作,現在把zk1 和 zk3也挂掉,再把三個節點全部起來,那麼現在zk2還是leader嘛?

    不是。 因為你leader挂了之後,就會選舉出新的leader(zk3),此時你在zk1中更新的資料(delete了一條資料)此時zk1和zk3的zxid是一緻的,已經同步呢!

    (你老的leader(zk2)中的資料不是最新的,怎麼好意思再給follower同步資料呢!)

    現在你又把zk1和zk3挂掉,再重新開機zk1,zk2,zk3,此時的選舉,不再是一開始根據myid誰大誰就是leader,而是基于zxid(節點的事物ID)誰大誰就是leader,因為zk1更新了資料,此時它的zxid是最大的,是以啟動後zk1是leader

    最後叢集狀态一緻的話,整個叢集的zxid都會一樣

5.結語

世上無難事,隻怕有心人,每天積累一點點,fighting!!!

繼續閱讀