zookeeper - 主从通信(3)

概述

    在讲清楚了《zookeeper选举》的过程之后,突然有个疑问那就是既然完成了选举了,那么zookeeper集群中各个角色将会如何进入工作,以及如何应对leader退出重新发起选举呢?然后就继续阅读才有了这篇博文。

    这篇博文主要想讲清楚的几个问题是:1、选举结束后leader的任务;2、选举结束后follower和observer的任务;3、leader和follower之间的交互;4、如何发起重新选举。其实我们知道在zookeeper集群当中选举和通信的两个通信是通过不同的端口去实现的,所以这里介绍的通信是另外一个端口的事情。

    加插一句,其实看源码有时候你跳出代码的细枝末节而直接问自己关键问题,无非就那几个核心的知识点,只要把这几个知识点在源代码中得到印证并串联起来,那么整个系统就打通了。当然,看源代码切记不要着急,因为肯定有一些地方是你忽略,宏观上正常运转的逻辑在代码层面肯定是可以找到的,所以只要耐心读下去和分析就可以了,当然毕竟很多源码已经出来了很久了,已经很多前人已经阅读了,可以在他们的肩膀上继续你的理解。


基础知识

    在讲解正式内容之前需要把zookeeper集群中的各个角色分清楚,这样能够更加方便的理解。我们之前将的选举无非就是为了区分出leader、follower、observer三种角色,各个角色的作用如下:

Leader

        Leader服务器是整个zookeeper集群工作机制中的核心,其主要工作有以下两个:

        事物请求的唯一调度和处理者,保证集群事务处理的顺序性。

        集群内部各个服务器的调度者。

Follower

        从角色名字可以看出,Follower服务器是zookeeper集群状态的跟随者,其主要工作有以下三个:

        处理客户端非事物请求,转发事物请求给Leader服务器。

        参与事务请求Proposal的投票。

        参与Leader选举投票。

Observer

        和Follower唯一的区别在于,Observer不参与任何形式的投票,包括事物请求Proposal的投票和Leader选举投票。简单地讲,Observer服务器只提供非事物服务,通常用于在不影响集群事务处理能力的前提下提升集群的非事物处理能力。


zookeeper - 主从通信(3)_第1张图片
核心逻辑

    在QuorumPeer的主循环当中,可以看到不同角色的处理逻辑,所以如果从阅读源码的角度出发,这里就是最好的入口了,我们要讲的leader、follower、observer等角色任务也是直接从这里可以跟进去发现的。


leader的任务

    leader的主要任务主要是两个,负责响应client的连接以及请求,响应follower的连接以及请求。因为前者涉及到数据的读写任务所以暂时没来得及分析,主要着重讲解后者。先把步骤写清楚,最后以源码截图来表述整个过程

    leader的过程

        1、启动follower的acceptor线程负责接收follower的连接(肯定会有follower来连接,因为前面的选举过程中zk集群的所有节点其实已经启动了)。

        2、针对accept后的follower的socket后建立一个单独的线程负责与follower进行通信。

        3、启动zookeeper的server端,主要用于监听client的连接。

        4、进入while循环后不停的发送ping包


    leader过程源码        

zookeeper - 主从通信(3)_第2张图片
leader过程-1

    1、负责启动acceptor线程接收follower的连接


zookeeper - 主从通信(3)_第3张图片
leader-2

    1、判断是否超过半数的follower进行连接了,这个有个知识点比较绕,就是如果没有超过半数我们就会通过connectingFollowers.wait进行等待,那么是谁帮忙唤醒的呢?其实是针对每个follower连接我们会新建一个线程进行处理,在这个处理过程中我们会去判断是否达到半数从而唤醒这个主线程的wait。


zookeeper - 主从通信(3)_第4张图片
leader-3

1、针对每个连接创建的一个创建一个线程,然后在线程里面负责和client进行通信。


zookeeper - 主从通信(3)_第5张图片
leader-4

1、每个与client通信的线程中都会尝试去唤醒leader的线程,其实可以看出来getEpochToPropose调用的是同一个方法,也就是说会执行notifyAll。这样就可以唤醒leader的等待线程。


zookeeper - 主从通信(3)_第6张图片
leader-5

1、负责和follower进行交互的逻辑。


zookeeper - 主从通信(3)_第7张图片
leader-6

1、主线程不停和follower进行通信。


follower&observer任务

    follower(observer)的角色就是跟leader不停的通信,然后如果通信失败那么就退出进行重新选举过程。当然follower还负责接收leader的命令执行相应的操作。整个follower的启动过程如下:

    1、follower向leader发起连接

    2、连接建议后进行for循环负责处理leader的命令。


源码分析

zookeeper - 主从通信(3)_第8张图片
follower-1

1、负责连接leader并处理leader发送的报文


zookeeper - 主从通信(3)_第9张图片
follower-2

1、主动连接leader并取得输入输出流进行交互。


zookeeper - 主从通信(3)_第10张图片
follower-3

1、处理leader发送过来的命令的逻辑


follower&leader交互

    这部分主要是讲解清楚leader和follower在建立连接过程中的交互,直接用时序图来说明,同时将交互之间的报文格式一并贴出来。


zookeeper - 主从通信(3)_第11张图片
交互过程

1、follower向leader发起连接

2、follower发送FOLLOWERINFO报文

3、leader回复LEADERINFO报文

4、follower发送ACKEPOCH报文

5、follower和leader各自继续执行各自逻辑

6、报文格式请参考《zookeeper-服务器角色介绍》


源码分析

zookeeper - 主从通信(3)_第12张图片
follower-1

核心点在于发起连接和进行连接注册



zookeeper - 主从通信(3)_第13张图片
follower-2

1、发起连接动作



zookeeper - 主从通信(3)_第14张图片
follower-3

1、发送FollowerInfo报文

2、处理LeaderInfo报文

3、发送AckEpoch报文



zookeeper - 主从通信(3)_第15张图片
server-1


zookeeper - 主从通信(3)_第16张图片
server-2


参考文献

    Zookeeper源码分析之六 Leader/Follower初始化

    zookeeper-服务器角色介绍

你可能感兴趣的:(zookeeper - 主从通信(3))