数据一致性解决方案
CAP理论
C:一致性、A:可用性、P:分区容错性 CAP只能满足两个 CA:两阶段提交的严格选举协议 CP弱A:RAFT协议等多数派选举协议 AP:GOSSIP等冲突解决协议
数据一致性
时间一致性:所有相关数据副本任意时刻数据一致 事务一致性:事务之行前后数据一致 应用一致性:分布式事务一致
BASE理论
基本可用:允许偶尔失败 软状态:数据状态要求任意时刻一致 最终一致性:弱一致性
数据一致性解决方案
多副本数据一致性: 一般用于容灾和高可用:副本之间通过同步复制或者异步复制的方式达到数据一致。 分布式事务数据一致性: 本地事务是指数据库的单机事务处理,有点是严格的ACID特性,高效、可靠、状态可以只在资源管理器中维护、应用编程模型简单。缺点:不具备分布式事务处理能力,隔离的最小单位受限于资源管理器。 分布式事务:事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点上。
强一致性解决方案:
一次请求对多个数据源的数据进行完整性以及一致性的操作,满足事务的特性,要么全部成功,要么全部失败,保证原子性以及可见性。 强一致性通过锁定资源的方式,但是会牺牲性能,使用之前需要谨慎评估。
XA分布式事务
XA协议: 是X/OPEN组织提出的分布式事务规范,该规范主要定义了全局事务管理器(TM)和本地资源管理器(RM)之间的接口,本地资源管理器往往由数据库实现。 主流的数据库产品都提供了XA接口,XA接口是一个双向的系统接口,在事务管理器以及多个资源管理器之间作为通信桥梁。 之所以需要XA,是因为在分布式系统中从理论上讲,两台机器是无法达到一致性状态的,因此引入了一个单节点进行协调。 有全局事务管理器管理的机器可以跨多个资源和进程,负责各个本地资源的提交和回滚,全局事务管理器一般使用XA二阶段提交协议与数据库进行交互。
二阶段提交(2PC)
准备阶段: 事务协调者向所有事务参与者发送事务内容,询问是否可以提交事务,并等待参与者回复。 提交阶段: 如果协调者收到了参与者的失败信息或者超时信息,直接给所有参与者发送回滚信息进行事务回滚;否则发送提交信息。 2PC方案实现起来比较简单,但是实际项目中使用比较少 缺陷:
- 性能问题:所有参与者在事务提交阶段处于同步阻塞状态,容易造成性能问题;
- 可靠性问题:如果协调者存在单点故障问题,一旦协调者出现故障,参与者一直处于锁定状态;
- 数据一致性问题:第二阶段如果发生局部网络问题,一部分收到提交消息,一部分没有收到,会导致数据不一致。
三阶段提交(3PC)
三阶段提交是在二阶段提交的基础上的改进版本,主要是加入了超时机制,同时在协调者和参与者中都引用了超时机制。 三阶段是将二阶段里面的准备阶段拆分为两个阶段,插入了一个预提交阶段,这样原先二阶段准备之后,参与者发生崩溃或者错误所引起的问题。 第一阶段: 事务协调者向所有事务参与者发送事务内容,询问是否可以提交事务(canCommit),并等待参与者回复。参与者收到请求之后,检查是否可以提交,如果认为可以执行事务操作,返回Yes,并进入预备状态(参与者不执行事务操作),否则返回No。 第二阶段: 协调者根据第一阶段中参与者的相应情况来决定是否可以进行基于事务的预提交操作: 任何一个参与者反馈abord,即中断事务,协调者向所有参与者发送abord,abord或者超时都会中断事务。 第三阶段: 第二阶段中所有参与者均返回yes,会向所有参与者发送doCommit请求,参与者收到doCommit请求之后会正式执行事务提交,并释放整个事务期间的占用资源,各参与者向协调者返回完成的消息,协调者收到所有参与者的反馈的ack完成的消息后,完成事务的提交。 注意: 在进入第三阶段之后,无论是协调者出现问题,还是协调者与参与者的网络出现问题,都会导致参与者无法收到协调者的请求,此时参与者都会在等待超时之后继续执行事务提交(因为异常的情况毕竟是少数)
弱一致性解决方案
弱一致性:复制是异步的,最终一致性是弱一致性的特例,保证用户最终能够读取到某操作对系统特定的数据更新。 弱一致性为了提高系统的吞吐量,允许一定程度上的数据脏读。
最终一致性解决方案
强一致性的技术实现成本很高,运行性能低,很难满足真实业务场景下的高并发需求,在实际的生产环境中,通常采用最终一致性的解决方案。 最终一致性:不追求任意时刻系统都能满足数据完整且一致的要求,通过一段业务上可接受时间之后,系统能达到数据完整且一致的目标。
消息队列
建立两个消息topic,一个用来处理正常的业务提交,一个用来处理异常冲正消息。请求服务向正常的topic提交业务请求,如果全部正常,则数据一致;如果出现任何异常,向异常的topic提交业务请求,负责回滚。
事务消息方案
核心: 消息队列必须支持半事务消息(如RocketMQ),半事务消息提供类似于X/OPEN XA二阶段提交的分布式事务功能,这样能够确保请求服务执行本地事务和发送消息在一个全局事务中,只有本地事务成功执行之后,消息才会被投递。消息一旦被投递,默认设计业务执行必须成功(通过重试机制)。如果因为某些异常导致业务最终执行失败,系统无法自愈。只能通过告警的方式等待人工干预。
数据订阅方案
核心: 监听数据库的更新日志,并转换成消息流供消费端进行订阅处理。业务订阅是异步的,会存在一定的消息延迟。
TCC事务补偿
TCC是服务化的二阶段编程模型,尝试(try)、确认(confirm)、取消(cancel)均由业务编码实现。 try阶段: 尝试执行业务,完成所有业务的检查,实现一致性;预留必须的业务资源,实现准隔离型。 confirm阶段: 真正执行业务,不做任何检查,仅适用于try阶段预留的业务资源,同时要满足幂等性。 cancel阶段: 取消执行业务,释放try阶段预留的业务资源,操作要满足幂等性。
相比于二阶段提交: TCC位于业务层服务,二阶段提交位于资源层 **性能提升: **业务来实现控制资源锁的粒度大小,不会锁定整个资源 数据最终一致性: 基于confirm和concel的幂等性,保证最终事务完成确认或者取消。 可靠性: 解决了XA协议的协调者单点故障的问题,由主业务方发起并控制整个业务活动,业务管理器也变成多点,引入集群。 缺点: 都要有具体业务实现,业务耦合度较高,提高开发成本。
saga事务模式
核心思想: 将长事务拆成多个本地短事务,由saga事务协调器进行协调,如果正常结束,则正常完成;如果某个步骤失败,根据相反顺序依次调用补偿操作,达到事务的最终一致性。 基本协议:
- saga事务由许多幂等的有序的小事务组成;
- 每个小事务都有对应的补偿,用于撤销执行后的结果;
和TCC相比,没有预留动作,直接提交。 有些场景不适合补偿,比如发送短信,发了之后如果撤销,就得再给用户发送说明撤销,体验较差。
|