Zookeeper是如何保證順序一致性的

zookeeper架構.jpg

本文適用於對Zookeeper有必定了解且想要了解源碼或正在瞭解源碼的同窗,花費大約五分鐘bash

前幾天看了一個帖子,講Zookeeper的順序一致性,比劃了一通數學解釋,看的雲山霧罩的,在此講下本身對於順序一致性的理解微信

Zookeeper常被用於分佈式協調服務(即服務或元數據註冊等場景,如Dubbo、Kafka:將生產者或元數據信息註冊到Zookeeper集羣上,以便分佈式系統其餘參與者及時看到,由於Zookeeper實現了相似Paxos的Zab協議,解決了分佈式數據一致性問題)、分佈式鎖等用途架構

什麼叫順序一致性:

假設有一個Zookeeper集羣(N>=3,N爲奇數),那麼只有一個Leader(經過FastLeaderElection選主策略選取),全部的寫操做(客戶端請求Leader或Follower的寫操做)都由Leader統一處理,Follower雖然對外提供讀寫,但寫操做會提交到Leader,由Leader和Follower共同保證同一個Follower請求的順序性,Leader會爲每一個請求生成一個zxid(高32位是epoch,用來標識leader選舉週期,每次一個leader被選出來,都會有一個新的epoch,標識當前屬於哪一個leader的統治時期,低32位用於遞增計數)分佈式

針對同一個Follower A提交的寫請求request一、request2,某些Follower雖然可能不能在請求提交成功後當即看到(也就是強一致性),但通過自身與Leader之間的同步後,這些Follower在看到這兩個請求時,必定是先看到request1,而後再看到request2,兩個請求之間不會亂序,即順序一致性ui

zookeeper寫請求流程.png

Leader在處理第4步Follower的ack回覆時,採用過半數響應即成功原則,也就是這時候有的Follower是尚未處理或者處理成功這個請求的spa

那麼問題來了,怎麼保證順序一致性的呢?

  • FollowerRequestProcessor爲Follower的首個處理器,若是是寫請求,先將請求寫入commitprocessor的queuedRequests(方便後續commit時判斷是否本Follower提交的寫請求),而後轉Leader
  • Leader爲每一個請求生成zxid,下發proposal給Follower,Follower會將請求寫入到pendingTxns阻塞隊列及txnLog中,而後發送ack給Leader
public void logRequest(TxnHeader hdr, Record txn) {
    Request request = new Request(hdr.getClientId(), hdr.getCxid(), hdr.getType(), hdr, txn, hdr.getZxid());
    if ((request.zxid & 0xffffffffL) != 0) {
        pendingTxns.add(request);
    }
    syncProcessor.processRequest(request);
}
複製代碼

proposal這步是會發給全部的follower的(放到LearnerHandler的請求處理隊列中,一個Follower一個LearnerHandler),以後Follower的ack就不必定全返回了code

  • ack過半,Leader發送commit請求給全部Follower,Follower對比commit request的zxid和前面提到的pendingTxns的zxid,不一致的話Follower退出,從新跟Leader同步
long firstElementZxid = pendingTxns.element().zxid;
if (firstElementZxid != zxid) {
    LOG.error("Committing zxid 0x" + Long.toHexString(zxid)
        + " but next pending txn 0x"
        + Long.toHexString(firstElementZxid));
    System.exit(12);
}
複製代碼
  • Follower處理commit請求,若是不是本Follower提交的寫請求,直接調用FinalRequestProcessor作持久化,觸發watches;若是是本Follower提交,則作一些特殊處理(主要針對客戶端鏈接斷開的場景),而後調用FinalRequestProcessor等後續處理流程
  • FinalRequestProcessor作持久化,返回客戶端

總之:Follower經過隊列和zxid等順序標識保證請求的順序處理,一言不合就會退出或者從新同步Leadercdn

歡迎關注個人微信公衆號

68號小喇叭
相關文章
相關標籤/搜索