zookeeper详解

zookeeper数据同步分类:
不管是那种数据同步分类,都要根据3个参数的对比结果,选择对应的数据同步方式

peerLastZxid:learner服务器(follower或observer),最后处理的zxid
minCommittedLog:Leader服务器proposal缓存队列committedLog中的最小zxid
manCommittedLog:Learner服务器proposal缓存队列committedLog中的最大zxid

1、diff差异同步
minCommittedLog << peerLastZxid << maxCommittedLog

2、TRUNC+DIFF(回滚+差异同步)
peerLastZxid(新leader) << maxCommittedLog(老 leader)
minCommittedLog << peerLastZxid(新leader) << maxCommittedLog
当leader将事务提交到本地事务日志中后,正准备将proposal发送给其他follower进行投票时突然宕机了,这是zk集群会选出新的leader,并且可能提交了几个事务,此后老leader再次上线,新leader发现它身上有自己没有的事务,就会回滚抹去老leader上自己没有的事务,再让老leader同步自己新提交的事务

没当集群有新leader产生时,epoch都会加+1

3、TRUNC(回滚)
就是Learner(follower)上的peerLastZxid的值,比maxCommittedLog还要大,这样只需要截取多余的部分事务记录就可以了,无需DIFF差异化同步

4、SNAP
全量同步
场景1、learner上的peerLastZxid比mixCommittedLog还要小
场景2、learner服务器没有提议缓存队列

 

leader选举原则:

1、Zookeeper集群中只有超过半数以上的服务器启动,集群才能正常工作;

2、在集群正常工作之前,myid小的服务器给myid大的服务器投票,直到集群正常工作,选出Leader

3、选出Leader之后,之前的服务器状态由Looking改变为Following,以后的服务器都是Follower
————————————————

zookeeper数据一致性:

所有写操作和客户端会话管理都以事务方式由leader统一协调,使用2阶段提交的方式,保证数据一致性
1、zk处理请求
请求分为2类: 只读请求 和 事务请求
只读请求本机处理(获取数据)
事务请求转发给leader协调(create/delete/setDate),以及客户端绘画的创建和销毁(createSession/closeSession)

2阶段-1:
投票阶段,集群中半数以上的服务持久化事务请求到事务日志,
所有事务请求由leader统一生成事务提议广播给follower
流程如下:
leader首相将事务请求持久化到事务日志文件中
leader生成事务提议,将其广播给所有follower
follower收到事务提议,也将事务持久化到事务日志文件,并给leader回应一个ack消息,表示做完事务持久化工作

阶段2-执行事务提交
leader收到半数以上ack后,认为半数以上都完成了事务日志持久化操作,可继续将事务请求同步到内存数据库中
此为事务提交阶段
流程如下:
leader收到半数以上ack信息后,进入事务commit阶段,leader先将事务请求同步到内存数据库
如果leader自己收到事务请求,此时就可以相应客户端了
leader向所有人follower广播commit消息
follower收到commit后,将事务请求同步到内存数据库
如果follower收到事务请求又转发给leader,此时follower就可以响应客户端了

————————————————

什么时候新建日志文件:
1、在进行事务日志写入之前,zookeeper会判断是否正在关联一个可写的事务日志文件,如果有则继续追加,如果没有就新建日志文件并管理上
2、上一个日志文件写满了

————————————————

什么时间触发快照:
1、事务日志写入数量达到阈值,每进行一次事务日志记录后,zk都会判断当前是否需要进行数据快照
采用过半随机策略,事务次数在[ snapCount/2 + 1,snapCount ]范围内生成的随机值时,触发数据快照

2、新leader同步数据
如果发生Leader重新选举,新Leader所在机器会检查最近一次快照之后是否有事务日志产生,
有就对最近的一次事务之前的全量数据做一次数据快照

————————————————

事务日志可视化:

文件在logs目录下
./zkTxnLogToolkit.sh ../logs/version-2/log.100000001
包含了session id、cxid(客户端操作序列号)、zxid、操作类型

 

快照日志可视化:

文件在data目录下
./zkSnapShotToolkit.sh ../data/version-2/snapshot.0

内容包含以下信息:
cZxid 创建这个节点时的事务ID
ctime 创建节点时间
mZxid 最后修改节点的事务ID
mtime 最后修改节点时间
pZxid 该节点最后更新子节点列表的事务ID
cversion 该节点子节点列表更新版本号,即子节点列表修改次数(不是子节点的值修改)
dataVersion 节点数据版本号
aclVersion 节点访问控制列表版本号
ephemeralOwner 如果为临时节点,则为节点拥有者的sessionID,如果不是临时节点则为0
dataLength 节点数据长度

————————————————

ZooKeeper启动数据初始化和同步:
ZooKeeper 服务器启动期间,需要进行数据初始化工作,就是将磁盘中的日志文件加载到ZooKeeper服务器内存中,主要包括两个过程:从快照日志文件中加载快照数据和根据事务日志进行数据修正。

为什么需要快照日志:
事务日志存的是增量数据
快照日志存的是某个时刻的全量数据
二者合二为一就是最大限度的全量数据

————————————————
数据备份策略:
防止日志文件损坏,可全量备份,开启日志清理后,至少保留3个快照文件
备份时间,一天一备,一小时一备,时间越短数据越新,异地备份,应该把精力放在数据恢复上

数据恢复
恢复数据分为了两种:冷恢复和热恢复

冷恢复就是通过备份的日志文件在 ZooKeeper 启动时初始化和同步,适用于当前集群故障,无法通信的场景
热恢复就是动态的将当前集群的数据同步到目的集群上,前提是当前集群是正常运行,可通信的

如何动态同步,可以利用 Observer 机制.将目的集群中的一个服务设置成当前集群的 Observer,
当前集群的Leader就会把数据动态同步给 Observer了,然后再将目的集群配置启动,
让这个Observer成为目的集群的 Leader 即可.
也可以将目的集群的所有服务都作为当前集群的Observer,可能会消耗一些当前集群 Leader的一些性能,以实际生产情况为准。

使用日志文件恢复数据需要注意,先把目的集群的日志文件清空
(删除 dataDir/version2 和 dataLogDir/version2 )
,将备份日志文件复制到集群中的某个服务即可,目的集群重启后,有备份日志文件的服务将成为 Leader,然后同步数据给 Follower.
前提:目的集群是一个新集群。

如果目的集群是一个已经在用的集群,就不能用日志文件恢复了,需要遍历原集群的数据,然后一条一条地写入到目的集群,该方式消耗性能较大,可能会影响目的集群的正常使用。该方式还有一个缺点就是原集群的 客户端会话不会同步,而日志文件恢复是可以的。
————————————————

Observer 介绍
在 ZooKeeper 集群服务运行的过程中,Observer 服务器与 Follow 服务器具有一个相同的功能,
那就是负责处理来自客户端的诸如查询数据节点等非事务性的会话请求操作.
但与 Follow 服务器不同的是,Observer 不参与 Leader 服务器的选举工作,也不会被选举为Leader服务器

在zoo.cfg配置文件中设置observer
peerType=observer

————————————————

自动清理快照,在zoo.cfg配置文件中手动添加

# 保存3个快照,3个日志文件

autopurge.snapRetainCount=3

 

# 间隔1个小时执行一次清理

autopurge.purgeInterval=1

 

posted @ 2023-02-09 20:24  丶花开时  阅读(497)  评论(0)    收藏  举报