Zookeeper選舉Leader源碼剖析
leader選舉流程
參數說明
- myid: 節點的唯一標識,手動設置
- zxid: 當前節點中最大(新)的事務id
- epoch-logic-clock: 同一輪投票過程中的邏輯時鐘值相同,每投完一次值會增加
leader選舉流程
- 默認投票給自己,優先選擇zxid大的為leader,因為zxid大的節點數據是最新的(理論上事務id越大,說明數據量越多也就意味著比較新),如果zxid一致,那么會選擇myid大的為leader,當節點選票過半則選舉成功
leader選舉核心步驟
-
源碼大致流程
-
初始化netty通信,客戶端發送命令立刻監聽到
-
初始化內存數據庫對象、初始化服務連接工廠等一些信息
- 啟動服務節點
- 加載文件數據到內存
- 啟動netty服務
- 初始化集群選舉leader
- 啟動一個線程進行選舉監聽
- 監聽到選票,將選票丟到recvQueue隊列中
- 啟動服務節點
-
啟動接收選票線程、發送選票線程進行監聽,都去隊列中接受和發送選票
-
啟動QuorumPeer線程執行run方法,根據節點狀態判斷
- leading: socket監聽follower節點,初始化LeaerZookeeperServer數據,同步數據到從節點,定時ping到follower節點請求保持長連接
- follower: 與leader建立發送socket連接,注冊自己到leader、同步leader數據、自旋接收leader同步數據,如果leader宕了,在finally中將自己的狀態改為looking,進入下一輪自旋選舉
- looking: 節點啟動后的默認狀態,選舉周期+1,初始化選票,默認選自己,發送選票到sendQueue隊列,同時還會不斷地從recvQueue隊列拿選票進行選舉
- leading: socket監聽follower節點,初始化LeaerZookeeperServer數據,同步數據到從節點,定時ping到follower節點請求保持長連接
-
-
問題
: ZK的選舉機制為什么存在大量自旋,如同步節點數據、選舉流程,如果長時間運行會不會導致CPU資源損耗過大- 對于長時間自旋毋庸置疑肯定會導致CPU資源緊張,但是想達到動態監聽數據變化就得犧牲一定的CPU性能,并且這樣也能保證數據的強一致性,也能保證節點選舉的實時性
- 倘若想要優化ZK,可以引入Redis/MQ基于發布/訂閱模式進行處理,但是這樣會造成引入三方中間件導致復雜度提升