The Chubby Paper
Chubby是一个分布式锁服务,之前读到的Bigtable就使用Chubby作为其底层依赖,这篇博客是对Chubby论文的浅读。
原论文:The Chubby lock service for loosely-coupled distributed systems
为什么需要第三方的锁服务?
Chubby 的目的,或者说分布式锁的目的,是同步集群中不同成员的行为,并使他们对某些事件或集群状态达成一致。 但随之而来的问题就是,为什么一定要依赖于第三方的锁服务,而不是直接在集群中使用 Paxos 或者 Raft 这样的一致性协议呢?
- 首先,第三方锁服务对原系统的侵入改造要求更少。许多系统在设计之初并未考虑引入一致性协议,如果使用 外部的第三方锁,就不会破坏太多现有的项目结构。
- 另外,Chubby 可以支持小文件的读写,使之能够将选主或数据分片的结果推广到整个集群。
- 开发者基本上熟悉了锁的概念,分布式锁对他们来说更容易接受。
- 一致性协议使用 quorum 进行决策,这意味着在客户端需要多台设备来保证高可用;但对于第三方锁,客户只需要获取一个分布式锁就可以了,一个客户即可做到。(这一点其实是站在 client 侧考虑的,其实有点牵强:Chubby 要保证 HA,同样也需要多个冗余成员,只是这种冗余和 client 的设计无关)
系统设计

Chubby 大体分成 client library 和 server 两个组件,前者是应用和服务侧交互的中介,后者是 Chubby 的核心代码实现。
服务侧的若干服务器组成的集群称为 Chubby cell ,它们使用一种一致性协议来选主。读操作由 master 独立完成,写操作则需要同步到超过半数的成员上。如果 master 宕机,则其他成员通过一致性协议重新选主;如果普通成员宕机,且未及时恢复,则系统将从一个资源池中选择一个新的机器并启动 Chubby 进程。这台机器将更新 DNS 表,替换掉旧机器的 IP 地址。master 将通过一致性协议与之同步状态。
命名机制
Chubby 的命名示例如下:
/ls/foo/wombat/pouch其中 ls 代表 lock service ,是一个必要的前缀。 foo 是 Chubby cell 的标识名,用于 DNS 查找。本地 Chubby cell 可以使用 local 指代。剩下的部分即可按照 Unix 文件系统的规范去解析。
缓存机制和 Chubby Session
client 在本地维持一份文件数据和节点元数据的 write-through 缓存,由 master 来决定是否更新。
master 记录每个 client 应该缓存的内容,一旦这些内容将要发生变化,master 首先向相应 client 发送指令标记缓存失效, client 在自己的 KeepAlive 消息中附加 ack 返回给 master,此时 master 方才修改这部分内容。
client 和 Chubby cell 之间的连接被称为 Chubby Session ,由周期性的 KeepAlive 消息维持。 每一个 Session 都有一个租约期(lease),由 master 在回复 KeepAlive 时更新。 同时,client 自身也持续估算来自 master 的 lease,其中考虑了 master 的时钟以及网络通信的时间开销。 当 client 估计的 lease 过期,它将不确定 master 是否终止了 Session,client 认为 Session 进入一段称为 jeopardy 的状态。 这个时候它清空本地缓存,继续等待一段 grace period。期间如果收到 KeepAlive 的回复,则重新恢复缓存,否则认为 Session 过期。 Chubby 会通知应用层目前的状态,进入 grace period 时发送 jeopardy 事件,恢复通信发送 safe 事件,反之发送 expired 事件。这种事件通知确保应用层可以根据 Session 状态调整运行逻辑,不必出现问题就无脑重启,造成不必要的开销。
