初识Zookeeper
- zookeeper为分布式应用提供了高效且可靠的分布式协调服务,提供了诸如统一命名服务、配置管理和分布式锁等分布式的基础服务。
- 在解决分布式数据一致性方面,zk没有直接采用Paxos算法,而是采用了一种被称为ZAB(Zookeeper Atomic Broadcast)的一致性协议。
- zk可以保证如下分布式一致性特性:
- 顺序一致性:从同一个client发起的事务请求,最终会被严格按照发起顺序被应用到zk中。
- 原子性:所有事务请求的处理结果在整个集群中所有机器上的应用情况一致。
- 单一视图:无论client连接哪个zk server,其看到的服务端数据模型都是一致的。
- 可靠性:一旦server端成功应用了一个事务,并成功对client响应,那么该事务所引起的服务端状态变更会被一直保存,知道另一个事务变更。
- 实时性:zk仅保证在一定时间段内,client最终一定能从server上读取到最新的数据状态。
zk设计目标
- 简单的数据模型:zk使得分布式程序能够通过一个共享的、树形结构的名字空间来进行相互协调。
- 可以构建集群:集群中只要有超过一半的机器能正常工作,集群就能对外提供服务。client会和集群中任意一台机器建立TCP连接,断开后,client会自动连接到另一台机器。
- 顺序访问:对于client的每个更新请求,zk都会分配一个全局唯一的递增编号,该编号反应了所有事务操作的先后顺序,app可以用zk的这个特性来实现更高层次的同步原语。
- 高性能:zk将全量数据存储在内存中,并直接服务client的所有非事务请求,因此尤其适用于以读操作为主的应用场景。
zk的基本概念
集群角色
- 集群角色:最典型的集群模式是Master/Slave模式。能够处理写操作的称为master,所以通过异步复制方式获取最新数据并提供读服务的为slave。
- 而zk中没有沿用传统的主从模式,而是引入了Leader、Follower和Observer三种角色。
- zk中所有机器通过一个leader选举过程来选定一台被称为leader的机器,leader server为client提供读写服务。
- follower和observer都能提供读服务,唯一区别在于observer不参与leader选举过程,也不参与写操作的“过半写成功”策略。因此,observer在不影响写性能的情况下提升集群的读性能。
会话(Session)
- 在zk中,一个客户端连接是指client和server之间的一个TCP长连接。
- 通过这个连接,client可以通过心跳检测与服务器保持有效的会话,也能够向zk server发送请求并接受响应。
- Session的 sessionTimeout值用来设置一个客户端会话的超时时间。当服务器压力太大、网络故障或是客户端主动断开连接等各种原因导致client连接断开时,只要在sessionTimeout 时间内能够重新连接上集群中任意一台服务器,那么之前创建的会话仍然有效。
数据节点(Znode)
- zk中的节点,一类是构建集群的机器,称为机器节点;另一类则是数据模型中的数据单元,称为数据节点ZNode。
- zk将所有数据存储在内存中,数据模型是一棵树(ZNode Tree)。
- 每个znode上会保存自己的数据内容,同时还会保存一系列属性信息。
- zk还允许每个节点添加一个特殊的属性:SEQUENTIAL。该属性是一个整形数字,是一个由父节点维护的自增数字。
版本
- 对于每个znode,zk都会为其维护一个叫做Stat的数据结构,Stat记录了该Znode的三个数据版本,分别是version(当前znode的版本)、cversion(当前znode子节点的版本)和aversion(当前znode的ACL版本)。
Watcher
- Watcher(事件监听器)是zk中一个很重要的特性。zk允许用户在指定节点上注册一些watcher,并在一些特定事件触发时通知感兴趣的client。
ACL
- zk采用ACL(Access Control Lists)策略来进行权限控制。
ZK的ZAB协议
ZAB协议
- 事实上,zk并没有完全采用Paxos算法,而是使用了Zookeeper Atomic Broadcast即zk原子消息广播协议作为其数据一致性的核心算法。
- ZAB是为zk专门设计的支持崩溃恢复的原子广播协议。
- zk主要依赖ZAB协议来实现分布式数据的一致性。基于该协议,zk实现了一种主备模式的系统架构来保持集群中各副本之间数据的一致性。
- 具体的,zk使用一个单一的主进程来接收并处理client的所有事务请求,并采用ZAB的原子广播协议,将server数据的状态变更以事务Proposal的形式广播到所有的副本进程上。
- 由于顺序执行的状态变更前后会存在一定的依赖关系,ZAB协议需要保证若一个状态变更被处理时,所有其依赖的状态变更都应该已经被处理了。
- 考虑到主进程可能崩溃,ZAB协议还需要在主进程崩溃时保持正常工作。
时间: 2024-10-15 05:07:54