从单点到分布式

本文梳理从单点到分布式遇到的概念及问题,包括:html

  • 单点问题
  • 主从
  • 集群
  • 负载均衡
  • 分布式
  • 分布式理论:CAP,BASE
  • 一致性:2PC,3PC,TCC,消息事务,Paxos,Raft

架构风格:万金油CS与分层中提到了CS架构风格。能够说CS架构风格是分布式架构的起点,因此咱们从CS架构风格开始。web

最简单的CS架构就是一个Client+一个Server!Client和Server之间创建链接,而后Server对Client的请求进行响应。算法

对于这个最简单的CS架构,有一个很明显的问题:「单点问题」数据库

即当这惟一的一个Server挂掉之后,Client就没法得到响应了。那怎么解决单点问题呢?很是简单,冗余。服务器

冗余的方法有两种:主从和集群!网络

注意:分布式并非为了解决单点问题的,而是为了解决单台服务器没法支撑总体业务的问题。

主从、集群和分布式

下面举个例子来讲明,主从、集群和分布式的区别!架构

假设我老婆开了家饭店。由于没钱,早期客户也不是不少,因此就一我的张罗。这就是一个单点。由于若是我老婆有什么事情,那就无法开店了。并发

从单点到分布式

但是我家有两个小孩,总是生病,三天两头的要跑医院,总是关门也不是办法。因此,在老婆有事的时候,我就去开店。我和我老婆就是「主备关系」。负载均衡

从单点到分布式

可是呢,我也要上班,我不可能总是去开店。因此咱们都没空的时候,就让我丈母娘帮忙开店。如今我、我老婆和丈母娘之间的关系仍是「主备关系」!为何?由于咱们没有同时开店,只是在其余人都有事的时候才来开店的。也就是说同时只有一个服务对外提供服务。分布式

一段时间后,饭店生意很好。老婆一我的有点忙不过来了。因而我就干脆辞职和老婆一块儿开店。咱们作的事情相同。因而咱们就组成了「集群」。咱们同时对外提供相同的服务。

从单点到分布式

此时若是我老婆有事,那我又变成了一个单点服务。

再后来,咱们两我的也忙不过来了。咱们就又招了个服务员。服务员主要工做就是帮忙点菜、收拾碗筷之类的。咱们就专心的作饭、收钱。如今我和我老婆之间仍是集群,由于咱们的工做同样。而我、我老婆和服务员就组成了分布式。咱们三我的组成了完整的服务。

从单点到分布式

可是呢,如今服务员出现了单点问题。当这个服务员请假的话,咱们又忙不过来了。因而咱们又招了一个服务员。这两个服务员之间又组成了集群。

从单点到分布式

最后,饭店越开越大。咱们招了服务员、收银、厨师、洗碗工、清洁员.....组成了一个大的分布式系统。

从单点到分布式

而我和我老婆则出去浪去了。

从单点到分布式

三者的区别

从上面的例子,咱们能够看出,主从、集群和分布式之间的区别:

  • 主从:同时只有一台服务对外提供服务。当这台服务器挂掉之后,另一个服务器对外提供服务。
  • 集群:全部服务器同时对外提供服务。有一台或几台服务器挂掉之后,可能有部分客户端会受到影响(看负载均衡算法)
  • 分布式:全部的服务组合成一个完成的系统对外提供服务。若是有一个或多个服务挂掉,那对应的那部分功能就无法使用。每一个服务均可以经过集群来确保可用性。

新的问题

虽然主从和集群解决了单点的问题。可是从主从到集群、再到分布式,系统间通讯成指数级增加,也引入了各类其它问题。

在单点CS架构下,只有Client和Server之间存在网络通讯,Server内部并不存在网络通讯。而变成分布式之后,Server间也须要经过网络通讯。因为网络的不稳定,可能会出现各类问题。同时因为节点数的增长,Server自己出问题的概率也就提升了,主要可能出现:

  • 通讯异常:因为网络的不稳定性,可能致使服务间的通讯出现异常
  • 网络分区:因为「通讯异常」,可能致使服务间的数据不一样步,或者部分服务没法对外服务。就是说,可能客户端访问到的响应有差别。
  • 响应超时:通常来讲,正常的调用会返回成功或失败的状态,可是网络通讯可能出现超时。超时分为
  • 发送超时:请求并无到达服务端
  • 响应超时:请求到达了服务端,可是服务端的响应并无返回到客户端
  • 处理方式:若是请求是幂等的,那能够再次请求。若是不是幂等的,那须要一些补偿措施。
  • 节点故障:服务节点宕机,没法对外提供服务。
  • 节点选择:即Client到哪一个节点去获取数据。这就涉及到负载均衡算法,通常的负载均衡算法有(这里不展开)
  • 随机
  • 轮询
  • 加权随机
  • 加权轮询
  • 源地址Hash
  • 一致性Hash

实际上在分布式系统中,要解决的问题是:「在网络不可靠的状况下,如何保证数据一致性」?

处理方式有两种:

  • 想办法保证强一致性
  • 不保证强一致性,但保证最终一致性

强一致性方案

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

操做方式有:

  • 2PC(两阶段提交)
  • 事务补偿TCC(能够说是业务层面的2PC)
  • 3PC(三阶段提交)
  • Sagas:将分布式长事务拆分红多个短事务,由Sagas引擎来协调,具体没有研究。可参考最后的参考资料。

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

  • 客户端提交操做到协调者
  • 协调者与参与者通讯,确保各个参与者的操做
  • 若是全部参与者操做成功,协调者返回客户端成功
  • 不然协调者返回客户端失败

具体流程见下文。

2PC

流程:

  • 提交请求阶段(commit-request phase) :
  • 协调者向全部参与者询问是否能够执行提交操做,而后开始等待各参与者的响应
  • 参与者直接就开始执行事务操做,并将Undo信息和Redo信息写入日志
  • 若是参与者的事务操做执行成功,则返回一个「赞成」消息;不然返回一个「终止」消息
  • 提交阶段(commit phase) :
  • 当协调者从全部参与者得到的响应消息都为「赞成」:
  • 协调者向全部参与者发出「正式提交」的请求
  • 参与者提交事务,并释放事务占用的资源
  • 参与者向协调者发送「完成」消息
  • 协调者收到全部参与者反馈的「完成」消息后,完成事务
  • 若是任一参与者在第一阶段返回「终止」消息,或者协调者在第一阶段超时以前没法获取全部参与者的响应消息:
  • 协调者向全部参与者发出「回滚操做」的请求
  • 参与者利用以前写入的Undo信息执行回滚操做,并释放在整个事务期间占用的资源
  • 参与者向协调者发送「回滚完成」消息
  • 协调者收到全部参与者反馈的「回滚完成」消息后,取消事务

举例:

假设两个Server(s1,s2)向三个注册中心节点注册(c1,c2,c3),若是是2PC,流程以下:

  • s1向c1,c2,c3发送「提交请求」,c1,c2,c3接收到了消息,将s1信息保存,并写入Undo和Redo日志,返回「成功」
  • 此时s2向c1,c2,c3发送「提交请求」,可是c1,c2,c3目前被锁定了,因此只能等待
  • s1收到全部的「成功」消息,向c1,c2,c3发送「确认提交」请求,c1,c2,c3提交事务,返回「完成」,s1事务结束
  • s2超时没等到全部的「成功」消息,事务回滚。

问题:

二阶段提交的问题很明显:

  • 节点阻塞:在请求阶段,节点就执行了事务操做,并进入阻塞状态。这会致使几个连锁问题:
  • 节点自己阻塞,在这个事务结束以前,这个节点不响应其它请求(上面的例子就是这种状况)
  • 若是节点占用了公共资源,其它想要访问公共资源的第三方节点也会进入阻塞状态
  • 若是在第二阶段出现网络故障,则节点会一直阻塞(可以使用超时机制)
  • 数据不一致:在第二阶段提交事务时,可能网络故障了,只有部分节点提交了数据。这就致使了数据不一致。
  • 超时失败:第二阶段,参与者执行完成了,并所有返回完成,可是协调者没有接收到,致使执行了回滚操做
  • 全部参与者都回滚了,事务执行失败(实际事务都执行成功了,可是没有接收到响应)
  • 部分参与者回滚,又致使了数据不一致

因此2PC并不能保证真正的一致性。

XA是基于2PC制定的分布式事务规范。JTA是基于XA实现的Java事务接口。

事务补偿TCC

TCC将整个业务逻辑分为三块:Try、Confirm和Cancel三个操做:

  • Try:对业务系统作检测及资源预留。相似2PC的阶段一
  • Confirm:对业务系统作确认提交。默认只要Try成功,Confirm必定成功。
  • Cancel:在业务执行错误时,执行的业务取消,释放预留资源

举例:

仍是假设两个Server(s1,s2)向三个注册中心节点注册(c1,c2,c3),若是是TCC,流程以下:

  • s1向c1,c2,c3发送「Try请求」,c1,c2,c3接收到了消息,锁定服务列表信息,返回「成功」
  • 此时s2向c1,c2,c3发送「Try请求」,锁定失败,能够等待或重试
  • s1收到全部的「成功」消息,向c1,c2,c3发送「Confirm提交」请求,c1,c2,c3提交事务,返回「完成」,s1事务结束

问题:

TCC的主要问题是适用性问题,由于是业务层的事务管理,因此须要针对具体的业务进行具体的Try/Confirm/Cancel的实现。

3PC

为了解决2PC的阻塞问题,就有了三阶段提交。三阶段提交将二阶段提交的「请求阶段」拆分为「CanCommit阶段」和「PreCommit阶段」。具体流程以下:

  • CanCommit阶段: 协调者向参与者发送提交请求,参与者若是能够提交就返回「是」,不然返回「否」。(注意,这里并不会执行事务,因此也不会阻塞)
  • PreCommit阶段:
  • 若是参与者都返回「是」,则进行事务的预执行:
  • 协调者向参与者发送PreCommit请求,并进入Prepared阶段
  • 参与者接收到PreCommit请求后,执行事务操做,并将undo和redo信息记录到事务日志中
  • 若是参与者执行成功,则返回「完成」消息,并等待最终指令
  • 假若有任何一个参与者向协调者发送了「否」,或者等待超时,那么就中断事务:
  • 协调者向全部参与者发送终止请求
  • 参与者收到终止请求后(或超时仍未收到协调者的请求),则终止事务
  • DoCommit阶段:该阶段提交事务,也分为两种状况:
  • 若是协调者接收到全部参与者返回的「完成」,则从PreCommit状态进入DoCommit状态,同时向全部参与者发送doCommit请求
  • 参与者接收到doCommit请求以后,提交事务,并在完成以后释放全部的资源
  • 事务提交完以后,向协调者发送「提交完成」响应
  • 协调者接收到全部参与者的「提交完成」响应以后,完成事务
  • 若是协调者没有接收到全部参与者发送的「提交完成」响应(参与者返回的不是「提交完成」响应或者超时没有返回任何信息),则终止事务

举例:

依然假设两个Server(s1,s2)向三个注册中心节点注册(c1,c2,c3),若是是3PC,流程以下:

  • s1向c1,c2,c3发送「CanCommit请求」,c1,c2,c3接收到了消息,返回「OK」
  • 此时s2向c1,c2,c3发送「CanCommit请求」,c1,c2,c3接收到了消息,也返回「OK」
  • s1收到全部的「成功」消息,向c1,c2,c3发送「PreCommit请求」,c1,c2,c3将s1信息保存,并写入Undo和Redo日志,返回「成功」
  • s2收到全部的「成功」消息,向c1,c2,c3发送「PreCommit请求」,c1,c2,c3返回「失败」
  • s1收到全部的「成功」消息,向c1,c2,c3发送「DoCommit请求」,c1,c2,c3提交事务,释放资源,返回成功。事务完成
  • s2收到「失败」消息,事务回滚

问题:

3PC一样会出现数据不一致的状况,在第三阶段协调者终止事务,可是参与者没有接收到,则可能致使数据不一致。

最终一致性

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

CAP定理

《JDBC的架构设计》中提到了本地事务的ACID特性:

  • 原子性(Atomicity):事务做为一个总体被执行,包含在其中的对数据库的操做要么所有被执行,要么都不执行
  • 一致性(Consistency):事务应确保数据库的状态从一个一致状态转变为另外一个一致状态。一致状态的含义是数据库中的数据应知足完整性约束
  • 隔离性(Isolation):多个事务并发执行时,一个事务的执行不该影响其余事务的执行
  • 持久性(Durability):已被提交的事务对数据库的修改应该永久保存在数据库中

CAP里也有一个A和一个C。可是实际二者之间并无什么关系。CAP中的C、A、P分别是:

  • 一致性(Consistency):这里的一致性指的是数据在多个副本之间保持强一致
  • 可用性(Availability):指系统能够对外提供服务,这是一个架构属性。关于架构属性可参考以前的文章《什么是架构属性》
  • 分区容错性(Partition tolerance):这里的分区指的是「网络分区」。指的是除非整个网络环境都发生了故障,不然系统在遇到任何网络分区故障的时候,仍然可以对外提供知足一致性和可用性的服务

CAP定理,说的是「对于一个分布式系统来讲,不可能同时知足一致性、可用性和分区容错性。最多只能知足其中两项」!

那咱们应该知足哪两项呢?这个都知道了,就是「分区容错性」和「可用性」,同时保证「最终一致性」!那为何呢?

咱们来假设:

  • 假如放弃可用性:即系统遇到任何问题,就对外不可用。上面说了,分布式系统网络间通讯数量大大增长,若是网络一波动,系统就不可用。那实际可用性还不如单点应用。那还要搞分布式干吗?
  • 假如放弃分区容错性:避免网络分区的方法就是将数据集中管理,又变成了单点应用了。
  • 假如放弃强一致性:强一致性指的是像数据库事务那样,操做完了之后,全部的数据都是一致的。可是在分布式系统里面,若是出现了网络分区或者网络延时,那么是没法保证强一致性的。虽然放弃了强一致性,可是可使用各类手段来保证最终一致性。就是说当网络故障恢复后,或者网络通讯结束后,保证各个副本的数据一致。

BASE理论

BASE理论是CAP的实践理论。其核心思想是:「根据CAP定理,咱们知道系统是没法作到强一致性的,但系统能够根据自身的业务特色,采用适当的方式来使系统达到最终一致。」

BASE包括:

  • 基本可用(Basically Available):在系统出现故障时,相对于正常的系统来讲,可能有某些服务降级,可是仍是能正常对外提供服务。服务降级包括:
  • 响应时间:即比正常系统响应时间慢
  • 功能:某些功能可能不可用。好比18年双11,淘宝的地址服务就挂了,可是不影响用户败家,只是不能修改地址而已。
  • 软状态(Soft State):指系统在最终一致以前的中间状态(即数据在一部分节点中,但尚未同步到全部的节点),该状态不影响系统的总体可用性。
  • 最终一致性(Eventually Consistent):系统从软状态中,通过一段时间,最终须要达到数据一致。这个「时间」取决于网络延时、系统负载、数据复制方案等因素。

能够看出,如今的主要问题就是「如何保证最终一致性」?

最终一致性方案

保证最终一致性的方法有:

  • 消息事务
  • Paxos算法
  • Raft

消息事务

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

  • 在提交事务时,须要提交一份数据到消息队列。二者要么所有成功,要么所有失败
  • 消息队列消费端消费消息,执行后续的任务
  • 若是执行成功则结束
  • 若是由于网络缘由执行失败,则重试。若是由于业务缘由执行失败,则能够写入一个补偿消息。消息生产方进行数据回滚

举例:

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

  • s1向c1和消息队列提交注册信息,提交成功
  • s2向c1和消息队列提交注册信息,提交成功
  • c2,c3监听到消息队列的消息,依次执行注册信息
  • 执行成功则c1,c2,c3的服务列表最终都是一致的
  • 若是c2执行s2失败,则须要向消息队列发送一个撤销操做,c1,c2接收到消息后,撤销s2的信息,s2接收到消息后,事务失败。

Paxos算法

广泛认为Paxos比较难理解,即便Lamport不使用任何公式写的《Paxos Made Simple》论文也都比较难以理解。

我以为《Paxos Made Simple》难以理解的缘由有两个:

  • 论文中没有明确「提案」和「Value」之间的关系,前面说「Value」,后面又说「提案」。实际上「提案」包括了「提案编号」和「提案值」(也就是Value),提案编号是一个全序ID,即全局惟一且是递增的。
  • 论文里面描述的Paxos算法分为两个阶段,可是这里的两个阶段和2PC里所说的两阶段意义是不一样的。2PC中的两个阶段是它的完整流程就是两个阶段,而Paxos里的两个阶段是交替执行的,直到达到最终一致。也就是说,对一次Paxos计算来讲,可能要通过屡次的阶段1、阶段二,才会达到最终一致

论文中对Paxos算法的流程描述以下:

阶段一:

  • Proposer选择一个提案号n,向大部分的Acceptor发送携带了提案号n的prepare请求
  • 若是Acceptor接收到了prepare请求,请求携带的提案号n大于它所响应的prepare请求所携带的提案号,那么它会返回一个响应,这个响应包含了它所经过的最大编号的提案(若是存在的话)
  • ,并保证之后都不会再接收提案号小于n的请求了
  • 阶段二:
  • 若是Proposer接收到了大部分Acceptor的响应,而后Proposer就发送accept请求给Acceptor,这个accept请求包含了提案号n和值v,这个v是前面Acceptor返回的最大编号的提案里的值,若是Acceptor没有返回任何提案,则v由Proposer自定义
  • 若是Acceptor接收到了提案号为n的accept请求,若是它没有响应任何提案号大于n的prepare请求,它就接收这个提案
Paxos中有三个角色Proposer提出提案,Acceptor接收提案,Learner获取提案

它主要保证了,在一次提案提交过程当中(也就是一个Paxos计算中):

  • 只有提案被提交了,那么它里面的值才能被选中
  • 最终只能有一个值被选中
  • 若是某个进程获取到了某个值,那么这个值必定是被选中的那个值

举例

下面我仍是以注册中心的流程,来阐述BasicPaxos算法(MultiPaxos这里不讨论)!

在这里Server能够说是Proposer,注册中心则是Acceptor,Client则是Learner。

假设有三个Server,P1[192.168.1.1],P2[192.168.1.2],P3[192.168.1.3]。五个注册中心节点A1,A2,A3,A4,A5。三个客户端L1,L2,L3。如今P1,P2都是第一次注册到注册中心(第一次计算):

  • P1,P2从全局ID生成器那里分别获取一个提案编号,P1[100],P2[101]
  • P1携带提案编号100向A1,A3,A5发送prepare请求。可是由于网络不太好,A1,A3成功接收,可是A5发送失败了。A1,A3接收到了提案,记录下提案编号100,并保证之后不会再赞成编号小于100的提案。由于是第一次接收提案,因此A1,A3都没有值返回。
  • P2携带提案编号101向A1,A2,A5发送prepare请求。都发送成功了。A2,A5是第一次接收到提案,因此直接记录下提案编号101,并保证之后不会再赞成编号小于101的提案。由于是第一次接收提案,因此A2,A5都没有值返回。对于A1来讲,由于已经接收到P1的提案,可是101大于100,因此记录下101,并保证之后不会再赞成编号小于101的提案。虽然A1接收了P1的prepare请求,可是并无接收到任何值,因此也没有返回。
  • P1接收到了A1,A3的响应,可是没有知足大多数。因此它从新获取了一个提案编号120,准备从新发送。
  • 在此以前,P2接收到了A1,A2,A5的响应,将本身的IP做为值,并携带编号101一块儿[101,[192.168.1.2]],向A1,A2,A5发送accept请求。A1,A2,A5都接收了这个提案,并记录了下来。
  • P1从新向A1,A3,A5发送prepare请求[120]。由于120大于A1,A3,A5所记录的提案号,因此A1,A3,A5都记录下来这个提案编号。因为A1,A5已经记录了P2的值,因此返回P2的值给P1。A3没有返回。
  • P1接收到了A1,A3,A5的响应,开始发送accept请求,可是A1,A5返回了P2的值,因此P1只能发送[120,[192.168.1.2]]到A1,A3,A5。
  • 第一次计算结束,目前A1,A3,A5记录的是[120,[192.168.1.2]]。A2记录的是[101,[192.168.1.2]],虽然编号不同,可是值是同样的。A4则能够经过学习获得最终的服务列表。

可是P1明显没有注册上去,因此它又开始了第二次注册尝试(第二次Paxos计算),这时呢,P3也开始注册了:

  • P1,P3从全局ID生成器那里分别获取一个提案编号,P1[210],P3[211]
  • P1携带提案编号210向A1,A3,A5发送prepare请求。A1,A3,A5接收到了提案,记录下提案编号210,并保证之后不会再赞成编号小于210的提案。由于这里是新的一次Paxos计算,因此这里实际仍是第一次接收数据,因此不会返回提案值。
  • P3携带提案编号211向A2,A4,A5发送prepare请求。由于211大于210,因此A2,A4,A5接收到了提案,记录下提案编号211,并保证之后不会再赞成编号小于211的提案。这里也不会返回提案值。
  • P1接收到了响应,开始发送access请求[210,[192.168.1.1]]到A1,A3,A5。A1,A3接收了这个提案,可是A5的提案号如今是211,它不接收这个提案。
  • P3接收到了响应,开始发送access请求[211,[192.168.1.3]]到A2,A4,A5。A2,A4,A5接收了这个提案。
  • P1从新获取了新的ID220,再次向A1,A3,A5发送prepare请求,A1,A3,A5都赞成了。A1,A3返回[210,[192.168.1.1]],A5返回[211,[192.168.1.3]]
  • P1接收到响应,只能发送[220,[192.168.1.3]]的prepare请求到A1,A3,A5。A1,A3,A5所有赞成。
  • 至此第二次计算结束,目前A1,A3,A5记录的是[220,[192.168.1.3]]。P3,A2,A4记录的是[211,[192.168.1.3]],虽然编号不同,可是值是同样的。P2则经过学习能够获得最终的服务列表。

如今P1仍是没注册上去,因此再来第三次注册尝试(第二次Paxos计算),如今就它一个注册了:

  • P1从全局ID生成器那里获取一个提案编号P1[310]
  • P1携带提案编号310向A1,A3,A5发送prepare请求。A1,A3,A5接收到了提案,记录下提案编号310,并保证之后不会再赞成编号小于310的提案。由于这里是新的一次Paxos计算,因此这里实际仍是第一次接收数据,因此不会返回提案值。
  • P1接收到了响应,开始发送access请求[310,[192.168.1.1]]到A1,A3,A5。A1,A3,A5接收了这个提案。
  • 其它节点能够经过学习,得到最终的服务列表。

Raft

Raft中也有三个角色:

  • Leader(领袖):处理客户端交互,通常一次只有一个Leader(若是出现网络分区,可能会出现多个Leader,但不影响最终一致性)
  • Follower(群众):默认状况下都是Follower,Leader从Follower中选举出来
  • Candidate(候选人):将要被选为Leader的Follower

Raft也分为两个阶段:

  • 选举阶段
  • 由选举出来的Learder负责和客户端交互,同步各个Follower

整个过程和美国大选相似:

  • 选举阶段(选总统)
  • Follower在随机等待一段时间后,转换为Candidate,当即先给本身投一票,而后向其它的Follower拉票,Follower进行投票,投票多的那个就是Leader
  • 若是出现了两个Candidate票数相同的,那么就再等待一段时间,由这两个Candidate再次拉票,票数多的就是Leader
  • 选出来的Leader经过心跳机制和Follower确立leader地位。若是Leader挂了,则从新选出新的Leader(这个Leader的数据必须是最新的)
  • Leader阶段(总统处理国事,并公告)
  • Leader接收到Client的消息后,此时为Uncommitted状态
  • Leader向全部的Follower复制这个消息,并等待Follower的响应
  • 当大多数的Follower返回后,Leader返回Client成功响应。此时为Committed状态
  • Leader告知Follower,该数据已提交

举例:

仍是假设Server(s1,s2)向三个注册中心节点注册(c1,c2,c3),Raft流程以下:

  • c1,c2,c3先选举出一个Leader,假设c1胜出
  • c1和c2,c3创建心跳,并等待Server注册
  • s1发送注册信息,c1接收,而后复制给c2和c3
  • s2发送注册信息,c1接收,而后复制给c2和c3。这里至关于已经退化成了单CS架构了
  • c1接收到c2,c3成功接收s1消息的响应,告知s1,事务成功
  • 可是c2接收s2消息失败,此时能够尝试重试,或者回滚事务

一致性方案选择

「强一致性」较「最终一致性」可靠性和性能都较差(Paxos因为逻辑复杂性能也不行),可是实现简单,「最终一致性」则反之。方案的选择,视具体状况而定:

  • 对于须要强一致性的业务来讲,则放弃部分性能,使用强一致性。好比转帐业务
  • 对于性能要求高,可是数据一致性要求并非太强的业务,可使用最终一致性。好比大V发微博

参考资料

  • 《PaxosMadeSimple》http://lamport.azurewebsites.net/pubs/pubs.html#paxos-simple
  • 《Base: An Acid Alternative》https://queue.acm.org/detail.cfm?id=1394128
  • Wiki二阶段提交https://zh.wikipedia.org/wiki/%E4%BA%8C%E9%98%B6%E6%AE%B5%E6%8F%90%E4%BA%A4
  • Wiki三阶段提交https://zh.wikipedia.org/wiki/%E4%B8%89%E9%98%B6%E6%AE%B5%E6%8F%90%E4%BA%A4
  • Wiki XAhttps://zh.wikipedia.org/wiki/X/Open_XA
  • Sagashttps://www.cs.cornell.edu/andru/cs711/2002fa/reading/sagas.pdf
  • CONSENSUS: BRIDGING THEORY AND PRACTICEhttps://ramcloud.stanford.edu/~ongaro/thesis.pdf
相关文章
相关标签/搜索