Zookeeper 从入门到入土⑧:集群
1. 事务 Id
概述:
- 变更状态: 事务是指能够改变 ZooKeeper 服务器状态的操作,我们也称之为事务操作或更新操作。⼀般包括数据节点创建与删除、数据节点内容更新等操作。
- ZXID: 对于每⼀个事务请求(proposal 提议),ZooKeeper 都会为其分配⼀个全局唯⼀(zk 中唯一)且有序的事务 ID,用 ZXID 来表示,通常是⼀个 64 位的数字。
- 高 32 位是 epoch(投票轮次),用来标识 Leader 是否发生改变。从 1 开始,如果有新的 Leader 产生出来,epoch 会自增。
- 低 32 位用来递增计数。每次 epoch 变化,都将低 32 位的序号重置。
作用: 标识节点同步状态。
2. Server 工作状态
- LOOKING: 不确定 Leader 状态。该状态下的服务器认为当前集群中没有 Leader,会发起 Leader 选举。
- FOLLOWING: 跟随者状态。表明当前服务器角色是 Follower,并且它知道 Leader 是谁。
- OBSERVING: 观察者状态。表明当前服务器角色是 Observer
- LEADING: 领导者状态。表明当前服务器角色是 Leader,它会维护与 Follower 间的心跳。
3. 服务器角色
- Leader
- Follower:参与选举,参与写操作时的投票。对外提供读服务。
- Observer:与 Folower 唯一的不同在于不参与选举,也不参与集群写操作时的投票。对外提供读服务。
Follower 与 Observer 统称 Learner
3.1. Leader
主要工作
- 有且仅有一个。事务请求的唯⼀调度和处理者,保证集群事务处理的顺序性。
- 集群内部各服务器的调度者。
请求处理链
使⽤责任链来处理每个客户端的请求
- 预处理器(PrepRequestProcessor): 识别出当前客户端请求是否是事务请求,并对其进行预处理。
对事务请求进⾏⼀系列预处理,如创建请求事务头、事务体、会话检查、ACL 检查和版本检查等 - 事务处理器(ProposalRequestProcessor): Leader 事务处理流程的发起者。
- 非事务性请求:将请求转发到 CommitProcessor 处理器
- 事务性请求:将请求转发到 CommitProcessor 处理器。根据请求类型创建对应的 Proposal 提议广播给所有的 Follower。还会将 Proposal 交付给 SyncRequestProcessor 进⾏事务⽇志的记录。
- 事务⽇志处理器(SyncRequestProcessor): ⽤来将事务请求记录到事务⽇志⽂件中,同时
会触发 Zookeeper 进⾏数据快照。 - 应答处理器(AckRequestProcessor): 负责在 SyncRequestProcessor 完成事务⽇志记录后,向 Proposal 的投票收集器发送 ACK 反馈,以通知投票收集器当前服务器已经完成了对该 Proposal 的事务⽇志记录。
- 事务提交处理器(CommitProcessor):
- 对于非事务请求:该处理器会直接将其交付给下⼀级处理器处理
- 对于事务请求:其会等待集群内针对 Proposal 的投票直到该 Proposal 可被提交,利⽤ CommitProcessor,每个服务器都可以很好地控制对事务请求的顺序处理。
- 应用队列处理器(ToBeAppliedRequestProcessor): 该处理器有⼀个 toBeApplied 队列,用来存储那些已经被 CommitProcessor 处理过的可被提交的 Proposal。其会将这些请求交付给 FinalRequestProcessor 处理器处理,待其处理完后,再将其从 toBeApplied 队列中移除。
- 最终处理器(FinalRequestProcessor): ⽤来进⾏返回请求前的操作,包括创建客户端请求的响应。针对事务请求,该处理器还会负责将事务应⽤到内存数据库中。
3.2. Follower
主要工作
- 处理客户端非事务性请求(读取数据),转发事务请求给 Leader。
- 参与事务请求 Proposal 的投票。
- 参与 Leader 选举投票。
请求处理链
- FollowerRequestProcessor:当前请求若是事务请求则会将该请求转发给 Leader, Leader 在接收到这个事务请求后,就会将其提交到请求处理链,按照正常事务请求进行处理。
- SendAckRequestProcessor:承担了事务日志记录反馈的角色,在完成事务日志记录后,会向 Leader 发送 ACK 消息以表明⾃身完成了事务日志的记录工作
3.3. Observer
Observer 是 ZooKeeper 自 3.3.0 版本开始引⼊的⼀个全新的服务器角色。
和 Follower 唯⼀的区别在于,Observer 不参与任何形式的投票,包括事务请求 Proposal 的投票和 Leader 选举投票。
Observer 服务器只提供非事务服务,通常⽤于在不影响集群事务处理能⼒的前提下提升集群的非事务处理能力。
4. 持久化
4.1. 数据快照
概述: 用来记录 zk 服务器上某一时刻的全量内存数据内容,并将其写入到指定的磁盘文件中,可通过 dataDir 配置文件目录。
snapCount 参数: 设置两次快照之间的事务操作个数。zk 节点记录完事务日志时,若距离上次快照,事务操作次数等于 snapCount/2~snapCount 中的某个值时,会触发快照生成操作,随机值是为了避免所有节点同时生成快照,导致集群影响缓慢)。
4.2. 事务日志
所有事务操作都是需要记录到日志文件中的,可通过 dataLogDir 配置文件目录,文件是以写入的第一条事务 zxid 为后缀,方便后续的定位查找。
zk 会采取 “磁盘空间预分配” 的策略,来避免磁盘 Seek 频率,提升 zk 服务器对事务请求的影响能力。默认设置下,每次事务日志写入操作都会实时刷入磁盘,也可以设置成非实时(写到内存文件流,定时批量写入磁盘),但那样断电时会带来丢失数据的风险。