【ZooKeeper】zookeeper源码3-网络通信机制


重点1:Leader,Follower,Observer内部都有一个专门对用户提供服务的服务端,有NIO和Netty两种实现,默认是NIO
重点2:Leader,Follower内部都有一个BIO的客户端和服务端,专门用来举行选举,合法链接是myid小的服务器相对myid大的服务器是客户端
重点3:Leader内部有一个专门用来做同步的BIO服务端,Follower和Observer的内部有一个BIO的客户端
重点4:Observer内部有选举的客户端和服务端,但是发送的选票不被处理,同时接收到选票也不做处理
重点5:如果这个Server的myid比另一个Server的myid小,则先关闭连接,然后对方发起请求跟这个建立连接,这个连接就是合法的;myid大的作为客户端,myid小的作为服务端

三种网络通信

在ZooKeeper内部有三套网络通信机制:选举,同步,CS通信

  • 选举过程中的网络通信:BIO 通信实现
    • 服务端:相对来说 ID 大的是客户端
    • 客户端:相对来说 ID 小的就是服务端
    • ID 大的 Server 发起链接请求给 ID 小的 Server,真实情况是,每个节点都会启动服务端
  • Follower 和 Leader 之间的状态同步网络通信:BIO 通信实现
    • 当选举结束的时候,必然有一个节点是 Leader,其他节点 Follower
    • Leader 是 Server,其实 服务端每次接收到一个 Follower 的链接请求,建立连接之后,就会创建一个 LearnerHandler 线程来专门给这个客户端提供服务
    • Follower 是 客户端
  • Client 和 ZK 服务端之间的通信:有两种:NIO(默认实现) + Netty(需要通过配置来开启)
    • 客户端:ClientCnxnSocketNIO,平白无奇的 NIO 的客户端
    • 服务端:NIOServerCnxn,这个服务端服务组件,是通过 NIOServerCnxnFactory 工厂类来创建的,在这个类中,有一个 Listener 的组件,启动了一个NIO 的服务端,监听了 2181 端口,等待客户端发起链接请求,只要建立了链接,则 ZooKeeper Server 就会创建一个 NIOServerCnxn 专门负责给某一个Client 提供服务

ServerState

org.apache.zookeeper.server.quorum.QuorumPeer.ServerState

public enum ServerState {
    LOOKING,            // TODO 注释: 所有节点刚启动的时候的状态
    FOLLOWING,          // TODO 注释: 某个节点成为 follower 角色的时候的状态
    LEADING,
    OBSERVING
}

没有leader的时候,都是LOOKING状态
如果有leader的话,根据选举结果和配置信息,来决定自己的状态

区分三对概念:
选举配置:observer participant
集群角色:observer leader follower
服务器状态:LOOKING FOLLOWING LEADING OBSERVING

ZabState

org.apache.zookeeper.server.quorum.QuorumPeer.ZabState

public enum ZabState {
    ELECTION,                   // TODO 注释: 表示正在选举
    DISCOVERY,                  // TODO 注释: 选举算法工作完成,得到一个推举的结果,现在正在确认
    SYNCHRONIZATION,
    BROADCAST
}

选举算法工作的结果,只是当前这个节点得到一个推举的结果
不同节点得到的推举结果有可能不一样
需要确认:相互之间再次发送信息确认跟随的leader是否是同一个
如果确认了leader,则选举才真正结束
选举结束进入同步状态
同步状态结束之后,进入BROADCAST状态,
只有进入BROADCAST状态,才能接收和处理外部客户端的请求

启动过程中状态:ELECTION,DISCOVERY,SYNCHRONIZATION(也是崩溃恢复)
启动完成状态:BROADCAST(原子广播)

Zookeeper 内部的网络通信的具体实现

1、执行选举使用的是: BIO 通信(ServerSocket Socket)
2、ZooKeeper 作为一个 C/S 体系的软件,对外提供服务,是 NIO 实现
3、ZooKeeper 的 C/S 架构也提供了 netty 的实现,但是需要去配置才可可以实现。默认是就是 NIO

Java IO

百度搜索:五种 IO 模型
1、BIO JDK-1.1(编码简单,效率低) 阻塞模型
选举过程中,多个节点之间的相互通信使用的网络通信模型
2、NIO JDK-1.4(效率有提升,编码复杂) 基于reactor实现的异步非阻塞网络通信模型
通常的IO的选择:
原生NIO
基于NIO实现的网络通信框架:netty
3、AIO JDK-1.7(效率最高,编码复杂度一般) 真正的异步非阻塞通信模型

NIO 的三大API:
1、Buffer
2、Channel
3、Selector

ZooKeeper 内部在 3.4.14 版本以前都是使用的 单 selector 的实现!从 zookeeper-3.5.x 版本往后,采用了 一主(AcceptThread:OP_ACCEPT)多从(SelectorThread: OP_READ 和 OP_WRITE)的多线程 reactor 模式,事实上,真正完全数据读写工作,是一个线程池: WorkerThreaPool

ZooKeeper 中的服务端和客户端

1、服务端:QuorumPeer ===> 启动了 ServerCnxnFactory,启动了NIO服务端,监听了2181端口 ===> 接收到客户端的一个链接请求,则生成一个ServerCnxn,当该对象创建好之后,会为当前这个客户端建立成功的链接,创建一个 Session 对象。
2、客户端:ZooKeeper ===> 启动和初始化了一个 ClientCnxn(SendThread EventThread) 对线,发送 ConnectRequest 给服务端

关于客户端和服务端的一个定义:谁发请求,谁就是客户端,谁接收和处理请求,谁就是服务端
1、真正的 client 给 zookeeper 发请求
2、zookeeper 中的 leader 给 follower 发命令
3、zookeeper 中的 follower 给 leader 发请求

两个最重要的 API: C/S 架构模式

1、ServerCnxn 服务端的通信组件
zookeeper集群启动的时候,会初始化 ServerCnxn
2、ClientCnxn 客户端的通信组件
当编写代码:new ZooKeeper(1,2,3) 底层会初始化一个通信客户端对象

ServerCnxn:org.apache.zookeeper.server.ServerCnxn
Stats,表示ServerCnxn上的统计数据。
Watcher,表示事件处理,监听器。
ServerCnxn,表示服务器连接,表示一个从客户端到服务器的连接。
ClientCnxn,存在于客户端用来执行通信的组件。
NettyServerCnxn,基于Netty的连接的具体实现。
NIOServerCnxn,基于NIO的连接的具体实现。
ServerCnxnFactory, 服务端通信组件的工厂实现 也有两种: NIOServerCnxnFactory + NettyServerCnxnFactory

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值