1、啟動或leader宕機選舉流程
2、客戶端與服務端互動流程(NIO或Netty)
3、寫入資料的ZAB一致性協議(如何保證訊息的順序性)
4、Watch監聽觸發機制
一、從原始碼啟動zookeeper
1、啟動單機zookeeper
zookeeper原始碼下載地址,選擇分支3.5.8:
https://github.com/apache/zookeeper.git

原始碼匯入idea后,如果org.apache.zookeeper.Version類會報錯,需要建一個輔助類:
package org.apache.zookeeper.version;
public interface Info {
int MAJOR = 1;
int MINOR = 0;
int MICRO = 0;
String QUALIFIER = null;
int REVISION = -1;
String REVISION_HASH = "1";
String BUILD_DATE = "2020-10-15";
}
我本地的并沒有報錯,所以我并沒有添加這個類!!!
然后在根目錄編譯執行:
mvn clean install -DskipTests
開源專案找入口類一般都是從啟動腳本去找,可以從bin目錄下的zkServer.sh或zkServer.cmd里找到啟動主類運行即可:

org.apache.zookeeper.server.quorum.QuorumPeerMain
注意:
1、將conf檔案夾里的zoo_sample.cfg檔案復制一份改名為zoo.cfg,將zoo.cfg檔案位置配置到啟動引數里

“-Dzookeeper.serverCnxnFactory=org.apache.zookeeper.server.NettyServerCnxFactory”

2、啟動之前需要先將zookeeper-server專案里pom.xml檔案里依賴的包(除了jline)的scope為provided這一行全部注釋掉
3、將conf檔案夾里的log4j.properties檔案復制一份到zookeeper-server專案的 \target\classes 目錄下,這樣專案啟動時才會列印日志
設定完成后我們啟動類QuorumPeerMain:

可以看到ZK已經啟動成功了,
用客戶端命令連接原始碼啟動的server:
// 默認連接到本機2181埠
bin/zkCli.sh
// 或者
bin/zkCli.sh -server localhost:2181
// 或者使用具體的IP埠
bin/zkCli.sh -server 192.168.50.190:2181

也可以從原始碼里運行客戶端(org.apache.zookeeper.ZooKeeperMain),注意需要加入啟動引數,見下圖:
-server localhost:2181


2、從原始碼啟動zookeeper集群
復制3個zoo.cfg檔案,修改對應集群配置.,并創建data/data\zookeeper1、data\zookeeper2、data\zookeeper3三個檔案夾來保存資料,
下面是zoo1.cfg的實體配置:
# The number of milliseconds of each tick
tickTime=2000
# The number of ticks that the initial
# synchronization phase can take
initLimit=10
# The number of ticks that can pass between
# sending a request and getting an acknowledgement
syncLimit=5
# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just
# example sakes.
dataDir=D:/Git_Repository/zookeeper/data/zookeeper1
# the port at which the clients will connect
clientPort=2181
# the maximum number of client connections.
# increase this if you need to handle more clients
#maxClientCnxns=60
#
# Be sure to read the maintenance section of the
# administrator guide before turning on autopurge.
#
# http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
#
# The number of snapshots to retain in dataDir
#autopurge.snapRetainCount=3
# Purge task interval in hours
# Set to "0" to disable auto purge feature
#autopurge.purgeInterval=1
server.1=127.0.0.1:2001:3001
server.2=127.0.0.1:2002:3002
server.3=127.0.0.1:2003:3003
注意這個dataDir的路徑中的’/’,不是’’,否則可能回報錯: myid is missing,
然后需要在zookeeper1、zookeeper2、zookeeper3下分別創建一個名稱為myid的檔案并填入機器id,內容分別為1,2, 3,

并創建三個不同配置的啟動節點,見下圖:

分別運行每個節點,集群啟動完畢!2181是leader, 2182和2183是follower節點,



二、啟動或leader宕機選舉leader流程
1、流程梳理

muid是機器碼,ZXID是最大的事務ID,
第一輪投票
每臺機器第一次投票都是投給自己,
優先選擇ZXID大的為leader,因為ZXID大的機器包含的資料是最新的,
如果AXID一樣大,默認選myid大的為leader,
注意,集群機器的數量是按照組態檔中配置的個數決定的,并不是服務啟動的個數!
第二輪投票
第二次選舉的時候,每一個機器都會將自己上一輪中認為是leader的票繼續投出去,
myid為1的機器投出去是(2,0,收到也是(2,0);myid為2的發出去(2,0),收到也是(2,0), 此時(2, 0)得票數為2,超過半數,則myid為2的機器成為leader,
myid為3的機器加入進來,發現已經存在leader了,自己就設定為follower節點,
2、原始碼分析
我們首先來從啟動類QuorumPeerMain來看:
public static void main(String[] args) {
QuorumPeerMain main = new QuorumPeerMain();
try {
main.initializeAndRun(args);
} catch (IllegalArgumentException e) {
.........
我們重點關注initializeAndRun這方法即可:
在這里插入代碼片
三、leader選舉多層佇列架構
整個zookeeper選舉底層可以分為選舉應用層和訊息傳輸層,應用層有自己的佇列統一接收和發送選票,傳輸層也設計了自己的佇列,但是按發送的機器分了佇列,避免給每臺機器發送訊息時相互影響,比如某臺機器如果出問題發送不成功則不會影響對正常機器的訊息發送,

四、Leader選舉原始碼流程圖

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/289208.html
標籤:其他
