分布式一致性实现方案

一. 构建分布式系统的指导思想

分布式系统是根据什么指导思想将共同任务分发到不同的计算机节点呢?

1. Partition分片

分而治之,即分片(Partition)的思想.对于计算任务而言,就是将计算任务进行切换,每个节点计算一些,最终汇总,这也是MapReduce(映射规约,用于大规模数据集(大于1TB)的并行运算)的思想;对于存储任务而言,可以在每个节点里存储一部分数据.当数据规模变大的时候,Partition是唯一的选择,同时这也会带来一些好处:

1️⃣.提升性能和并发,操作被分发到不同的分片,相互独立;

2️⃣.提升系统的可用性,即使部分分片不能用,其他分片也不会受到影响.

2. Replication复制

理想的情况下,有分片就行了,但事实的情况却不大理想.原因在于,分布式系统中有大量的节点,且通过网络通信.单个节点的故障(进程crash、断电、磁盘损坏)是个小概率事件,但整个系统的故障率会随节点的增加而指数级增加,而且网络通信也可能会出现断网、高延迟的情况.在这种一定会出现的“异常”情况下,分布式系统还是需要继续稳定的对外提供服务,即分布式系统需要较强的容错性.最简单的办法,就是冗余或者复制集(Replication),即多个节点负责同一个任务,最为常见的就是在分布式存储中,多个节点负责存储同一份数据,以此增强可用性与可靠性.同时,Replication也会带来性能的提升,比如数据的locality(局部性)可以减少用户的等待时间.

PartitionReplication是解决分布式系统问题的一记组合拳,很多具体的问题都可以用这个思路去解决,但这并不是银弹!因为往往是为了解决一个问题,会引入更多的问题.比如为了保证可用性与可靠性,引用了冗余(复制集),有了冗余,各个副本间的一致性问题就变得很头疼.一致性在系统的角度和用户的角度又有不同的等级划分,如果要保证强一致性,那么会影响可用性与性能,在一些应用(比如电商、搜索)中是难以接受的.如果要保证最终一致性,那么就需要处理数据冲突的情况.CAP、FLP这些理论告诉我们,在分布式系统中,没有最佳的选择,都需要进行权衡,做出最合适的选择.

二. 分布一致性问题的提出

分布式系统中要解决的一个重要问题就是数据的复制.在我们的开发中,相信很多开发人员都遇到过这样的问题:假设客户端C1将系统中的一个键K对应的值由V1更新为V2,但客户端C2无法立即读取到K对应的最新值,需要在一段时间之后才能 读取.这很正常,因为数据库复制之间存在延时.

分布式系统对于数据的复制需求一般都来自于以下两个原因:

1️⃣. 为了增加系统的可用性,以防止单点故障引起的系统不可用;

2️⃣. 提高系统的整体性能,通过负载均衡技术,能够让分布在不同地方的数据副本都能够为用户提供服务.

数据复制在可用性和性能方面给分布式系统带来的巨大好处是不言而喻的,然而数据复制所带来的一致性挑战,也是每一个系统研发人员不得不面对的.

所谓分布一致性问题,是指在分布式环境中引入数据复制机制之后,不同数据节点之间可能出现的,并且无法依靠计算机应用程序自身解决的数据不一致的情况.简单讲,数据一致性就是指在对一个副本数据进行更新的时候,必须也确保能够更新其他副本的数据,否则不同副本之间的数据将不一致.

三. CAP理论

1. CAP 概念

2000 年,加州大学伯克利分校计算机教授 Eric Brewer 提出了著名的 CAP 理论,任何基于网络的数据共享系统(即分布式系统)最多只能满足数据一致性(Consistency)、可用性(Availability)和网络分区容错(Partition Tolerance)三个特性中的两个.

在大规模的分布式环境下,网络故障是常态,所以网络分区容错是必须保障的,只能在可用性和一致性两者间做出选择,即 CP 模型或者 AP模型,实际的选择需要通过业务场景来权衡.

在分布式系统中,同时满足CAP定律中的一致性 Consistency、可用性 Availability和分区容错性 Partition Tolerance三者是不可能的.在绝大多数的场景,都需要牺牲强一致性来换取系统的高可用性,系统往往只需要保证最终一致性.

Day07_06_分布式教程之分布式一致性实现方案_数据_02

2. CAP 详解

1️⃣. Consistency: 一致性是指数据在多个副本之间能否保持一致的特性.在一致性的需求下,当一个系统在数据一致的状态下执行更新操作后,应该保证系统的数据仍然处于一直的状态.而强一致性就是指在客户端任何时候看到的各节点数据都是一致的(All nodes see the same data at the same time);

对于一个将数据副本分布在不同分布式节点上的系统来说,如果对第一个节点的数据进行了更新操作并且更新成功后,却没有使得第二个节点上的数据得到相应的更新,于是在对第二个节点的数据进行读取操作时,获取的依然是旧数据(或称为脏数据),这就是典型的分布式数据不一致的情况.在分布式系统中,如果能够做到针对一个数据项的更新操作执行成功后,所有的用户都可以读取到其最新的值,那么这样的系统就被认为具有强一致性.

2️⃣. Availability可用性是指系统提供的服务必须一直处于可用的状态,对于用户的每一个操作请求总是能够在有限的时间内返回结果.这里的重点是"有限时间内"和"返回结果".而高可用性就是指在任何时候系统都是可以读写的(Reads and writes always succeed);

"有限时间内"是指,对于用户的一个操作请求,系统必须能够在指定的时间内返回对应的处理结果,如果超过了这个时间范围,那么系统就被认为是不可用的.另外,"有限的时间内"是指系统设计之初就设计好的运行指标,通常不同系统之间有很大的不同.无论如何,对于用户请求,系统必须存在一个合理的响应时间,否则用户便会对系统感到失望.
"返回结果"是可用性的另一个非常重要的指标,它要求系统在完成对用户请求的处理后,返回一个正常的响应结果.正常的响应结果通常能够明确地反映出队请求的处理结果,即成功或失败,而不是一个让用户感到困惑的返回结果.

3️⃣. Partition Tolerance: 分区容错性是指在网络故障、某些节点不能通信的时候系统仍能继续工作,继续保证对外提供满足一致性和可用性的服务.(The system continue to operate despite arbitrary message loss or failure of part of the the system).

网络分区是指在分布式系统中,不同的节点分布在不同的子网络(机房或异地网络)中,由于一些特殊的原因导致这些子网络出现网络不连通的状况,但各个子网络的内部网络是正常的,从而导致整个系统的网络环境被切分成了若干个孤立的区域.需要注意的是,组成一个分布式系统的每个节点的加入与退出都可以看作是一个特殊的网络分区.

以实际效果而言,分区相当于对通信的时限要求.系统如果不能在时限内达成数据一致性,就意味着发生了分区的情况,必须就当前操作在C和A之间做出选择.

3. CAP的搭配方案对比

Day07_06_分布式教程之分布式一致性实现方案_分布式系统_04

说明:对于一个分布式系统而言,分区容错性是一个最基本的要求.因为既然是一个分布式系统,那么分布式系统中的组件必然需要被部署到不同的节点,否则也就无所谓分布式系统了,因此必然出现子网络.而对于分布式系统而言,网络问题又是一个必定会出现的异常情况,因此分区容错性也就成为了一个分布式系统必然需要面对和解决的问题,因此系统架构师往往需要把精力花在如何根据业务特点在 C(一致性)和A(可用性)之间寻求平衡.

四. BASE理论

3.1 BASE理论概念

BASE是Basically Available(基本可用)、Soft State(软状态)和Eventually Consistent(最终一致性) 三个短语的缩写.
BASE理论是对CAP中一致性和可用性权衡的结果,其来源于对大规模互联网系统分布式实践的总结,是基于CAP定理逐步演化而来的.BASE理论的核心思想是:即使无法做到强一致性,但每个应用都可以根据自身业务特点,采用适当的方式来使系统达到最终一致性.

3.2 BASE理论中的三要素:

1️⃣. 基本可用
基本可用是指分布式系统在出现不可预知故障的时候,允许损失部分可用性----注意:这绝不等价于系统不可用.比如:

(1).响应时间上的损失.正常情况下,一个在线搜索引擎需要在0.5秒之内返回给用户相应的查询结果,但由于出现故障,查询结果的响应时间增加了1~2秒;

(2).系统功能上的损失:正常情况下,在一个电子商务网站上进行购物的时候,消费者几乎能够顺利完成每一笔订单,但是在一些节日大促购物高峰的时候,由于消费者的购物行为激增,为了保护购物系统的稳定性,部分消费者可能会被引导到一个降级页面.

2️⃣. 软状态
软状态指允许系统中的数据存在中间状态,并认为该中间状态的存在不会影响系统的整体可用性,即允许系统在不同节点的数据副本之间进行数据同步的过程中存在延时.

3️⃣. 最终一致性
最终一致性强调的是所有的数据副本,在经过一段时间的同步之后,最终都能够达到一个一致的状态.因此,最终一致性的本质是需要系统保证最终数据能够达到一致,而不需要实时的保证系统数据的强一致性.

总的来说,BASE理论面向的是大型高可用可扩展的分布式系统,和传统的事务ACID特性是相反的,它完全不同于ACID的强一致性模型,而是通过牺牲强一致性来获得可用性,并允许数据在一段时间内是不一致的,但最终达到一致状态.但同时,在实际的分布式场景中,不同业务单元和组件对数据一致性的要求是不同的,因此在具体的分布式系统架构设计过程中,ACID特性和BASE理论往往又会结合在一起.

五. 数据一致性分级

1️⃣. 强一致性:
当用户完成更新操作之后,任何多个后续进程或者线程的访问都会返回最新的更新过的值.这种是对用户最友好的,就是用户上一次写什么,下一次就保证能读到什么.根据 CAP 理论,这种实现需要牺牲可用性.

2️⃣. 弱一致性:
系统并不保证后续进程或者线程的访问都会返回最新的更新过的值.系统在数据写入成功之后,不承诺立即可以读到最新写入的值,也不会具体的承诺多久之后可以读到.

3️⃣. 最终一致性:
这是弱一致性的特定形式,系统保证在没有后续更新的前提下,系统最终返回上一次更新操作的值.在没有故障发生的前提下,不一致窗口的时间主要受 通信延迟/系统负载和复制副本 的个数影响. DNS 是一个典型的最终一致性系统.这里之所以将最终一致性单独提出来,是因为它是弱一致性中非常推崇的一种一致性模型,也是业界在大型分布式系统的数据一致性上比较推崇的模型.

六. 一致性实现方案

1. 强一致性的实现方案

保证强一致性的思路其实很简单,就是「假设网络在大部分情况下都是正常的,批量的去操作这一批节点,要么全部成功,要么全部失败」!

1.1 强一致性实现方案:

  • 1️⃣. 2PC(两阶段提交);

  • 2️⃣. 事务补偿TCC(可以说是业务层面的2PC);

  • 3️⃣. 3PC(三阶段提交);

  • 4️⃣. Saga:将分布式长事务拆分成多个短事务,由Saga引擎来协调.

1.2 2PC与3PC的执行过程

2PC和3PC都引入了一个「协调者」来协调各个节点(参与者):

  • 客户端提交操作到协调者;

  • 协调者与参与者通信,确保各个参与者的操作;

  • 如果所有参与者操作成功,协调者返回客户端成功;

  • 否则协调者返回客户端失败.

2. 最终一致性实现的方案

可以看到,强一致性在任何一个节点出现问题后,事务都会失败.在事务要求不是很高的情况下,并不一定要保证强一致性,只要保证最终一致性就可以了.保证最终一致性的思路是基于CAP定理和BASE理论.

2.1 最终一致性实现的方案

  • 1️⃣.消息事务;

  • 2️⃣.Paxos算法;

  • 3️⃣.Raft算法.

2.2 消息事务

消息事务的原理很简单,通过消息队列来保障最终一致性,大致流程为:

  • 在提交事务时,需要提交一份数据到消息队列,两者要么全部成功,要么全部失败;

  • 消息队列消费端消费消息,执行后续的任务;

  • 如果执行成功则结束;

  • 如果因为网络原因执行失败,则重试.如果因为业务原因执行失败,则可以写入一个补偿消息,消息生产方进行数据回滚.

举例:
还是假设Server(s1,s2)向三个注册中心节点注册(c1,c2,c3),消息事务流程如下:

  • s1向c1和消息队列提交注册信息,提交成功;

  • s2向c1和消息队列提交注册信息,提交成功;

  • c2,c3监听到消息队列的消息,依次执行注册信息;

  • 执行成功则c1,c2,c3的服务列表最终都是一致的;

  • 如果c2执行s2失败,则需要向消息队列发送一个撤销操作,c1,c2接收到消息后,撤销s2的信息,s2接收到消息后,事务失败.

2.3 Paxos算法

Paxos算法分为两个阶段,但是这里的两个阶段和2PC里所说的两阶段意义是不同的.2PC中的两个阶段是指它的完整流程就是两个阶段,而Paxos里的两个阶段是交替执行的,直到达到最终一致.也就是说,对一次Paxos计算来说,可能要经过多次的阶段一、阶段二,才会达到最终一致.

Paxos中有三个角色,Proposer提出提案,Acceptor接收提案,Learner获取提案.

2.4 Raft算法

Raft中也有三个角色:

  • 1️⃣. Leader(领袖):处理客户端交互,一般一次只有一个Leader(如果出现网络分区,可能会出现多个Leader,但不影响最终一致性);

  • 2️⃣. Follower(群众):默认情况下都是Follower,Leader从Follower中选举出来;

  • 3️⃣. Candidate(候选人):将要被选为Leader的Follower.

Raft也分为两个阶段:

  • 1️⃣. 选举阶段;

  • 2️⃣. 由选举出来的Learder负责和客户端交互,同步各个Follower.

选举过程和美国大选类似:

  • <1>. 选举阶段(选总统);

  • Follower在随机等待一段时间后,转换为Candidate,立即先给自己投一票,然后向其它的Follower拉票,Follower进行投票,投票多的那个就是Leader;

  • 如果出现了两个Candidate票数相同的,那么就再等待一段时间,由这两个Candidate再次拉票,票数多的就是Leader;

  • 选出来的Leader通过心跳机制跟Follower确立leader地位.如果Leader挂了,则重新选出新的Leader(这个Leader的数据必须是最新的);

  • <2>. Leader阶段(总统处理国事,并公告);

  • Leader接收到Client的消息后,此时为Uncommitted状态;

  • Leader向所有的Follower复制这个消息,并等待Follower的响应;

  • 当大多数的Follower返回后,Leader返回Client成功响应,此时为Committed状态;

  • Leader告知Follower,该数据已提交.

七. 一致性方案选择

「强一致性」较「最终一致性」来说,在可靠性和性能上都较差(Paxos由于逻辑复杂性能也不行),但是实现简单,「最终一致性」则反之.对于方案的选择,视具体情况而定:

  • 对于需要强一致性的业务来说,则考虑放弃部分性能,可以使用强一致性,比如转账业务;

  • 对于性能要求高,但是数据一致性要求并不是太强的业务,可以使用最终一致性,比如发微博.