论文为: ZooKeeper: Wait-free coordination for Internet-scale systems
Description
ZooKeeper是为分布式应用提供的协调服务的组件, 想法源于谷歌的chubby, 在其上做了很多修改.
ZooKeeper具有一下特征:
- 采用事件驱动机制, 因此能提供 wait-free 的接口.
- 高可用性, 相比chubby, 更加注重效率.
- 对于同一客户端的请求, 能保证FIFO地执行.
- 对于所有改变ZooKeeper状态的请求, 能保证全局有序.
ZooKeeper采用专门设计的 原子广播协议(atomic broadcast protocol) --- Zab来保 证一致性.
改变ZooKeeper状态的请求都通过master顺序处理, 读请求则可以通过follower处理, 这是保证ZooKeeper 高效率的关键.
原子广播(atomic broadcast)
由原子广播保证server间的一致性, 提供fail-over. 在文章论文研读之Zab协议里有总结.
详情可以参考:
- A simple totally ordered broadcast protocol ---简单介绍了Zab.
- Zab: High-performance broadcast for primary-backup systems ---相比上一篇更加详细.
Replicated Database
ZooKeeper周期性地创建快照(snapshots), 复制自身的状态, 但是创建快照时并不对整个文件系统加锁, 而是深度遍历所有节点, 原子地复制所有节点. 这就导致最后的快照可能不对应任何一个有效状态, 即节 点间状态不一致. 但是由于所有的写操作都是idempotent的, 所以只需要重放在开始创建快照时刻之后的 写操作, 即可使快照有效.
Client-Server Interactions
client可以连接到ZooKeeper中的任何一个server, 与server建立session后, 即可向其发送请求. 对于读请求, 可以由server在本地处理, 并在回复中附带zxid, 以表明当前server的状态. 对于写请求, 如果server不是master, 就需要将请求转发到master, 由master处理, 再返回给client.
读请求的处理方式会导致client读到的数据可能是无效的, 如果client需要保证一定读取最新的数据, ZooKeeper提供sync接口, client通过调用sync通知连接的server与master同步状态, 同步完成后再 读取数据即可获得最新数据.
ZooKeeper规定, 当client连接到一个新的server时, 必须保证此server的zxid >= client最后请求 的zxid. 即server的状态不能落后的client观察到的最新的状态. 这对于保证durability非常重要.
ZooKeeper使用超时机制检测session failure, 设超时时间为session timeout, 建立session的 client为session client.
当master发现在session timeout内ZooKeeper没有收到session client的请求时, 即认为发生了 failure. 因此, 客户端必须在一定时间内发送消息给server, 如果没有请求时, 则需要发送heartbeat 消息.
设session timeout为s, 那么当session在 s/3 时间内没有消息时, client向server发送heartbeat 消息, 在 2s/3 时间内没有收到回复时, 与其他server尝试建立session. 这样做是为了防止当server 发生failure, 导致master认为client长时间没有发送消息, 而将session关闭.