Zookeeper之领导者选举初始化源码分析

image.png
Zookeeper集群启动配置

1、配置文件
创建三个配置文件conf\zoo_sample.cfg、conf\zoo_sample2.cfg、conf\zoo_sample3.cfg


image.png

只有dataDir和clientPort对应不同的服务端数据存储位置及客户端连接端口


image.png

在dataDir文件夹下需要分别创建myid文件,用来存储server后面的序号1、2、3。(例如server.1=127.0.0.1:12881:13881的1)
image.png

2、三个服务端

QuorumPeerMain对应conf\zoo_sample.cfg启动


image.png

QuorumPeerMain3对应conf\zoo_sample3.cfg启动
image.png

QuorumPeerMain2对应conf\zoo_sample2.cfg启动
3、两个客户端配置
加个 -D:zoocfg=D:\workspase\zookeeper-master\conf\zoo_sample.cfg 对于不同服务端的客户端(对应不同端口)连接
image.png

集群启动

1、isDistributed判断是否以集群方式启动
org.apache.zookeeper.server.quorum.QuorumPeerConfig#isDistributed


image.png

standaloneEnabled=true(默认是false,是非集群)也可以启动
votingMembers参与投票数量大于1,也是集群启动。
可以算出过半值half=1(当以三台启动3/2=1)
2、initializeAndRun初始化集群
org.apache.zookeeper.server.quorum.QuorumPeerMain#initializeAndRun
这里便是根据isDistributed来判断是否以集群启动,与单机启动的区别


image.png

3、runFromConfig
org.apache.zookeeper.server.quorum.QuorumPeerMain#runFromConfig
①、ServerCnxnFactory创建与单机相同
image.png

②、创建quorumPeer对象,并给参数赋值
创建quorumPeer对象,并给参数赋值。从config读取到quorumPeer中,下面是对myid赋值


image.png

③、quorumPeer.start 启动
image.png

initialize 初始化、JvmPauseMonitor赋值、start 启动、join 阻塞
4、QuorumPeer#start
org.apache.zookeeper.server.quorum.QuorumPeer#start
image.png

主要步骤:
①、loadDataBase()加载数据
②、startServerCnxnFactory 用来开启acceptThread、SelectorThread和workerPool线程池
③、开启领导者选举startLeaderElection
④、开启JVM监控线程startJvmPauseMonitor
⑤、调用父类super.start();进行领导者选举

初始化领导者选举相关的线程和队列

1、startLeaderElection


image.png

①、创建当前选票currentVote
②、创建选举方式createElectionAlgorithm
2、createElectionAlgorithm
org.apache.zookeeper.server.quorum.QuorumPeer#createElectionAlgorithm
目前选举方式只有electionAlgorithm=3


image.png

image.png

这个方法创建了以下三个对象:

①、创建QuorumCnxManager对象
②、QuorumCnxManager.Listener
③、FastLeaderElection

1、创建QuorumCnxManager对象

这个类是一个使用TCP实现用于领导者选举的连接管理器类。可以简单理解为一个处理Socket的传输层类
org.apache.zookeeper.server.quorum.QuorumCnxManager#QuorumCnxManager


image.png

创建recvQueue、queueSendMap、senderWorkerMap等属性对象


image.png
2、创建QuorumCnxManager.Listener对象

Listener的创建和启动


image.png

a、run
org.apache.zookeeper.server.quorum.QuorumCnxManager.Listener#run


image.png

b、启动ListenerHandler线程
org.apache.zookeeper.server.quorum.QuorumCnxManager.Listener.ListenerHandler#run
image.png

c、acceptConnections
org.apache.zookeeper.server.quorum.QuorumCnxManager.Listener.ListenerHandler#acceptConnections
开启服务端serverSocket,等待客户端连接。阻塞在serverSocket.accept()方法


image.png
服务端间的连接

当再开一台,则会进行相互连接。阻塞在serverSocket.accept()的方法这里将会继续往下执行。13881和13883端口用来进行领导者选举。
server.1=127.0.0.1:12881:13881
server.3=127.0.0.1:12883:13883


image.png

表示:由sid=1的向sid=3的连接,则会关闭当前sid=1连接的sid=3的socket。sid=3的会向sid=1进行连接
1、acceptConnections
接受连接
org.apache.zookeeper.server.quorum.QuorumCnxManager.Listener.ListenerHandler#acceptConnections


image.png

2、receiveConnection
处理连接
org.apache.zookeeper.server.quorum.QuorumCnxManager#receiveConnection
image.png

3、handleConnection
org.apache.zookeeper.server.quorum.QuorumCnxManager#handleConnection
①、通过网络连接获取数据sid,获取sid表示是那一台连过来的


image.png

②、关闭小的sid向大的sid的socket连接
如果当前sid比连过来的大(sid < self.getId()表示当前sid=3的是服务端),由sid=1的向sid=3的连接,则会关闭当前sid=1连接的sid=3的socket。上图所示。
image.png

③、大的sid与小的sid建立socket连接(服务端是小的sid=1)
关闭sid=1向sid=3的socket后,建立sid=3向sid=1建立连接(即大的sid向小的sid连接)
image.png

4、connectOne 主动建立socket连接
org.apache.zookeeper.server.quorum.QuorumCnxManager#connectOne
image.png

5、initiateConnectionAsync
org.apache.zookeeper.server.quorum.QuorumCnxManager#initiateConnectionAsync
image.png

6、执行QuorumConnectionReqThread线程run方法
org.apache.zookeeper.server.quorum.QuorumCnxManager#initiateConnection
image.png

7、initiateConnection
建立socket连接
org.apache.zookeeper.server.quorum.QuorumCnxManager#initiateConnection


image.png

image.png

8、startConnection
org.apache.zookeeper.server.quorum.QuorumCnxManager#startConnection
image.png

image.png

image.png

开启SendWorker、RecvWorker线程。并把SendWorker与sid放入到senderWorkerMap。创建queueSendMap集合
9、SendWorker#run
org.apache.zookeeper.server.quorum.QuorumCnxManager.SendWorker#run
image.png

image.png

从queueSendMap获取并发送给其他服务
image.png

org.apache.zookeeper.server.quorum.QuorumCnxManager.SendWorker#send
image.png

10、RecvWorker#run
org.apache.zookeeper.server.quorum.QuorumCnxManager.RecvWorker#run
读取并添加到recvQueue
image.png
3、创建FastLeaderElection对象

1、FastLeaderElection
org.apache.zookeeper.server.quorum.FastLeaderElection#FastLeaderElection


image.png

2、starter
org.apache.zookeeper.server.quorum.FastLeaderElection#starter
创建sendqueue、recvqueue队列。Messenger对象


image.png

3、Messenger
org.apache.zookeeper.server.quorum.FastLeaderElection.Messenger#Messenger
创建WorkerSender并封装成wsThread线程,创建WorkerReceiver并封装成wrThread
image.png

4、FastLeaderElection#start
org.apache.zookeeper.server.quorum.FastLeaderElection#start


image.png

5、Messenger#start
org.apache.zookeeper.server.quorum.FastLeaderElection.Messenger#start
image.png

启动WorkerSender和WorkerReceiver
6、WorkerSender#run
org.apache.zookeeper.server.quorum.FastLeaderElection.Messenger.WorkerSender#run
image.png

从sendqueue发送队列取出并处理
org.apache.zookeeper.server.quorum.FastLeaderElection.Messenger.WorkerSender#process
image.png

自己发送给自己选票
image.png

org.apache.zookeeper.server.quorum.QuorumCnxManager#addToRecvQueue
添加到recvQueue


image.png

7、WorkerReceiver#run
org.apache.zookeeper.server.quorum.FastLeaderElection.Messenger.WorkerReceiver#run
从recvQueue获取得到Message response对象
image.png

把发送给其他节点的投票信息封装成ToSend对象放入到sendqueue队列
image.png

image.png

总结:

本章主要分析了领导者选举的初始化。
在初始化过程中,主要创建了三个对象
1、QuorumCnxManager 这个类的创建的作用是创建与Socket底层交互的相关线程和队列
SendWorker和RecvWorker线程,recvQueue队列、queueSendMap和senderWorkerMap集合。
2、QuorumCnxManager.Listener 用来处理领导者选举的服务端的连接
3、FastLeaderElection 快速领导者选举工具类,创建了与领导者选举相关的线程和集合
WorkerSender和WorkerReceiver线程,sendqueue和recvqueue队列

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350