Lease 机制和 Quorum 机制

一、Lease 机制

Lease 机制是最重要的分布式协议,广泛应用于各种实际的分布式系统中。即使在某些系统中相似的设计不被称为 Lease,但我们可以分析发现其本质就是一种 Lease 的实现。

Lease 机制的定义如下:lease 是由颁发者授予的在某一有效期内的承诺。颁发者一旦发出 lease,则无论接受方是否收到,也无论后续接收方处于何种状态,只要 lease 不过期,颁发者一定严守承诺;另一方面,接收方在 lease 的有效期内可以使用颁发者的承诺,但一旦 lease 过期,接收方一定不能继续使用颁发者的承诺。

Lease 机制的基本原理如下:中心服务器在向各节点发送数据时同时颁发一个 lease,每个 lease 具有一个有效期,该有效期通常是一个明确的时间点,例如 12:00:10,一旦真实时间超过这个时间点,则 lease 过期失效(假设中心服务器与各节点的时钟是同步的)。

Lease 机制的核心为 承诺,具体表现为:

  1. 在 lease 的有效期内,中心服务器保证不会修改对应数据的值;
  2. 节点收到数据和 lease 后,将数据加入本地 cache,一旦对应的 lease 超时,节点保证将对应的本地 cache 数据删除并重新发起读请求;
  3. 中心服务器在修改数据时,首先阻塞所有新的读请求,并等待之前为该数据发出的所有 lease 超时过期,然后修改数据的值。

Lease 机制可以容错的关键是:服务器一旦发出数据及 lease,无论客户端是否收到,也无论后续客户端是否宕机,也无论后续网络是否正常,服务器只要等待 lease 超时,就可以保证对应的客户端节点不会再继续 cache 数据,从而可以放心的修改数据而不会破坏 cache 的一致性。

工程中,常选择的 lease 时长是 10s 级别,这是一个经过验证的经验值,实践中可以作为参考并综合选择合适的时长。

工程中,总是使用多个中心节点互为副本,成为一个小的集群,该小集群具有高可用性,对外提供颁发 lease 的功能。

工程中,直接实现 Lease 机制无疑会增加系统设计的复杂度,好在我们有类似 zookeeper 这样的开源的高可用系统,在工程中完全可以间接使用 Lease。

问题一:修改元数据时,阻塞了所有新的读请求,造成没有读服务?

  1. 服务器在进入修改数据流程后,一旦收到读请求则只返回数据但不颁发 lease;
  2. 服务器在进入修改数据流程后,服务器颁发的 lease 有效期限选择为已发出的 lease 的最大有效期限;

问题二:服务器在修改元数据时需要等待所有的 lease 过期超时,从而造成修改元数据的操作时延大大增大?

  1. 在等待所有的 lease 过期的过程中,服务器主动通知各个持有 lease 的节点放弃 lease 并清除 cache 中的数据,如果服务器收到客户端返回的确认放弃 lease 的消息,则服务器不需要在等待该 lease 超时;

问题三:如何解决颁发者和接收者的时钟同步问题?

  1. 对于时钟不同步,实践中的通常做法是将颁发者的有效期设置得比接收者的略大,只需大过时钟误差就可以避免对 lease 的有效性的影响。

二、Quorum 机制

Quorum 机制是一种简单有效的副本管理机制。

Quorum 机制概括说来是一种集合 N, N 是全集 U 的子集,N 中任意取集合 W、R ,W、R 都存在交集。

通俗来讲这个理论:假设有2个筐 A、B,A 中全放红球 2 个,B 中全放黑球 2 个,一次要取到所有颜色的球,只需取出3个球即可。

现在将这个理论用于分布式系统的数据一致性,如上情况,假设红色代表最新数据的版本,黑色代表历史数据的版本,那么取到所有版本再比较,就可以获得最新数据版本,也得到最新数据。这样对于想将所有数据取出的次数 4 次,操作次数就降低啦。

那么对于写模型,只需要完成 W 个副本的更新后,用户写操作就算完成,而不需要等待全写,此后系统内部会继续更新剩余节点,最终达到一致。可以看到,该算法是把写的部分负载转移到了读上,通过延长分布式系统中数据一致性的最终时间来降低写负载。至于转移多少负载比较合适,这个需要根据分布式系统的具体需求中对数据一致性的要求。

提高到数学公式:

N 表示数据所具有的副本数;R 表示完成读操作所需要读取的最小副本数,即一次读操作所需参与的最小节点数目;W 表示完成写操作所需要写入的最小副本数,即一次写操作所需要参与的最小节点数目。

由 Quorum 的理论可知,W 和 R 是关联的,W 值决定 R 值,要获取最新数据需要满足 R > N - W

假设 N=5, 如果 R=1, 那么 W 必须是 5. 所以就是写入所有的节点是全部节点,那么读取任何一个节点就可以最新的数据(有点就是像读写锁了);如果 R=5, 那么 W 只要是 1 就可以了。那么写的效率就非常高。读取的效率比较低。

posted @ 2021-04-07 15:37  JMCui  阅读(463)  评论(0编辑  收藏  举报