- 自序
- 概述
- 安装和运行 Zookeeper
- Zookeeper 开发实例
- ZooKeeper 中的组和成员
- 创建组
- 加入组
- 成员列表
- 删除分组
- Zookeeper 服务
- 数据模型 Data Model
- 操作 Operations
- 实现 Implementation
- 数据一致性 Consistency
- 会话 Sessions
- ZooKeeper 应用程序 Building Applications with ZooKeeper
- 配置服务 Configuration Service
- 坚韧的 ZooKeeper 应用 The Resilient ZooKeeper Application
- 一个稳定的配置服务 A reliable configuration service
- 生产环境中的 ZooKeeper ZooKeeper in Production
- 韧性和性能 Resilience and Performance
- 配置
数据一致性 Consistency
理解了 ZooKeeper 的实现原理,有助于理解 ZooKeeper 如何保证数据的一致性。就像字面上理解的“leader”和“follower”的意思一样,在 ensemble 中 follower 的 update 操作会滞后于 leader 的 update 完成。事实的结果使我们在提交更新数据之前,不必在每一台 ZooKeeper 服务器上执行持久化变更数据,而是仅需在主服务器上执行持久化变更数据。ZooKeeper 客户端的最佳实践是全部链接到 follower 上。然而客户端是有可能连接到 leader 上的,并且客户端控制不了这个选择,甚至客户端并不知道连接到了 follower 还是 leader。下图所示,读操作向 follower 请求即可,而写操作由 leader 来提交。
每一个对 znode 树的更新操作,都会被赋予一个全局唯一的 ID,我们称之为 zxid(ZooKeeper Transaction ID)。更新操作的 ID 按照发生的时间顺序升序排序。例如,z1z_{1}z1 小于 z2z_2z2,那么 z1z_1z1 的操作就早于 z2z_2z2 操作。
ZooKeeper 在数据一致性上实现了如下几个方面:
- 顺序一致性
从客户端提交的更新操作是按照先后循序排序的。例如,如果一个客户端将一个 znode z 赋值为 a,然后又将 z 的值改变成 b,那么在这个过程中不会有客户端在 z 的值变为 b 后,取到的值是 a。
- 原子性
更新操作的结果不是失败就是成功。即,如果更新操作失败,其他的客户端是不会知道的。
- 系统视图唯一性
无论客户端连接到哪个服务器,都将看见唯一的系统视图。如果客户端在同一个会话中去连接一个新的服务器,那么他所看见的视图的状态不会比之前服务器上看见的更旧。当 ensemble 中的一个服务器宕机,客户端去尝试连接另外一台服务器时,如果这台服务器的状态旧于之前宕机的服务器,那么服务器将不会接受客户端的连接请求,直到服务器的状态赶上之前宕机的服务器为止。
- 持久性
一旦更新操作成功,数据将被持久化到服务器上,并且不能撤销。所以服务器宕机重启,也不会影响数据。
- 时效性
系统视图的状态更新的延迟时间是有一个上限的,最多不过几十秒。如果服务器的状态落后于其他服务器太多,ZooKeeper 会宁可关闭这个服务器上的服务,强制客户端去连接一个状态更新的服务器。
从执行效率上考虑,读操作的目标是内存中的缓存数据,并且读操作不会参与到写操作的全局排序中。这就会引起客户端在读取 ZooKeeper 的状态时产生不一致。例如,A 客户端将 znode z 的值由 aaa 改变成 a′a^{'}a′,然后通知客户端 B 去读取 z 的值,但是 B 读取到的值是 aaa,而不是修改后的 a′a^{'}a′。为了阻止这种情况出现,B 在读取 z 的值之前,需要调用 sync
方法。 sync
方法会强制 B 连接的服务器状态与 leader 的状态同步,这样 B 在读取 z 的值就是 A 重新更改过的值了。
注意 |
---|
sync 操作只在异步调用时才可用,原因是你不需要等待操作结束再去执行其他的操作。因此,ZooKeeper 保证所有的子操作都会在 sync 结束后再执行,甚至在 sync 操作之前发出的操作请求也不例外。 |
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论