一、 zookeeper角色
1、leader角色
集群只能有一个leader角色,主要有两个职责:
- 负责集群的写操作
- 发起并维护各个Follower节点及Observer之间的心跳以监控集群的运行状态。
2、follower角色
集群可以有多个follower,follower通过心跳和leader保持连接,只要有两个职责:
- 负责集群的读操作
- 参与集群的leader选举
3、Observer角色
集群可以有多个Observer,Observer主要职责:
- 负责集群的读操作
Observer功能与follower类似,主要区别是Observer无投票权。
zk集群想支持更多的客户端并发操作,只能增加更多的follower节点,但是过多follower会使投票阶段变得复杂,选主时间过长,不利于故障快速恢复。所以引入更多Observer节点。
二、zab协议
zab(zookeeper atomic broadcast)即zookeeper原子消息广播协议。该协议通过事务编号zxid保障集群状态的唯一性。zxid单调递增。
(1)Epoch
指当前集群的周期号,集群每次leader变更都会产生一个新的周期号,周期号单调递增。如果leader崩溃恢复后发现自己比当前集群中leader周期号小,则会以follower的角色加入集群
(2)zxid
zxid指zab协议的事务号,它是一个64位数字。低32位存储单调递增的计数器,针对客户端的每个事务请求,计数器都加1。高32位存储leader的周期号epoch,每次选举出一个新leader后高32位加1,之后低32位从0开始重新计数。
三、leader选举机制和流程
什么节点适合当leader?
- 数据越新(事务zxid)
- myid越大
(1)leader选举过程
- 节点启动时,zk投票给自己
- 通过socket发送给集群中其他节点(注意:只能由myid大的节点,向myid小的节点连接,反之不能连接,zk代码中会主动断开),进行pk(zxid,myid),然后改票
- 通过过半机制,即可选举出leader节点,其他为follower节点
- 新加入的节点直接为follower节点,之后进行数据同步(如果zkid比leader大,则直接回滚)
(2)leader选举的时机
- zk启动时
- leader节点挂掉时
- 集群中超过一半follwer节点挂掉
注意:leader选举时不能提供服务
四、zk怎么处理写请求的
使用2pc两阶段提交
- 客户端发送写请求给follower节点时,follower节点不处理写请求,会转发到leader节点。
- leader节点首先生成日志zxid并持久化,然后发送给所有follower节点
- follower节点持久化日志,之后返回ack。
- leader节点while(true)(多线程,每条线程对应一个follower节点)等待ack,如果超过一半ack(过半机制,不包括Observer节点),则进行commit。
- 所有节点更新database(内存中数据)
五、zookeeper怎么保证数据一致性
- leader领导者机制
- 2pc(两阶段提交)
- 过半机制(验证是否超过一半)
- 同步机制
当follower节点发送心跳(包含zxid)给leader节点时,如果zxid小则会触发同步机制,更近一步保证了数据一致性
六、zookeeper重要功能
- watch机制(用于注册中心)
- 临时、顺序节点(用于分布式锁)
- leader选举机制(用于集群管理)
七、zookeeper的应用场景
- dubbo框架的注册中心和配置中心
- springcloud框架的注册中心
- elastic-job分布式调度框架注册中心
- kafka、hbase、hadoop、solr集群管理
- curator框架实现分布式锁
- TinyId实现分布式id
- seata框架配置中心
八、zookeeper脑裂问题
zk集群中各个节点间的网络通信不良时, 容易出现脑裂现象。
集群中的节点监听不到leader节点的心跳, 就会认为leader节点出了问题, 此时集群将分裂为不同的小集群, 这些小集群会各自选举出自己的leader节点, 导致原有的集群中出现多个leader节点.
使用过半机制,当集群中存活的节点少于半数节点, 集群将不可用.