分布式系统之Quorum机制

在了解Quorum机制之前,先回顾一下数据一致性

  • 强一致性:在任意时刻,从任意不同副本取出的值都是一样的。
  • 弱一致性:有时泛指最终一致性,是指在任意时刻,可能由于网络延迟或者设备异常等原因,不同副本中的值可能会不一样,但经过一段时间后,最终会变成一样。

显然,我们更想要做到强一致性的这种效果,那么有哪些方式可以实现呢,其中最为简单直接的就是WARO,也就是Write All Read one。

WARO协议

是一种简单的副本控制协议,当 Client 请求向某副本写数据时(更新数据),只有当所有的副本都更新成功之后,这次写操作才算成功,否则视为失败。这样的话,只需要读任何一个副本上的数据即可。但是WARO带来的影响是写服务的可用性较低,因为只要有一个副本更新失败,此次写操作就视为失败了。

 

到这里,再来看Quorum机制到底是个什么鬼?他比WARO又好在什么地方

Quorum机制

Quorum 的定义如下:假设有 N 个副本,更新操作 wi 在 W 个副本中更新成功之后,则认为此次更新操作 wi 成功,把这次成功提交的更新操作对应的数据叫做:“成功提交的数据”。对于读操作而言,至少需要读 R 个副本,其中,W+R>N ,即 W 和 R 有重叠,一般,W+R=N+1。

  • N = 存储数据副本的数量

  • W = 更新成功所需的副本

  • R = 一次数据对象读取要访问的副本的数量

听起来有些抽象,举个例子:

假设我有5个副本,更新操作成功写入了3个,另外2个副本仍是旧数据,此时在读取的时候,只要确保读取副本的数量大于2,那么肯定就会读到最新的数据。至于如何确定哪份数据是最新的,我们可以通过引入数据版本号的方式判断(Quorum 机制的使用需要配合一个获取最新成功提交的版本号的 metadata 服务,这样可以确定最新已经成功提交的版本号,然后从已经读到的数据中就可以确认最新写入的数据。)

Quorum的应用

Quorum在分布式系统中的应用很多,下面举几个比较典型的例子:

 

1、HDFS HA

为解决NameNode的单点问题,在Hadoop 2.0对HDFS的高可用进行了改进,使得系统中可以同时启动多个NameNode,一个Active,一个Standby,并使用ZKFC(ZKFailoverController)对两者进行监控,当发现Active的NameNode服务中断,Standby的NameNode的状态会自动变为Active,接替原ActiveNameNode对外提供服务。

 

要想实现上面的功能,那就必然需要一个机制来确保Active和Standby这两个NameNode中的数据一致,所以在该系统中还引入了一个QJM模块,全称为Quorum Journal Manager。该模块一般由奇数个结点构成,每个QJM结点对外有一个RPC接口,以供Active NameNode向QJM写入EditLog(操作日志),此时会要求半数以上的QJM都写入成功,才算此次操作成功。Standby的NameNode也会定期从QJM上获取最新的EditLog来更新自身的数据

 

img

 

 

2、Zookeeper

Zookeeper的选举机制是遵循了Quorum的,这也是为什么我们部署Zookeeper必须要求有奇数个Cluster可用的原因。这样一是能保证Leader选举时不会出现平票的情况,避免出现脑裂。二是Leader在向Follower同步数据的时候,必须要超过半数的Follower同步成功,才会认为数据写入成功。

其实除了Zookeeper以外,很多支持分布式部署的模块,也都遵循和使用了这个设计,比如Redis的哨兵(sentinel)机制。

参考:分布式非权威指南

 

posted @ 2020-04-25 12:50  sw_kong  阅读(9403)  评论(0编辑  收藏  举报