ZooKeeper 简介
ZooKeeper 是一种分布式协调服务,用于管理大型主机。在分布式环境中协调和管理服务是一个复杂的过程。ZooKeeper通过其简单的架构和API解决了这个问题 ZooKeeper 允许开发人员专注于核心应用程序逻辑,而不必担心应用程序的分布式特性。
ZooKeeper 框架最初是在“Yahoo!"上构建的,Apache ZooKeeper成为 Hadoop,HBase 和其他分布式框架使用的有组织服务的标准。使用 ZooKeeper 跟踪分布式数据的状态。
分布式应用正在运行的一组系统称为集群,而在集群中运行的每台机器被称为节点。
分布式应用的优点
- 可靠性 - 单个或几个系统的故障不会使整个系统出现故障。
- 可扩展性 - 可以在需要时增加性能,通过添加更多机器,在应用程序配置中进行微小的更改,而不会有停机时间。
- 透明性 - 隐藏系统的复杂性,并将其显示为单个实体/应用程序。
分布式应用的挑战
- 竞争条件 - 两个或多个机器尝试执行特定任务,实际上只需在任意给定时间由单个机器完成。例如,共享资源只能在任意给定时间由单个机器修改。
- 死锁 - 两个或多个操作等待彼此无限期完成。
- 不一致 - 数据的部分失败。
ZooKeeper 提供的服务
ZooKeeper 是由集群(节点组)使用的一种服务,用于在自身之间协调,并通过稳健的同步技术维护共享数据。ZooKeeper 本身是一个分布式应用程序,为写入分布式应用程序提供服务。
- 命名服务 - 按名称标识集群中的节点。它类似于 DNS,但仅对于节点。
- 配置管理 - 加入节点的最近的和最新的系统配置信息。
- 集群管理 - 实时地在集群和节点状态中加入/离开节点。
- 选举算法 - 选举一个节点作为协调目的的leader。
- 锁定和同步服务 - 在修改数据的同时锁定数据。此机制可帮助你在连接其他分布式应用程序(如 Apache HBase)时进行自动故障恢复。
- 高度可靠的数据注册表 - 即使在一个或几个节点关闭时也可以获得数据。
ZooKeeper 优点
- 简单的分布式协调过程
- 同步 - 服务器进程之间的相互排斥和协作。此过程有助于Apache HBase进行配置管理。
- 有序的消息
- 序列化 - 根据特定规则对数据进行编码。确保应用程序运行一致。这种方法可以在MapReduce中用来协调队列以执行运行的线程。
- 可靠性
- 原子性 - 数据转移完全成功或完全失败,但没有事务是部分的。
ZooKeeper 架构
- Client(客户端)
客户端,我们的分布式应用集群中的一个节点,从服务器访问信息。对于特定的时间间隔,每个客户端向服务器发送消息以使服务器知道客户端是活跃的。类似地,当客户端连接时,服务器发送确认码。如果连接的服务器没有响应,客户端会自动将消息重定向到另一个服务器。 - Server(服务器)
服务器,我们的 ZooKeeper 总体中的一个节点,为客户端提供所有的服务。向客户端发送确认码以告知服务器是活跃的。 - Ensemble
ZooKeeper 服务器组。形成 ensemble 所需的最小节点数为 3。 - Leader
服务器节点,如果任何连接的节点失败,则执行自动恢复。Leader 在服务启动时被选举。 - Follower
跟随leader指令的服务器节点。
ZooKeeper 数据模型
层次命名空间
ZooKeeper 文件系统的树结构
ZooKeeper 节点称为 znode,每个 znode 由一个名称标识,并用路径 (/) 序列分隔。
每个 znode下的根目录下,有两个逻辑命名空间 config 和 workers,config 命名空间用于集中式配置管理,workers 命名空间用于命名。在 config 命名空间下,每个 znode 最多可存储1MB的数据。
这种结构的主要目的是存储同步数据并描述 znode 的元数据。此结构称为 ZooKeeper 数据模型。
ZooKeeper 数据模型中的每个 znode 都维护着一个 stat 结构。一个 stat 仅提供一个 znode 的元数据。它由版本号,操作控制列表 (ACL),时间戳和数据长度组成。
- 版本号 - 每个 znode 都有版本号,这意味着每当与 znode 相关联的数据发生变化时,其对应的版本号也会增加。当多个 ZooKeeper 客户端尝试在同一 znode 上执行操作时,版本号的使用就很重要。
- 操作控制列表(ACL) - ACL 基本上是访问 znode 的认证机制。它管理所有 znode 读取和写入操作。
- 时间戳 - 时间戳表示创建和修改 znode 所经过的时间。它通常以毫秒为单位。ZooKeeper 从“事务ID" (zxid) 标识 znode 的每个更改。zxid 是唯一的,并且为每个事务保留时间,以便你可以轻松地确定从一个请求到另一个请求所经过的时间。
- 数据长度 - 存储在 znode 中的数据总量是数据长度。你最多可以存储1MB的数据。
ZooKeeper 节点类型
Znode 被分为持久(persistent)节点,顺序(sequential)节点和临时(ephemeral)节点。
- 持久节点 - 即使在创建该特定 znode 的客户端断开连接后,持久节点仍然存在。默认情况下,除非另有说明,否则所有znode 都是持久的。
- 临时节点 - 客户端活跃时,临时节点就是有效的。当客户端与 ZooKeeper 集合断开连接时,临时节点会自动删除。因此,只有临时节点不允许有子节点。如果临时节点被删除,则下一个合适的节点将填充其位置。临时节点在leader选举中起着重要作用。
- 顺序节点 - 顺序节点可以是持久的或临时的。当一个新的 znode 被创建为一个顺序节点时,ZooKeeper 通过将10位的***附加到原始名称来设置 znode 的路径。例如,如果将具有路径 /myapp 的 znode 创建为顺序节点,则 ZooKeeper 会将路径更改为 /myapp0000000001 ,并将下一个***设置为 0000000002。如果两个顺序节点是同时创建的,那么 ZooKeeper 不会对每个 znode 使用相同的数字。顺序节点在锁定和同步中起重要作用。
ZooKeeper 组件
- 写入(write)- 写入过程由 leader 节点处理。leader 将写入请求转发到所有 znode,并等待 znode 的回复。如果一半的 znode 回复,则写入过程完成。
- 读取(read)- 读取由特定连接的znode在内部执行,因此不需要与集群进行交互。
- 复制数据库(replicated database)- 它用于在zookeeper中存储数据。每个 znode 都有自己的数据库,每个 znode 在一致性的帮助下每次都有相同的数据。
- Leader - Leader 是负责处理写入请求的 Znode。
- Follower - follower 从客户端接收写入请求,并将它们转发到 leader znode。
- 请求处理器(request processor)- 只存在于 leader 节点。它管理来自 follower 节点的写入请求。
- 原子广播(atomic broadcasts) - 负责广播从leader节点到follower节点的变化。
ZooKeeper API 介绍
- connect - 连接到ZooKeeper集合
- create - 创建znode
- exists - 检查znode是否存在及其信息
- getData - 从特定的znode获取数据
- setData - 在特定的znode中设置数据
- getChildren - 获取特定znode中的所有子节点
- delete - 删除特定的znode及其所有子项
- close - 关闭连接
ZooKeeper 选举机制
提供了三种
- LeaderElection
- AuthFastLeaderElection
- FastLeaderElection(默认)
为何 ZooKeeper 要有 leader?
Zookeeper 是以 Fast Paxos 算法为基础,paxos 算法存在活锁的问题,即当有多个 proposer 交错提交时,有可能互相排斥导致没有一个 proposer 能提交成功,而 Fase Paxos 作了一些优化,通过选举产生一个 leader。
- proposer:提议者
- accepter:决策者
- learners:最终决策学习者
选举状态:
- looking:竞选状态
- following:随从状态,参与投票
- observing:观察状态,不参与投票
- leading:领导中
选举机制发生的时间
- 集群启动时
- leader 节点崩溃时
选举参与的参数
- ZXID: 事务 id,为了保证事务的顺序一致性,zk采用了递增的事务id号(zxid)来标识事务,所有的提议(proposal)都在被提出的时候加上了 zxid,实现中 zxid 是一个64位的数字,他高32位是 epoch,低32用于递增计数。值越大说明数据越新,在选举算法中数据约新权重越大
- myid: 服务器 id,服务器 id 越大,选举的权重越大。或者投票次数,同一轮投票过程中的逻辑时钟值是相同的,每一次投票完成 epoch 就会+1,然后与接受到的其他服务器返回的投票信息中的数值相比,根据不同的值做出不同的判断
- epoch: 逻辑时钟