分布式系统的一致性问题

目录

前言

1、CAP 原理

2、BASE 和最终一致性

3、Paxos 算法简介

Paxos中的基本角色如下:

Paxos 中可能还存在下列角色。

下面介绍Paxos的具体流程。

(1)第一阶段为发起提议阶段

(2)第二阶段为决议的批准阶段


前言

在关系型数据库理论中,一致性存在于事务的 ACID 要求中,表示在事务发生前后,数据库的完整性约束没有被破环。

在分布式系统中,“一致性”这个词汇包含两方面内容。

(1)数据的多个副本内容是相同的(也可以看作一种完整性或原子性要求)。如果要求多个副本在任意时刻都是内容相同的。这也可以看做是一种事务要求,即对数据的更新要求同时发生在多个副本上,要么都成功,要么都不成功。

(2)系统执行一系列相关操作后,系统的状态仍然是完整的。

举例来说,用户A和B同时更新数据D。设原始数据为D1.0,正确的顺序是A先修改数据到D2.0,B在A的基础上更新,形成D3.0。但由于A和B同时更新数据,则可能是A和B都是基于D1.0更新了数据。此时,A和B中后写入成功的数据会覆盖先写入的版本(而不是基于先写入的版本)。如果A和B分别向不同的副本写入数据,则会出现两个相互冲突的版本:D2.a 和 D2.b。

但是,考虑到常见的大数据应用并不是非常需要传统的强一致性事务机制,很多实际的NoSQL数据库软件并不支持分布式事务,或者需要通过复杂的二次开发实现。此时,一致性问题仅涉及多副本的同步。

1、CAP 原理

CAP是指分布式系统中的 Consistency(一致性)、Availability(可用性)、Partition tolerance(分区容错性)三个特性。

CAP原理是指在分布式系统中,CAP三个特性不可兼得,只能同时满足两个。

Consistency(一致性):是指分布式系统中所有节点都能对某个数据达成共识。具体到NoSQL系统中表示,主要关注数据的多个副本内容是否相同。如果数据在系统中只有一个副本,那么共识可以轻易达成,但在多副本的情况下,就要在数据写入、读取等过程中设计一致性策略。此外,在NoSQL数据库中,还会关注一致性的“强度”,比如是否允许数据在多时间内不一致。

Availability(可用性):是指系统能对用户的操作予以反馈。大多数软件操作系统都会对用户操作予以反馈,因此这里的可用性通常是指系统反馈的即时程度。也有一些 NoSQL 系统并不会对诸如数据删除等操作予以反馈,需要用户自行查询操作结果。

Partition tolerance(分区容错性):也可称之为分区保护性。分区可以理解为系统发生故障,部分节点不可达或者部分消息丢包,此时可以理解为系统分成了多个区域。分区容错是指在部分节点故障,以及出现消息丢包的情况下,集群系统仍然可以提供服务,完成数据访问。也有人将分区理解为数据分区,分区容错是指通过数据分区实现容错,即多副本的方式,实现系统部分节点故障时可以完成数据访问。无论何种理解,都可以视为在系统中采用多副本策略。

CAP理论认为分布式系统只能兼顾其中两个特性,即出现CA、CP和AP三种情况,兼顾CA则系统不能采用多副本;兼顾CP则必须容忍系统响应迟缓;兼顾AP则需要容忍系统内多副本可能出现的不一致情况。

eg:当用户读写数据时,强一致性原则要求系统需要同时写入所有数据副本,或检查所有数据副本的数据是否一致。可用性原则要求系统快速完成上述操作并给用户反馈。但如果此时出现部分节点不可达,则不可能保证所有数据都一致,如果强制要求所有数据都一致。则系统在故障恢复之前都无法给用户一个操作结果的反馈。

在实践中,CAP原理不能理解为非此即彼的选择,一般会根据实际情况进行权衡,或者在软件层面以可配置的方式,支持用户进行策略选择。eg:某个ATM机与银行主机房发生网络故障,此时是否允许ATM机出钞?如果允许则造成数据不一致,可能造成服务滥用和经济损失,不允许则造成服务不可用,影响用户体验,有损企业形象。在实际应用中,可以给 ATM 规定一个失联时出钞的上限,在可接受的数据不一致的情况下,提升一些用户体验。

CAP原理也不能仅理解为整个分布式软件设计原则,在不同的层面、子系统或模块中,都可以根据CAP原理制定局部设计策略。例如,要求系统中的某个节点,在自身数据的管理上是兼顾CA的,但在集群整体上是兼顾CP或AP的。

最后,CAP原理和对于分布式系统一致性原理,不仅适用于大数据、NoSQL领域,也适应于网站的分布式架构设计和业务流程设计等方面。

2、BASE 和最终一致性

根据CAP原理,可以看到在分布式系统中无法得到兼顾一致性、可用性和分区容错性的完美方案。因此在NoSQL数据库的设计中会出现这样的难题。

(1)强一致性是传统关系数据库的优势,体现在ACID四个方面。很多人认为所谓数据库就应该是强一致性的。但是在NoSQL数据库的设计中是否仍然要维持这样的特点?

(2)可用性(这里可以看作响应的延迟)是很多分布式系统中非常重要的指标。NoSQL的设计需求和大型电商网站有所差异,如果将其应用在此类系统的后端,则需要保证即便操作超大的数据集,响应时间也要非常短。

(3)分区容错性则是很多NoSQL必然兼顾的。人们把大数据看作是“资产”,必然要求数据不能丢,并且数据要全在线,不能做离线保存,这样才能利用数据创造价值。因此支持分布式、多副本是大多数NoSQL系统的必选项。

为了解决上述难题,分布式系统需要根据实际业务要求,对一致性做一定妥协,此时并非放弃分布式系统中的一致性保障,而是提供弱一致性保障。具体要求可以通过BASE一词,从三个方面进行描述。

(1)Basically Available(基本可用):允许分布式系统中的部分节点或功能出现故障的情况下,系统的核心部分或其他数据仍然可用。例如,某些电商会在“双十一”等交易繁忙的场景下,暂时关闭商品评论等非主要功能。

(2)Soft-state(软状态/柔性事务):允许系统中出现“中间状态”,在NoSQL中可以体现为允许多个副本存在暂时不一致情况。

(3)Eventual Consistency(最终一致性):允许系统的状态或者多个副本之间存在暂时的不一致,但随着时间的推移,总会变得一致。这种不一致的时间一般不会过长,但要视具体情况而定。最终一致性类似于通过银行进行非实时转账的场景,转账者的钱被划走后,可能需要24小时才能达到接收者的账户,在此期间,用户账户状态和转账前后是不一致的。

最终一致性可以看作是BASE理论的核心,即通过弱化一致性要求,实现更好的伸缩性、可靠性(多副本)和响应能力。NoSQL和关系型数据库在一致性上的取舍差异, 也体现出二者不能相互替代的特点。

在实际应用中,ACID和BASE并非绝对对立,需要根据实际情况,在分布式系统的不同模块、子系统中采用不同的原则。对于实际的NoSQL软件,由于大多数放弃了对分布式事务的支持,因此其关注点更多是在多副本的最终一致性方面,即是否允许数据副本在短时间内或故障期间出现不一致情况,但最终各个副本的数据会同步,这和网站等场景有异性区别。

3、Paxos 算法简介

在分布式系统下,有时会需要多个节点就某个问题达成共识,例如,多个节点需要共同更新一个属性配置,共同执行一条指令,或者在一个主从结构的分布式系统中,当主节点出现故障时,多个从节点选举出一个新的主节点(即对谁当新主节点这一问题达成共识)。

考虑到网络存在延时、中断和丢包等可能性,节点可能无法及时收到消息,并且节点可能对提议有不同意见,例如不同节点同时对某集群参数进行了不同配置。此时需要一种分布式一致性算法,使节点之间能够较快速的对某个提议进行投票并达成共识。

Paxos算法是由莱斯利.兰伯特(Leslie Lamport)提出的一种基于消息的一致性算法,也被称为分布式共识算法,该算法被认为是同类算法中最有效的,其主要目的是就某个提议,在多个节点之间达成共识。

Paxos中的基本角色如下:

(1)若干proposer(提议者):proposer 负责提出投票提议(proposal),以及给出建议的决议(或称为值,value)。

(2)若干(一般三个以上)acceptor(投票者):acceptor收到提议后进行投票,以少数服从多数的原则决定是否接受提议,以及是否批准该值。

Paxos 中可能还存在下列角色。

(1)若干client(客户端):提议的生产者,client 会将提议提交给任意一个 proposer,并由其提交投票。

(2)若干learner(学习者): learner 没有投票权但关心提议,他们只能观察投票结果,并更新自己的认识,获得被批准的决议(值)。

(3)若干coordinator(合作者)和一个leader(领导者):在改进后的Paxos机制中存在这些角色,以更好的协调提议发起过程。

在实际系统中,通常只有客户端和服务端的概念。客户端一般扮演client、proposer和learner的角色,而服务端扮演accepter、coordinator和leader的角色。此外,一个节点也可能承担多个角色。

下面介绍Paxos的具体流程。

Paxos算法实际分为多个阶段,这里简称为 prepare、promise、accept和accepted四个阶段,如果系统中存在learner,则还可以加入一个learn阶段。下面描述算法细节。

(1)第一阶段为发起提议阶段

proposer向至少半数以上的accepter发送prepare请求。由于可能会有多个proposer都期望对自己的提议进行投票,为了确保一次只处理一个提议,proposer会将各自的提议进行编号,编号可以理解为递增的数字或 时间戳等。proposer 会将提议和编号发向各个acceptor。

acceptor决定是否接受提议,并向proposer发送promise回应。收到提议的 acceptor 可能进行如下操作之一。

① 如果 acceptor 发现该提议的编号比之前接受过的提议编号更旧,则不会进行任何回应。

② 如果 acceptor 发现该提议的编号是目前最新的(大于之前接受过的最新编号) ,则会接受该提议,同时记录下这个编号,承诺拒绝接收任何编号更旧的提议及决议。此时 acceptor 向 proposer 发送 promise 回应。如果 acceptor 对该提议已经有过决议,则在回应信息中加入编号最新的一个决议,注意,如果该 acceptor 有历史决议,则理论上该决议已经得到过半数以上 acceptor 的批准;如果 acceptor 没有历史决议,则在回应信息中加入一个空值。

proposer 在一个时限之内收集 acceptor 的回应。

① 当发现半数以上 acceptor 进行了回应(即同意对该议题进行投票),算法进入第二阶段。

② 如果回应的 acceptor 未超过半数---可能由于网络、节点故障或编号太旧,则 proposer 需要更新提议的编号值,并再次重复第一阶段。

(2)第二阶段为决议的批准阶段

proposer 向至少半数以上的 acceptor 发送 accept 请求。由于在第一阶段,acceptor 会将历史决议或空值附加到回应信息中,因此,此时 proposer 可能进行如下操作之一。

① 如果有多个 acceptor 在回应信息中附带了历史决议,则找到编号最新的协议(理论上应该是过半数的),将其发送给所有 acceptor,同时发送的还有上一轮使用的编号。

② 如果没有任何 acceptor 已有决议,则 proposer 将自己提议的决议发给所有 acceptor,同时发送的还有上一轮使用的编号。

acceptor 向 proposer 发送 accepted 回应。当 acceptor 在第二阶段收到 proposer 发送的期望决议后,会检查其编号是否符合最新原则。

① 如果该编号是最新的(大于等于之前接受过的最新编号),则批准该决议,持久存储,并进行确认。

② 如果该编号不是最新的(例如在此过程中其他 proposer 刷新了最新编号),则拒绝决议,并附带当前 accceptor 处的最新编号。

当 proposer 收到半数以上 acceptor 的 accepted 回应时,会有以下几种情况。

① 如果发现有更新的编号,则表示过程中其他 proposer 刷新了最新编号,于是更新自身编号,返回到第一阶段,重新提议。

② 如果不存在更新的编号,则认为该决议已经达成共识。

③ 如果回应数量不足半数,可能由于网络或节点故障等原因,更新自身编号,返回到第一阶段,重新提议。

④ 如果系统中存在 learn,则 learn 会通过主动或被动的方式,从acceptor 处了解该提议的当前决议,并更新自身的认识。

在经典 Paxos 过程中,当 proposer 发现提议无法收到足够多的 promise 回应或 accepted  回应,理论上都会增加提议的编号,使之新一些,并重新提交 prepare 请求。因此当多个客户端同时期望进行提议时,他们可能会不断提升 epoch 编号以抢占提议权这可能造成投票效率降低,甚至产生活锁。

为了解决这个问题,第二阶段提交中的 coordinator(协调者)角色被引入。coordinator 角色可能有多个,但其中有一个最权威的被称为 leader(领导者)。客户端或 proposer 需要进行提议时,可以向任何一个 coordinator 提交提议,coordinator 会将其提交给 leader,由 leader 决定对哪个决议进行投票。此外,在第二阶段,需要批准的值也是由 leader 传递给各个 acceptor。这种机制避免了 proposer 自行增加编号所引起的活锁问题。

下图描述了引入 coordinator 和 leader 之后的 Paxos 协议流程。

注意图中 server1 首先扮演了 proposer 角色,其次在投票中扮演了 acceptor 的角色。此外,如果 leader 宕机,则 coordinator 可以通过心跳等机制发现这一问题,并公共选举新的 leader,选举过程可通过多种机制实现,这里并不关心。

利用 Paxos 协议实现的著名系统有谷歌的 Chubby 和 Apache 软件基金会维护的开源软件 Zookeeper 等。此外在很多 NoSQL 数据库中的数据多副本一致性、主节点选举等功能也是基于 Paxos 的思想实现的。

参考:《NoSQL 数据库的基本原理》

发布了95 篇原创文章 · 获赞 16 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/tiankong_12345/article/details/101156486
今日推荐