选举机制
ZooKeeper的选举机制:集群中,半数以上机器存活,集群才能正常工作。在集群还没有选出leader之前,myid小的服务器会给myid大的服务器投票,直到选出leader,此时集群开始正常工作。选出leader后,之前的服务器状态由looking变更为following状态,这些服务器的身份是follower。
首先,我们在ZooKeeper的配置文件中,指定集群中ZooKeeper的数量,这里以集群中包括5个ZooKeeper为例来分析下选举过程。
依次启动1,2,3,4,5这5台服务器的ZooKeeper。
- 服务器1启动,发起一次选举,服务器1投票给自己,此时服务器1得票为1,1不超过半数3,服务器1状态为looking。
- 服务器2启动,重新发起一次选举,服务器1和服务器2投票给自己,因为服务器1发现服务器2的myid比自己的大,服务器1更改选票投给服务器2,此时服务器1得0票,服务器2得到2票,2不超过半数3,服务器1和服务器2状态为looking。
- 服务器3启动,重新发起一次选举,服务器1服务器2服务器3投票给自己,因为服务器1和服务器2发现服务器3的myid比自己的大,服务器1和服务器2更改选票投给服务器3,此时服务器1得0票,服务器2得0票,服务器3得3票,3超过半数3,服务器3的当选leader,服务器1和服务器2状态变为following,服务器3状态变为leading。
- 服务器4启动,重新发起一次选举,服务器1服务器2服务器3已经不是looking状态,不会更改选票信息,经过投票后,服务器1得0票,服务器2得0票,服务器3得3票,服务器4服从多数,更改选票投给服务器3,服务器4变更状态为following。
- 服务器5启动,重新发起一次选举,服务器1服务器2服务器3已经不是looking状态,不会更改选票信息,经过投票后,服务器3得5票,其余服务器得0票,服务器5变更状态为following。
结点类型
ZNode有两种类型:短暂结点和持久结点。
短暂结点:客户端与服务器断开连接后,创建的结点自动删除
持久结点:客户端与服务器断开连接后,创建的结点不会自动删除
ZNode有四种形式的目录结点:
持久化目录结点:客户端与ZooKeeper断开连接后,结点依旧存在
持久化顺序编号目录结点:客户端与ZooKeeper断开连接后,结点依旧存在,ZooKeeper会给该结点名称进行顺序编号
临时目录结点:客户端与ZooKeeper断开连接后,结点被删除
临时顺序编号目录结点:客户端与ZooKeeper断开连接后,结点被删除,ZooKeeper会给该结点名称进行顺序编号
创建znode时设置顺序标识,znode名称后会附加一个值,顺序号是一个单调递增的计数器,由父节点维护。
在分布式系统中,顺序号可以被用于为所有的事件进行全局排序,这样客户端可以通过顺序号推断事件的顺序。
stat结构体
- czxid:创建结点的事务zxid,每次修改ZooKeeper状态都会收到一个zxid形式的时间戳,这是ZooKeeper的事务id,事务id是ZooKeeper中所有修改的总次序,每次修改都有一个唯一的zxid,zxid越小,代表这个事务越早发生
- ctime:znode被创建的毫秒数,从1970年开始
- mzxid:znode结点最后更新的事务id
- mtime:znode结点最后更新的毫秒数,从1970年开始
- pZxid:znode最后更新的子结点zxid
- cversion:znode子结点的变化号,znode子结点修改次数
- dataversion:znode数据变化号
- aclVersion:znode访问控制列表的变化号
- ephemeralOwner:如果是临时结点,这个是znode拥有者的sessionid,如果是持久结点,这个是0
- dataLength:znode结点的数据长度
- numChildren:znode子结点数量
监听器原理
常见的监听有:监听结点数据变化、监听结点增减变化。
- 在Main线程中,创建一个ZooKeeper客户端,此时会创建两个线程,一个负责网络连接通信,一个负责监听
- 通过connect线程将注册的监听事件发给ZooKeeper
- 将注册的监听事件添加到ZooKeeper监听器列表中
- ZooKeeper监听到有数据变化或者路径变化的时候,会发送消息给listener线程
- listener线程内部调用process()方法
写数据流程
- Client向ZooKeeper的Server1发送一个写请求
- 如果Server1不是leader,Server1会把请求转发给leader,leader会把请求广播给各个Server,各个Server执行写操作,成功后通知leader
- 当leader收到大多数Server(超过半数)数据写成功的时候,Zookeeper就认为数据写成功了
- leader会告知Server1数据写成功
- Server1进一步通知Client数据写成功,此时整个写操作完成