本质
Lease 是由颁发者授予的在某一有效期内的承诺。
包含两方面的内容:
- 颁发者遵守承诺:颁发者一旦发 出 lease,则无论接受方是否收到,也无论后续接收方处于何种状态,只要 lease 不过期,颁发者一定严守承诺;
- 接受者遵守承诺:接收方在 lease 的有效期内可以使用颁发者的承诺,但一旦 lease 过期,接收方一定不能继续使用颁发者的承诺。
由于 lease 是一种承诺,具体的承诺内容可以非常宽泛,可以是数据的正确性;也可以是某种权限,例如当需要做并发控制时,同一时刻只给某一个节点颁发 lease,只有持有 lease 的节点才可以修改数据;也可以是某种身份。
Lease机制介绍
读数据
1.判断元数据是否已经处于本地 cache 且 lease 处于有效期内
1.1 是:直接返回 cache 中的元数据
1.2 否:向中心服务器节点请求读取元数据信息
1.2.1 服务器收到读取请求后,返回元数据及一个对应的 lease
1.2.2 客户端是否成功收到服务器返回的数据
1.2.2.1 失败或超时:退出流程,读取失败,可重试
1.2.2.2 成功:将元数据与该元数据的lease记录到内存中,返回元数据
写数据
1.节点向服务器发起修改元数据请求。
2.服务器收到修改请求后,阻塞所有新的读数据请求,即接收读请求,但不返回数据。
3.服务器等待所有与该元数据相关的 lease 超时。
4.服务器修改元数据并向客户端节点返回修改成功。
问题及优化点
问题 | 原因 | 优化 |
---|---|---|
服务器在修改元数据时首先要阻塞所有新的读请求,造成没有读服务 | 为了防止发出新的 lease 从而引起 不断有新客户端节点持有 lease 并缓存着数据,形成“活锁” | 1. 服务器在进入修 改数据流程后,一旦收到读请求则只返回数据但不颁发 lease。 2. 造成在修改流程执行的过程中, 客户端可以读到元数据,只是不能缓存元数据。当进入修改流程,服务器颁发的 lease 有效期限选择为已发的 lease 的最大有效期限。 |
服务器在修改元数据时需要等待所有的 lease 过期超时,从而造成修改元数据的操作时延大大增大 | 颁发者要遵守承诺 | 1.在等待所有的 lease 过期的过程中,服务器主动通知各个持有 lease 的节点放弃 lease 并清除 cache 中的数据,如果服务器收到客户端返回的确认放弃 lease 的消息, 则服务器不需要在等待该 lease 超时. 2.该过程中,如果因为异常造成服务器通知失败或者客户端节点 发送应答消息失败,服务器只需依照原本的流程等待 lease 超时即可,而不会影响协议的正确性 |
cache机制与多副本机制区别
对于 cache 的数据,可以随时删除 丢弃,并命中 cache 的后果仅仅是需要访问数据源读取数据;
然而副本机制却不一样,副本是不能随意丢弃的,每失去一个副本,服务质量都在下降,一旦副本数下降到一定程度,则往往服务将不 再可用。
Lease的容错能力分析
- 引入绝对时间作为有效期,Lease 机制能否非常好的容错网络异常。
- lease一旦颁发成功,网络异常也没关系。
- lease颁发不成功,重试即可。
- Lease 机制能较好的容错节点宕机
- 颁发者宕机,无法改变以前的承诺,不会导致出错。
- 颁发者恢复后,等待最大过期时间,保持正确。
- 接收方宕机,颁发者无需做处理,到期后自动收回承诺。
- lease 机制不依赖于存储
颁发者可以持久化颁发过的 lease 信息,从而在 宕机恢复后可以使得在有效期的 lease 继续有效。但这对于 lease 机制只是一个优化,如之前的分析, 即使颁发者没有持久化 lease 信息,也可以通过等待一个最大的 lease 时间的方式使得之前所有颁发 的 lease 失效,从而保证机制继续有效。
基于Lease机制确定节点状态
- 使用心跳方式确定 主副本的问题:
如果有3副本A、B、C,并通过中心结点Q来管理。其中A为主副本。
Q在某时刻未能预期收到主节点A的心跳,Q认为A已经异常,于是从B、C中选取一个B作为主节点。但实际上A并未异常,而是由于网络瞬时阻塞、或是Q本身出现异常使A这消息暂时未收到。这时,系统中出现A、B两个都是主节点的情况,称“双主”问题,从节点C可能同时从这两个主节点同步数据,这会引发很严重的数据错误。 - lease机制
- 由中心节点M向其他节点发送 lease, 若某个节点持有有效的 lease,则认为该节点正常可以提供服务
- 节点 A、B、C 依然周期性的发送 heart beat 报告自身状态,节点 Q 收到 heart beat 后发送一个 lease,表示节点 Q 确认了节点 A、B、C 的状态
- 节点 Q 可以给 primary 节点一个特殊的 lease,表示节点可以作为 primary 工作。
- 一旦节点 Q 希 望切换新的 primary,则只需等前一个 primary 的 lease 过期,则就可以安全的颁发新的 lease 给新的 primary 节点,而不会出现“双主”问题。
风险:
用一个中心节点发送 lease 也有很大的风险,一旦该中心节点宕机或网络异常, 则所有的节点没有 lease。
实际系统总是使用多个中心节点互为副 本,成为一个小的集群,该小集群具有高可用性,对外提供颁发 lease 的功能。
chubby 和 zookeeper 都是基于这样的设计。
Lease有效时间选择
当颁发者在发布 lease 时通常都是将当前时间加上一个固定的时长从而计算出 lease 的有效期,如何确定有效期?
- 如果lease时长太小,例如1s,一旦出现网络抖动 lease 很容易丢失,从而造成节点失去 lease, 使得依赖 lease 的服务停止;
- 如果 lease 时长太大,例如 1 分钟,则一旦接受者异常,颁发者需要过长的时间收回 lease 承诺。
工程中,常选择的 lease 时长是 10 秒级别,这是一个经 过验证的经验值,实践中可以作为参考并综合选择合适的时长。