分布式系统概念--第一篇 一致性协议、一致性模型、拜占庭问题、租约、副本协议

1,一致性协议

两阶段提交协议与Raft协议、Paxos协议

①两阶段提交协议

在分布式系统中,每个节点虽然可以知晓自己的操作时成功或者失败,却无法知道其他节点的操作的成功或失败。当一个事务跨越多个节点时,为了保持事务的ACID特性,需要引入一个作为协调者的组件来统一掌控所有节点(称作参与者)的操作结果并最终指示这些节点是否要把操作结果进行真正的提交(比如将更新后的数据写入磁盘等等)。因此,二阶段提交的算法思路可以概括为: 参与者将操作成败通知协调者,再由协调者根据所有参与者的反馈情报决定各参与者是否要提交操作还是中止操作。

因此,系统包含两类节点,一类是协调者,一类是参与者,协议的执行由两个阶段组成:

具体参考:二阶段提交:维基百科

两阶段协议是阻塞的,节点在等待对方的应答消息时,它不能做其他事情且持有的资源也不释放。它主要是用来保证跨多个节点的操作的原子性--要么都操作,要么都不操作,而像Raft协议则诸如用来保证操作的一致性,即各个节点都执行相同的操作

两阶段协议的举例参考:两阶段提交协议

 

②Raft协议和Paxos协议

Raft与Paxos 在分布式应用中的基本功能相似,但是Paxos难于理解,相对而言Raft算法要简单一些。关于Raft协议有一篇经典的论文:

《In Search of an Understandable Consensus Algorithm (Extended Version)》

其中文翻译地址参考:寻找一种易于理解的一致性算法(扩展版)

还有一篇文章详细解释了Raft算法的相关实现:Raft论文的第 31 号参考文献。

下面仅记录一下看论文过程中出现的一个问题:

为什么 “大多数规则” 能够保证对于一个给定的任期,只会有一个候选人最终赢得选举成为Leader?
在Raft中,对于一个给定的任期号,每一台Server按照先来先服务原则对该任期号最多只投一张票,若某Candidate发送的请求投票RPC带有的任期号获得超过半数的Server的同意,则该Candidate成为Leader。
正是由于每个Server对某个任期只最多投一次票,且获得的投票要超过半数才能成为Leader,故在一个给定的任期投票中,最终只会有一个Candidate成为Leader。

关于Raft协议中的Leader选举步骤参考:Raft系列文章之二:Leader选举

 

2,分布式系统中常见的三种一致性模型

①强一致性:当更新操作在某个副本上执行成功后,之后所有的读操作都要能够获得最新的数据。对于单副本而言,读写操作都是在同一数据上执行,很容易保证一致性;而对于多副本数据,则需要使用分布式协议如2PC协议。

②弱一致性:当更新某数据时,用户读到最新的数据需要一段时间。

③最终一致性:它是一种特殊形式的弱一致性。它不能保证当某个数据X更新后,在所有后续对X的操作能够看到新数据,而是需要一个时间片段,在经过该时间片段之后,则能保证。在这个时间片段内,数据可能是不一致的,该片段称“不一致窗口“。

参考:数据一致性模型

 

3,拜占庭将军问题

在分布式理论中,经常看到”在非拜占庭错误情况下,算法是有效的……“ 或者说 ”...可以容忍非拜占庭失效“。那么什么是拜占庭将军问题呢?

分布式计算上,不同的计算机透过讯息交换,尝试达成共识;但有时候,系统上协调计算机(Coordinator / Commander)或成员计算机 (Member / Lieutanent)可能因系统错误并交换错的讯息,导致影响最终的系统一致性。参考:维基百科:拜占庭将军问题

也即,在系统不同的机器之间会传递错误的消息,这种情况即为拜占庭问题。这与”网络分割、机器崩溃...”是不同的。比如Raft协议不能容忍拜占庭问题,但是能够 在非拜占庭错误情况下,有网络延迟、分区、丢包、冗余和乱序等错误情况出现时,都可以保证其操作的正确性。

 

4,租约,心跳包(heartbeat)

①租约

这里主要列举租约可以用来干什么?

a,进行故障检测。这类似于ZooKeeper中master 与 slaver 之间发送的心跳包的作用。在ZK中, master 和 slaver 之间通过交换心跳包来检测它们是否还存活。一个具体的例子参考:故障检测

b,维护缓存一致性维护缓存的一致性,第一种办法是轮询:每次读取数据时都先询问服务器数据是不是最新的,若不是,则先让服务器传输新数据,然后再读取该新数据。第二种方法是回调:由服务器记录有哪些客户端读取了数据,当服务器对数据做修改时先通知记录下来的这些客户端,上次读取过的数据已经失效。这二种方法都有一定的缺陷,参考:租约机制简介

因此,可以引入租约机制。在租约期限内,可以保证客户端缓存的数据是最新的。当租约过期后,客户端需要重新向服务器询问数据,重新续约。

租约的定义:租约就是在一定期限内给予持有者特定权力的 协议。每个租约都有一个期限,正是这个期限可以保证租约机制容忍机器失效和网络分割。

租约机制优化后台数据库访问的一个例子:使用租约机制解决缓存数据更新的问题

 

5,副本协议

副本协议是控制副本读写行为的规则,使得副本满足可用性和一致性。

副本协议分为两类,①中心化的副本控制协议:由一个中心节点协调副本数据的更新,维护副本数据的一致性。这里重点介绍下常用的Primary-Secondary中心化副本控制协议:假设数据是以数据段(segment/partition)为单位分布在集群各台机器上的,每个数据段指定一个作为主副本,其余的数据段则为从副本,对该数据段的更新(读写)而言,由主副本来负责。比如,当多个Client同时需要更新某个数据段时,所有的更新操作都发送到该数据段所对应的主副本所在的机器上,由它来确定更新的顺序,负责协调一致性。

那么,Client如何找到主副本所在的机器呢???这需要一个元数据服务器,它专门用来记录主副本的位置及相关信息,记录集群个各个数据段的主副本的位置信息,副本分配情况……该元数据服务器应该相当于GFS中的Master。

注意:由于上面是假设数据不是以机器为单位分布在集群中,而是以数据段为单位分布在集群中,当某个数据段被指定为主副本时,该主副本也是按照以数据段为单位的数据分布方式分布到集群中的,即各个Primary副本的位置在集群中是随机分配的。

要将Primary副本所在的机器与Master机器区分开来:应该在GFS中,Primary副本所在的机器可能是某台Slaver机器,它用来存储各个数据块。而Master是用来存储元数据信息的。

②去中心化的副本控制协议:各个节点之间是平等的,通过协商方式来达成某些操作。

学习材料参考:《分布式系统原理介绍  刘杰》

posted @ 2015-08-21 21:16  大熊猫同学  阅读(6772)  评论(0编辑  收藏  举报