本文针对zookeeper的关键架构进行介绍,包括数据模型,集群结构,数据一致性保障,高性能设计,zookeeper自身的leader选举以及数据存储
zookeeper的数据模型
zookeeper数据模型使用类似文件系统的树形结构
zookeeper把这个数据模型叫做data tree, data tree的每一个节点称为znode。
znode节点类型
- 永久节点:客户端会话丢失时,zookeeper服务端不会自动删除这些节点
- 临时节点:客户端会话丢失时,zookeeper服务端会自动删除这些节点
- 无序节点:节点之间没有先后顺序关系
- 顺序节点:节点之间有顺序关系,节点名称会按照创建顺序递增
zookeeper的各种应用场景的原理归根结底都是对znode的增删改查
zookeeper集群结构
zookeeper有standalone和quorum两种模式。standalone模式下只有一个节点,quorum模式下,集群中有多个zookeeper节点
会话管理
会话- zk客户端可以和任意的节点建立session
- zk客户端可以主动关闭session
- zk客户端连接失败时会重新发起连接,和其他节点连接
- 如果服务节点在timeout事件内没有收到客户端消息,也会主动关闭session
节点角色
- leader:处理读写请求
- follower:只能处理读请求,follower在收到写请求后会转发给leader
-
observer:一种特殊的follower,处理读请求,不参与选举,不参与事务提交。只接收leader发送的inform信息更新自己的数据。一般用于跨区域数据同步
observer一般用于跨机房的部署场景,能有效提升局部读性能。
跨机房部署
zookeeper的数据一致性保证
zookeeper通过多种措施保证数据一致性
- 协议层使用TCP,保证发送顺序
- 客户端顺序一致性:先发出的请求先处理
- 多客户端按CAS方式更新: setdata带数据版本version,version为-1表示无条件更新,否则会zk节点会比较版本
- 所以写操作由leader统一处理
- leader按FIFO给每个写请求分配一个zxid,按照zxid commit数据
- 消息顺序广播:leader为每个follower维护一个队列,保证顺序广播
- 节点之间采用ZAB协议同步数据,只要过半的节点ack才认为提交成功
- 事务日志:写操作作为事务执行,都会记录事务日志
节点间数据同步
follower新加入集群后,需要向leader同步数据
if follower的zxid<leader的zxid:
从leader拉取数据
elif follower的epoch>=leader的epoch:
回退follower上epoch的数据
写请求处理流程
zookeeper使用ZAB(zookeeper atomic broadcast )协议保证分布式一致性,保证提交到leader的数据被过半的节点提交
详细的广播过程:
leader发送propose
foller收到propose后写日志,给leader返回ack
opt-1 正常场景
{
leader收到过半节点的ack后,发送commit
follower收到commit后提交数据
}
opt-2 ack未过半
{
leader在超时时间内没有收到过半节点的ack
leader回退本地数据
}
opt-3 leader commit消息超时
{
follower在超时时间内没有收到leader的commit
follower回退本地数据
}
响应客户端
zookeeper高性能
- 读写分离:leader处理rw请求,follower处理读请求
- 数据批量落盘:按照条数,时间两个维度定时刷新事务日志到磁盘;按条件生成快照日志
zookeeper集群自身leader选举
选举时机
- 集群刚启动时
- 运行期leader宕机
选举算法
整个选举过程可以分为:发起投票-处理投票-统计投票-更新状态
step1 广播自己的<sid,zxid>,选举自己
step2 监听其他节点发来的Vote <r_sid,r_zxid>
if s_zxid > zxid:
更新自己的vote,<sid,zxid> = <r_sid,r_zxid>
广播Vote <r_sid,r_zxid>
elif s_zxid == zxid and r_sid>sid:
更新自己的vote,<sid,zxid> = <r_sid,r_zxid>
广播Vote <r_sid,r_zxid>
else:
donothing
如果获得半数以上节点的选票就成为leader
选举过程举例
选举zookeeper数据存储
数据存储格式
zookeeper的数据会存储两份,一份存储在内存中,保证了快速访问;一份存储在磁盘中,保证了节点重启后可以恢复数据。
- zookeeper全部数据会以dataTree方式在内存中存储
- 日志文件:zookeeper收到写请求时,会写内存和事务日志,定期把事务日志刷新到磁盘
- 快照文件:zookeeper定期生成内存datatree的全量数据快照
数据恢复
数据恢复时,首先加载快照文件,然后通过事务日志回放追加未写到的快照的内容
网友评论