分布式系统为了保证一致性,有一个非常著名的算法PAXOS,这个也是目前经过证明的保证能够保证强一致性(strong consistency)的唯一算法。PAXOS算法也是唯一保证了在非拜占庭(参考拜占庭将军问题)情况下, 2F+1个副本节点中,有F个副本节点存在故障,仍然能够保证数据读写强一致性。

PAXOS算法需要多轮副本节点间的交互才能达成一致读写,负载和延时比较大。多数分布式系统中的设计理念是在CAP中优先选择AP,对于C采用的是eventual consistency,大规模部署时能够提升上层业务的可用性。

(一)NRW       

         Amazon Dynamo一样的NRW机制,NRW的本质一个Quorum机制。N代表数据的副本数目,R代表了一次成功读操作需要读到的最少副本数目,W代表了一次成功写操作需要读到的最少副本数目。当R+W>N时,按照Quorum机制的证明,仅仅只能保证写W个副本成功后,读R个副本中一定有最新写入的数据。

NRW在Dynamo内部可以为不同的store配置不同的参数。典型的配置如322,以为系统为每个数据设置3个副本,写请求要至少写成功2个节点才算请求成功,读请求要至少写成功2个节点才算请求成功,这样读写请求都可以允许一个节点发生故障,提升可用性,选择这些值是为满足性能,耐用性,一致性和可用性SLAs的需求。有些系统也可以配置为313,这就要求写请求必须3个全部写成功才算成功,在写操作的过程中,不允许任何节点故障。

【原创】分布式一致性算法之(NRW&Vector Clock)【原创】分布式一致性算法之(NRW&Vector Clock)

        一定会保障读到新数据,但是读到的R个副本中哪个是最新的并不是NRW机制能够解决的问题,需要采用Vector Clock或TimeStamps来解决。

(二) Vector Clock

         Vector Clock是一种向量锁机制,实现为一个{node, counter}的列表,SoD存储的每个Key-value都有一个vector clock,用来标记每个数据的版本。其中Node代表的是SoD节点号,counter代表的是该对象被更新的次数,据此可以判断一个对象的多个副本之间的新老版本关系。Vector clock只有在写的时候才更新,读的时候保持不变。写数据时node号是该key-value对应的主节点的node id。

举例如有A,B,C三个节点,N=3:

(1). put(key, value)后,A,B,C节点上的数据记录为:(key, value, {A,0});

(2). Put (key, value2)后,A, B, C节点上的数据记录为:(key, value, {A, 1});

根据Vector Clock可以对比出数据版本的先后关系,比如同一个key,value数据,在节点A,B,C上的数据记录分别为:

A: (key, value, {A, 2})

B: (key, value, {A, 2}{B,1})

C: (key, value, {A, 3})

则节点B上版本比A新,节点C上版本比A新,当客户端读请求获取R=2个副本数据时,无论是A和B,或者A和C,都可以根据vector clock比对出哪个是新数据,保证了读写一致性。则点B和节点C的版本冲突,无法通过vector clock对比出新老关系,需要上层应用来解决版本冲突问题。导致版本B和C节点上同一个key数据版本冲突,是由集群内节点故障时序不同导致的,特别是在多个客户端并发读写同一个数据时产生。具体场景请参考场景序列图[

      在Dynamo这种弱一致性的系统中,即便采用R+W>N的读写因子,也会出现版本冲突,需要上层应用在编写程序时解决这个问题。当前SoD在每个Vector Clock中加入了timestamp,一旦出现上述版本冲突问题,上层可根据时间戳来判断新旧关系。另外, Vector Clock中{node, counter}列表会随着处理主节点变化而不断增长,有些系统内部会对vector clock列表根据时间戳先后关系进行裁剪,防止vector clock列表增长过大。Vector clock列表信息也称为version信息。

 

相关文章:

  • 2021-11-29
  • 2021-09-07
  • 2021-08-27
  • 2021-07-23
  • 2021-11-18
猜你喜欢
  • 2021-06-26
  • 2021-06-29
  • 2021-05-09
  • 2021-08-13
  • 2021-06-12
相关资源
相似解决方案