ZooKeeper集群中的跟隨者對客戶端請求的處理流程解讀(一)
在ZooKeeper中QuorumPeer這個類是整個集群的抽象,代表著ZooKeeper的整個集群、其關聯著ZooKeeper集群的重要信息,包括集群狀態、當前ZK節點的狀態、當前ZK節點編號(myid)、數據存儲實例(ZKDATABASE)等等。同時QuorumPeer擴展了Thread類,因此在ZooKeeper運行的過程中,QuorumPeer實例是以獨立的線程方式運行的。
QuorumPeer線程實例會在主程序體里面循環判斷當前集群的狀態,這包括下面幾種狀態:LOOKING(集群正在處于領導者選舉的狀態)、LEADING(當前節點處于領導者的狀態)、 FOLLOWING(當前節點處于跟隨者的狀態)、OBSERVING(當前節點處于觀察者的狀態)。
本文主要是介紹跟隨者對客戶端請求處理鏈的解讀,因此我們在這里只關心當前節點處于跟隨者狀態的時候的程序入口。看下code:
case FOLLOWING: try { LOG.info("FOLLOWING"); setFollower(makeFollower(logFactory)); follower.followLeader(); } catch (Exception e) { LOG.warn("Unexpected exception",e); } finally { follower.shutdown(); setFollower(null); setPeerState(ServerState.LOOKING); } break;
當ZooKeeper集群結束領導者選舉狀態之后,如果當前節點判斷選舉結束當前節點沒有被選中,而只能充當跟隨者的時候,程序進入上邊這個分支,ZooKeepr集群開始構造跟隨者實例,即makeFollower方法。makeFollower方法做的事情是根據FollowerZooKeeperServer實例、日志工廠實例和 ZooKeeper的數據存儲實例來構造Follower實例,并把Follower實例傳遞給當前集群QuorumPeer的follower屬性來進行關聯。
protected Follower makeFollower(FileTxnSnapLog logFactory) throws IOException { return new Follower(this, new FollowerZooKeeperServer(logFactory, this,new ZooKeeperServer.BasicDataTreeBuilder(), this.zkDb)); }
跟隨者實例構造完成之后就進入了 followLeader階段,也就是跟隨領導者的階段,followLeader方法是Follower接口定義的行為。先簡單描述一下 followLeader要做的事情:首先建立和領導者的連接,向領導者同步數據,這里跟隨者對領導者的通信數據處理方法主要是 processPacket。然而發現這里的code和客戶端的請求并沒有毛的關系,那么跟隨者對客戶端開放的服務哪里去了呢?還記得上面構造跟隨者傳入的FollowerZooKeeperServer實例嗎。
首先看看syncWithLeader這個方法,表面上它是和領導者同步數據的意思,事實上它偷偷的做了很多事情。
首先從領導者讀取一個數據包,這個包可能是下面幾種類型的命令:
DIFF:領導者發起DIFF命令
SNAP:領導者發起的SNAP命令,跟隨者接收到這個命令后會清空本地的ZK數據庫,同步領導者的數據。
TRUNC:領導者發起的TRUNC命令,跟隨者接收到這個命令之后會根據本地的日志截斷數據,到領導者的最新數據處。
完了之后跟隨者將zxid設置為領導者相同的zxid,然后建立會話跟蹤。
接下來跟隨者開始接收領導者其他命令,包括PROPOSAL、COMMIT、UPTODATE、INFORM和NEWLEADER,這也是跟隨者和領導者同步的過程中要做的事情。
PROPOSAL:跟隨者接收到PROPOSAL命令的時候會將領導者的提議放入未提交“口袋”。
COMMIT:命令會使得跟隨者提交之前未提交的提議,當然需要發生在跟隨者和領導者同步鏡像數據之后,否則還是將提議放入未提交的口袋,UPTODATE表示跟隨者和領導者已經同步數據完成,開始進入新的階段。
INFORM:這個跟觀察者相關的,這里先不介紹。
UPTODATE:表示領導者已經和跟隨者同步完成、跟隨者可以開始接客。。。
NEWLEADER:表示要換領導者了、開啟新的時代。
UPTODATE完了之后跟隨者會處理未提交和需要提交的提議,未提交的提議需要記錄日志等待領導者的COMMIT命令,需要提交的提議跟隨者將他寫入ZKDatabase。
接下來跟隨者要做的事主要是保持和領導者的通信和對客戶端請求的接受和處理,下篇文章主再繼續介紹跟隨者對客戶端請求的處理流程。
來自:http://jvmplus.duapp.com/