zookeeper 原理简介随笔
两部分: 文件系统和通知机制。
文件系统,全量数据存于内存。
zk主要有2种节点类型,临时节点和持久节点。
又细分为
- 普通临时节点
- 顺序临时节点
- 普通持久节点
- 顺序持久节点
临时节点的生命周期和客户端一致。如果客户端会话失效,则节点会被自动销毁。
临时节点没有子节点
顺序节点中,只会为其直接子节点维持顺序
二阶段提交协议
分为事务询问和执行事务两个部分。
事务询问:
- 协调节点(主节点)查询各节点是否可以执行事务,各节点收到请求后执行事务(但不提交),写日志。
- 各节点返回事务执行状态给主节点。
事务提交:
- 主节点收到从节点返回后,如果都是ok,则发送提交请求给各节点。各节点提交事务,向主节点返回。
中断请求:
- 主节点收到从节点失败响应,发送中断事务请求。
ZAB
zookeeper Atomic Broadcast,zookeeper 原子广播协议。分为2部分
- 消息广播
类似于二阶段提交协议。主节点(leader)接受客户端事务请求(或其他follower转发给leader的请求),并将此请求封装后形成proposal广播给其他节点。节点收到请求后执行请求(更改内存数据,写事务日志),并将执行结果发给leader。leader统计节点执行情况,只要过半数则通知节点执行提交操作。
- 崩溃恢复
恢复阶段是指leader突然挂掉或集群刚启动时,进行的恢复操作。主要分为leader选举和状态同步两部分。
leader选举
即执行选举的过程。在集群模式下,会在服务器启动后执行选举策略。初始情况下,每个服务器都会将自己选为leader进行投票。每次投票以(myid,zxid)格式向其他服务器发送选票信息。当收到其他选票信息后,比较自己选票与其他选票
选取规则为优先比较zxid,若zxid大则选其为leader。zxid相同则比较myid,myid大的为leader。比较完成后将投票继续发送出去。直到有过半机器通过后,则leader选举出来。
状态同步
选举结束后,learner(follower或observer)向leader注册,(即表明承认新leader身份),然后开始注册流程。
- 在同步前,leader会初始化2个值,其本身缓存队列中最小,最大zxid(记为maxzxid,minzxid)。用于后续判断learner同步类型。
- 同步类型分为差异同步,回退同步,回退差异同步,全量同步。
- 从节点将自己最大zxid传给leader,leader判断此zxid是否在自己(minzxid和maxzxid)之间。
- leader等待过半从节点完成同步后,即开始对外服务接收请求。
总结来说:
- zk集群的leader收到客户端请求后,写事务日志,广播请求给其他节点,其他节点写事务日志后返回。
- zk收集一半以上节点收到响应后,发送提交请求,各节点收到请求后提交事务,返回ack
ZAB协议就是一个简化的二阶段提交协议。只有主节点接收请求,收到后写事务日志,广播请求,其他节点通过后,主节点再发送提交请求。leader收到过半机器返回即通过。
每个Server在工作过程中有三种状态:
LOOKING:当前Server不知道leader是谁,正在搜寻
LEADING:当前Server即为选举出来的leader
FOLLOWING:leader已经选举出来,当前Server与之同步
zk的磁盘管理
zk对磁盘依赖严重,对zk的数据变更,都会写事务日志到磁盘。并且只有集群过半服务器都写事务日志成功后才返回给客户端。
事务日志文件的分配一般采用预分配的策略,为提高磁盘IO效率。默认预分配64M。
设置参数 dataLogDir
所以对事务日志的目录,最好使用性能较好的磁盘,尽量避免内存与磁盘间的交换。
zk的通知机制
客户端向服务器注册watch的同时,会将Watcher对象储存在客户端的WatchManager中。当服务器触发watch事件后,传给客户端,客户端再从WatchManager中取出对应的Watcher对象执行。