精华内容
下载资源
问答
  • 分布式数据一致性
    千次阅读
    2019-05-22 15:19:34

    前言

    分布式数据库的数据一致性管理是其最重要的内核技术之一,也是保证分布式数据库满足数据库最基本的ACID特性中的 “一致性”(Consistency)的保障。在分布式技术发展下,数据一致性的解决方法和技术也在不断的演进,本文就以分布式数据库作为案例,介绍分布式数据库数据一致性的原理以及实际实现。

    1、数据一致性

    1.1 数据一致性是什么

    大部份使用传统关系型数据库的DBA在看到“数据一致性”时,第一反应可能都是数据在跨表事务中的数据一致性场景。但是本文介绍的“数据一致性”,指的是**“数据在多份副本中存储时,如何保障数据的一致性”**场景。

    由于在大数据领域,数据的安全不再由硬件来保证,而是通过软件手段,通过同时将数据写入到多个副本中,来确保数据的安全。数据库在同时向多个副本写入记录时,如何确保每个副本数据一致,称为“数据一致性”。

    1.2 关系型数据库如何保障数据一致性

    传统的关系型数据库对于运行环境–硬件要求都比较高,例如Oracle会建议用户使用小型机+共享存储作为数据库的运行环境,DB2 DPF也同样建议用户采用更好的服务器+高端存储来搭建数据库的运行环境。所以在数据存储安全的技术要求下,传统关系型数据库更多是依赖硬件的技术来保障数据的安全性。

    在这里插入图片描述
    因为关系型数据库的数据安全是基于硬件来保障,并且数据也不会通过同时存储多份来保障数据的安全,所以关系型数据库的用户默认认为数据存储是一致的。

    1.3 分布式存储如何保障数据一致性

    本文在讨论分布式存储时,主要指的是大数据产品中的分布式文件系统和分布式数据库,例如:SequoiaDB和HDFS。

    用户在搞明白分布式存储的数据一致性原理时,必须要先明白为什么他们就需要数据一致性,和分布式存储的数据存储与关系型数据库的数据存储又有什么区别。

    大数据技术的诞生,确确实实让系统的性能有新的突破,并且支持硬件以水平扩展的方式来获得线性增长的性能和存储。这些都是过去传统关系型数据库所无法提供的。另外,大数据技术也抛弃了运行环境必须足够好的硬性要求,而是允许用户通过批量廉价X86服务器+本地磁盘的方式搭建规模集群,从而获得比过去依赖硬件垂直扩展所提供的更强的计算能力和更多的存储空间。

    大数据技术的核心思想就是分布式,将一个大的工作任务分解成多个小任务,然后通过分布式并发操作的方式将其完成,从而提高整个系统的计算效率或者是存储能力。而在分布式环境下,由于硬件的要求降低,必然需要大数据产品提供另外一个重要的功能–数据安全

    在这里插入图片描述
    大数据产品在解决数据安全的方式上,都比较接近,简单来说,就是让一份数据通过异步或者同步的方式保存在多台机器上,从而保障数据的安全。

    分布式存储在解决数据安全的技术难点后,又引入了一个新的技术问题,就是如何保障多个副本中的数据一致性。目前SequoiaDB是使用Raft算法来保证数据在多个副本中一致性。

    2、Raft算法

    2.1 Raft算法背景

    在分布式环境下,最著名的一致性算法应该是Paxos算法,但是由于它实在过于晦涩难懂,并且实现起来极度困难,所以在2013年,Diego Ongaro、John Ousterhout两个人以易懂(Understandability)为目标设计了一套一致性算法Raft。Raft算法最大的特点在于简单易懂,并且实现起来简单

    2.2 Raft算法概述

    与Paxos不同,Raft强调的是易懂,Raft和Paxos一样只要保证n/2+1节点正常就能够提供服务。

    众所周知当问题较为复杂时可以把问题分解为几个小问题来处理,Raft也使用了分而治之的思想。Raft算法重点解决三个子问题:选举(Leader election)、日志复制(Log replication)、安全性(Safety)。

    Raft算法强化了Leader节点的功能,Follower节点的数据只能够从Leader中获取,所以Follower节点的实现就变得简单,只要负责和Leader保持通信,并且接受Leader推送的数据即可。

    2.3 Raft算法原理

    2.3.1 节点角色

    Raft算法中,对节点的状态分为3种角色,分别是Leader(领导者)、Follower(追随者)和Candidate(候选者)。

    Leader,负责处理来自客户端的请求,负责将日志同步到Follower中,并且保证与Follower之间的heartBeat联系;

    Follower,当集群刚刚启动时,所有节点均为Follower状态,它的工作主要为响应Leader的日志同步请求,响应Candidate的请求,以及把请求到Follower的事务请求转发给Leader;

    Candidate,选举Leader时负责投票,选举出来Leader后,节点将从Candidate状态变为Leader状态。

    在这里插入图片描述

    2.3.2 Terms

    在分布式环境下,“时间同步”一直都是老大难的技术难题。Raft为了解决这个问题,将时间划分为一个一个的Term(可以理解为“逻辑时间”)来处理在不同时间段里的数据一致性。

    Terms有以下原则

    • 每个Term中,至多存在一个Leader
    • 某些Term中,有可能存在由于选举失败,没有Leader的情况
    • 每个节点自己维护本地的currentTerm
    • 每个Term都是一个连续递增的编号
    • 如果Follower的Term编号比别的Follower Term编号小时,该Follower Term编号将更新Term编号,以保持与其他Follower Term编号一致

    2.3.3 选举

    Raft的选举由定时器触发,每个节点的触发时间都不相同。

    所有的节点在开始时状态都为Follower,当定时器触发选举后Term编号递增,该节点的状态由Follower转为Candidate,并且向其他节点发起RequestVote RPC请求,这时选举有3种情况可能发生:

    发起RequestVote的节点收到n/2+1(过半数)个节点的投票,该节点将从Candidate状态变为Leader状态,开始向其他节点发送HeartBeat以保持Leader的正常状态

    如果收到投票请求后,该节点发现发起投票的节点Term大于自己,则该节点状态从Candidate转为Follower,否则保持Candidate状态,并且拒绝该投票请求

    选举期间发生了超时,则Term编号递增,重新发起选举
    在这里插入图片描述

    2.3.4 日志复制

    日志复制主要的作用就是用来保证节点的数据一致性与高可用性。

    当Leader被选举出来后,所有的事务操作都必须要经过Leader处理。这些事务操作成功后,将会被按顺序写入到LOG中,每个LOG都包含一个index编号。

    Leader在LOG发生变化后,通过HeartBeat将新的LOG同步到Follower上,Follower在接收到LOG后,再向Leader发送ACK信息,当Leader接到大多数(2/n+1)Follower的ACK信息后,将该LOG设置为已提交,并且Leader将LOG追加到本地磁盘中。

    同时Leader将在下一个HeartBeat中,通知所有的Follower将该LOG存储在各自的本地磁盘中。

    2.3.5 安全性

    安全性是用于确保每个节点都是按照相同的日志序列进行执行的安全机制。

    如果当某个Follower在同步Leader的日志时失败,但是未来该Follower又可能被选举为Leader时,就有可能导致前一个Leader已经commit的日志发生覆盖,这样就导致了节点执行不同序列的日志。

    Raft的安全性就是用于保证选举出来的Leader一定包含先前已经commit LOG 的机制,主要遵循的原则如下:

    每个Term 只能选举一个Leader;

    Leader的日志完整性,则当Candidate重新选举Leader时,新的Leader必须要包含先前已经commit的LOG;

    Candidate在选举新的Leader时,使用Term来保证LOG的完整性;

    3、分布式数据库数据一致性技术实现

    以国产原厂的分布式数据库SequoiaDB为例,SequoiaDB在多副本的部署中,采用Raft算法保证数据在多副本环境中保持一致。

    SequoiaDB集群中,总共包含3中角色节点,分别是协调节点、编目节点和数据节点。由于协调节点本身不存任何数据,所以只有编目节点和数据节点存在事务操作,换言之,编目分区组和数据分区组的副本同步采用Raft算法保证数据一致性。

    在这里插入图片描述

    3.1 编目节点和数据节点的事务日志介绍

    编目节点和数据节点由于都是需要存储数据的,并且在集群部署中该,为了确保数据的安全,都是建议采用分布式的方式进行部署,所以在数据同步中,需要采用Raft算法的基本原理进行数据同步。

    编目节点和数据节点在存储数据时,共包含两大部分,一个真实的数据文件,另一个是事务日志文件。
    在这里插入图片描述
    SequoiaDB的节点事务日志,默认情况下由20个64MB(总大小为1.25GB)的文件构成。节点的事务日志主要包含一个index编号和数据操作内容,index编号保持永远递增状态。

    另外,SequoiaDB节点的事务日志不会永久保存,而是当所有的事务日志写满后,再重新从第一个文件开始进行覆盖写入。

    3.2 编目分区组的数据一致性

    由于编目分区组是保存SequoiaDB集群的元信息,数据同步要求高,所以编目分区组的数据一致性要求为强一致性,即每次向编目分区组执行事务操作时,必须要确保所有的编目节点操作成功,才计算该操作执行成功,否则该事务操作将在整个编目分区组中回退事务日志,以保证分区组内的数据一致性。

    另外,编目分区组还有一个比较重要的特性,即编目分区组必须要存在主节点才能够正常工作,如果老的主节点宕机了,编目分区组暂时没有主节点,则该编目分区组不能够对外提供任何事务操作和数据查询操作。

    3.3 数据分区组的数据一致性

    数据分区组的数据一致性默认情况下为最终一致性性,即只要求主节点执行事务操作成功即视为操作成功,主节点将在未来异步同步ReplicaLOG到从节点上。

    3.4 主从节点的事务日志同步

    SequoiaDB的主从节点是通过事务日志同步来保证数据一致性的,并且主从节点的事务日志同步是单线程完成。

    如果当主节点和从节点的LSN差距为一条记录,则主节点会主动将最新的事务日志推送给从节点。

    如果主节点和从节点的LSN差距超过一条记录,则从节点会主动向主节点请求同步事务日志,主节点收到同步请求后,会将从节点的LSN号到主节点最新的LSN号对应的事务日志打包一次性发送给从节点。

    3.5 从节点日志重放

    当从节点获取到主节点推送过来的事务日志后,就会自动解析事务日志和重放。从节点在重放事务日志时,默认情况下会以10并发来重放事务日志。

    从节点在执行并发重放日志时有条件限制,即在集合的唯一索引个数<=1的情况下,INSERT、DELETE、UPDATE、LOB WRITE、LOBUPDATE、LOB REMOVE操作可以支持并发重放事务日志。从节点在做并发重放时,是通过记录的OID进行打散并发执行,这样就可以保证对相同记录的操作不会由于并发重放导致数据不一致。

    但是用户需要注意,从节点在重放事务日志时, DROP CL操作不能够支持并发重放。

    4、SequoiaDB数据一致性应用

    目前SequoiaDB数据分区组的数据一致性是基于集合级别进行配置的。用户在使用SequoiaDB过程中,可以随时调整数据一致性的强度。

    4.1 创建集合时指定

    在一个多副本的SequoiaDB集群中,集合默认的数据一致性行级别为“最终一致性”。用户可以在创建集合时显式指定该集合的“数据一致性强度”,例如可以在SequoiaDB Shell中执行以下命令

    db.CSNAME.createCL(“CLNAME”,{ReplSize:3})

    ReplSize参数填写范围
    在这里插入图片描述

    4.2 修改已经存在的集合

    如果集合在创建时没有设置“数据一致性”ReplSize参数,用户也可以对已经存在的集合进行修改,在SequoiaDB Shell修改命令如下

    db.CSNAME.CLNAME.alter({ReplSize:3})

    ReplSize的取值范围和创建集合时一致。

    4.3 如何查看集合的ReplSize参数

    如果用户希望检查当前集合的RepliSize参数值,可以通过数据库快照进行查看,在SequoiaDB Shell查看命令如下

    db.snapshot(SDB_SNAP_CATALOG,{}, {“Name”:null, “IsMainCL”:null,“MainCLName”:null, “ReplSize”:null})
    打印信息如下

    {

    “MainCLName”:“test.main2”,

    “Name”: “foo.bar2”,

    “IsMainCL”: null,

    “ReplSize”: null

    }

    {

    “IsMainCL”: true,

    “Name”: “test.main2”,

    “MainCLName”: null,

    “ReplSize”: null

    }

    {

    “Name”: “foo.tt”,

    “ReplSize”: 3,

    “IsMainCL”: null,

    “MainCLName”: null

    }

    5、总结

    分布式的数据库,通过Raft算法来确保在分布式情况上数据的一致性,并且编目分区组和数据分区组对数据一致性要求又有所不同,编目分区组始终要求的是数据在多副本请情况下数据强一致性,而数据分区组则可以由用户在创建集合时来执行数据一致性的强度,强度越高,数据安全性越好,但是执行的效率就会相对较差,反之依然。

    目前SequoiaDB在数据一致性场景上,用户的调整空间较大,可以根据不同的业务要求来调整数据一致性的强度,以满足业务或追求性能最优,或者数据最安全的技术要求。

    更多相关内容
  • 为了便于讨论问题,先简单介绍下数据一致性的基础理论。当更新操作完成之后,任何多个后续进程或者线程的访问都会返回最新的更新过的值。这种是对用户最友好的,就是用户上一次写什么,下一次就保证能读到什么。根据...
  • 保证分布式数据一致性的6种方案

    万次阅读 2018-07-30 17:17:07
    在电商等业务中,系统一般由多个独立的服务组成,如何解决分布式调用时候数据一致性?  具体业务场景如下,比如一个业务操作,如果同时调用服务 A、B、C,需要满足要么同时成功;要么同时失败。A、B、C 可能是多...

    问题的起源

    在电商等业务中,系统一般由多个独立的服务组成,如何解决分布式调用时候数据的一致性? 

    具体业务场景如下,比如一个业务操作,如果同时调用服务 A、B、C,需要满足要么同时成功;要么同时失败。A、B、C 可能是多个不同部门开发、部署在不同服务器上的远程服务。

    在分布式系统来说,如果不想牺牲一致性,CAP 理论告诉我们只能放弃可用性,这显然不能接受。为了便于讨论问题,先简单介绍下数据一致性的基础理论。

    强一致

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

    弱一致性

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

    最终一致性

    弱一致性的特定形式。系统保证在没有后续更新的前提下,系统最终返回上一次更新操作的值。在没有故障发生的前提下,不一致窗口的时间主要受通信延迟,系统负载和复制副本的个数影响。DNS 是一个典型的最终一致性系统。

    在工程实践上,为了保障系统的可用性,互联网系统大多将强一致性需求转换成最终一致性的需求,并通过系统执行幂等性的保证,保证数据的最终一致性。但在电商等场景中,对于数据一致性的解决方法和常见的互联网系统(如 MySQL 主从同步)又有一定区别,群友的讨论分成以下 6 种解决方案。

    1. 规避分布式事务——业务整合

    业务整合方案主要采用将接口整合到本地执行的方法。拿问题场景来说,则可以将服务 A、B、C 整合为一个服务 D 给业务,这个服务 D 再通过转换为本地事务的方式,比如服务 D 包含本地服务和服务 E,而服务 E 是本地服务 A ~ C 的整合。

    优点:解决(规避)了分布式事务。

    缺点:显而易见,把本来规划拆分好的业务,又耦合到了一起,业务职责不清晰,不利于维护。

    由于这个方法存在明显缺点,通常不建议使用。

    2. 经典方案 - eBay 模式

    此方案的核心是将需要分布式处理的任务通过消息日志的方式来异步执行。消息日志可以存储到本地文本、数据库或消息队列,再通过业务规则自动或人工发起重试。人工重试更多的是应用于支付场景,通过对账系统对事后问题的处理。

    消息日志方案的核心是保证服务接口的幂等性。

    考虑到网络通讯失败、数据丢包等原因,如果接口不能保证幂等性,数据的唯一性将很难保证。

    eBay 方式的主要思路如下。

    Base:一种 Acid 的替代方案

    此方案是 eBay 的架构师 Dan Pritchett 在 2008 年发表给 ACM 的文章,是一篇解释 BASE 原则,或者说最终一致性的经典文章。文中讨论了 BASE 与 ACID 原则在保证数据一致性的基本差异。

    如果 ACID 为分区的数据库提供一致性的选择,那么如何实现可用性呢?答案是

    BASE (basically available, soft state, eventually consistent)

    BASE 的可用性是通过支持局部故障而不是系统全局故障来实现的。下面是一个简单的例子:如果将用户分区在 5 个数据库服务器上,BASE 设计鼓励类似的处理方式,一个用户数据库的故障只影响这台特定主机那 20% 的用户。这里不涉及任何魔法,不过它确实可以带来更高的可感知的系统可用性。

    文章中描述了一个最常见的场景,如果产生了一笔交易,需要在交易表增加记录,同时还要修改用户表的金额。这两个表属于不同的远程服务,所以就涉及到分布式事务一致性的问题。

     

     

    文中提出了一个经典的解决方法,将主要修改操作以及更新用户表的消息放在一个本地事务来完成。同时为了避免重复消费用户表消息带来的问题,达到多次重试的幂等性,增加一个更新记录表 updates_applied 来记录已经处理过的消息。

     

     

    系统的执行伪代码如下

     

     

    (点击可全屏缩放图片)

    基于以上方法,在第一阶段,通过本地的数据库的事务保障,增加了 transaction 表及消息队列 。

    在第二阶段,分别读出消息队列(但不删除),通过判断更新记录表 updates_applied 来检测相关记录是否被执行,未被执行的记录会修改 user 表,然后增加一条操作记录到 updates_applied,事务执行成功之后再删除队列。

    通过以上方法,达到了分布式系统的最终一致性。进一步了解 eBay 的方案可以参考文末链接。

    3. 去哪儿网分布式事务方案

    随着业务规模不断地扩大,电商网站一般都要面临拆分之路。就是将原来一个单体应用拆分成多个不同职责的子系统。比如以前可能将面向用户、客户和运营的功能都放在一个系统里,现在拆分为订单中心、代理商管理、运营系统、报价中心、库存管理等多个子系统。

    拆分首先要面临的是什么呢?

    最开始的单体应用所有功能都在一起,存储也在一起。比如运营要取消某个订单,那直接去更新订单表状态,然后更新库存表就 ok 了。因为是单体应用,库在一起,这些都可以在一个事务里,由关系数据库来保证一致性。

    但拆分之后就不同了,不同的子系统都有自己的存储。比如订单中心就只管理自己的订单库,而库存管理也有自己的库。那么运营系统取消订单的时候就是通过接口调用等方式来调用订单中心和库存管理的服务了,而不是直接去操作库。这就涉及一个『分布式事务』的问题。 

     

     

    分布式事务有两种解决方式

    1. 优先使用异步消息。

    上文已经说过,使用异步消息 Consumer 端需要实现幂等。

    幂等有两种方式,一种方式是业务逻辑保证幂等。比如接到支付成功的消息订单状态变成支付完成,如果当前状态是支付完成,则再收到一个支付成功的消息则说明消息重复了,直接作为消息成功处理。

    另外一种方式如果业务逻辑无法保证幂等,则要增加一个去重表或者类似的实现。对于 producer 端在业务数据库的同实例上放一个消息库,发消息和业务操作在同一个本地事务里。发消息的时候消息并不立即发出,而是向消息库插入一条消息记录,然后在事务提交的时候再异步将消息发出,发送消息如果成功则将消息库里的消息删除,如果遇到消息队列服务异常或网络问题,消息没有成功发出那么消息就留在这里了,会有另外一个服务不断地将这些消息扫出重新发送。

    2. 有的业务不适合异步消息的方式,事务的各个参与方都需要同步的得到结果。这种情况的实现方式其实和上面类似,每个参与方的本地业务库的同实例上面放一个事务记录库。

    比如 A 同步调用 B,C。A 本地事务成功的时候更新本地事务记录状态,B 和 C 同样。如果有一次 A 调用 B 失败了,这个失败可能是 B 真的失败了,也可能是调用超时,实际 B 成功。则由一个中心服务对比三方的事务记录表,做一个最终决定。假设现在三方的事务记录是 A 成功,B 失败,C 成功。那么最终决定有两种方式,根据具体场景:

    1. 重试 B,直到 B 成功,事务记录表里记录了各项调用参数等信息;

    2. 执行 A 和 B 的补偿操作(一种可行的补偿方式是回滚)。

    对 b 场景做一个特殊说明:比如 B 是扣库存服务,在第一次调用的时候因为某种原因失败了,但是重试的时候库存已经变为 0,无法重试成功,这个时候只有回滚 A 和 C 了。

    那么可能有人觉得在业务库的同实例里放消息库或事务记录库,会对业务侵入,业务还要关心这个库,是否一个合理的设计?

    实际上可以依靠运维的手段来简化开发的侵入,我们的方法是让 DBA 在公司所有 MySQL 实例上预初始化这个库,通过框架层(消息的客户端或事务 RPC 框架)透明的在背后操作这个库,业务开发人员只需要关心自己的业务逻辑,不需要直接访问这个库。

    总结起来,其实两种方式的根本原理是类似的,也就是将分布式事务转换为多个本地事务,然后依靠重试等方式达到最终一致性

    4. 蘑菇街交易创建过程中的分布式一致性方案

    交易创建的一般性流程

    我们把交易创建流程抽象出一系列可扩展的功能点,每个功能点都可以有多个实现(具体的实现之间有组合/互斥关系)。把各个功能点按照一定流程串起来,就完成了交易创建的过程。 

     

     

    面临的问题

    每个功能点的实现都可能会依赖外部服务。那么如何保证各个服务之间的数据是一致的呢?比如锁定优惠券服务调用超时了,不能确定到底有没有锁券成功,该如何处理?再比如锁券成功了,但是扣减库存失败了,该如何处理?

    方案选型

    服务依赖过多,会带来管理复杂性增加和稳定性风险增大的问题。试想如果我们强依赖 10 个服务,9 个都执行成功了,最后一个执行失败了,那么是不是前面 9 个都要回滚掉?这个成本还是非常高的。

    所以在拆分大的流程为多个小的本地事务的前提下,对于非实时、非强一致性的关联业务写入,在本地事务执行成功后,我们选择发消息通知、关联事务异步化执行的方案。

    消息通知往往不能保证 100% 成功;且消息通知后,接收方业务是否能执行成功还是未知数。前者问题可以通过重试解决;后者可以选用事务消息来保证。

    但是事务消息框架本身会给业务代码带来侵入性和复杂性,所以我们选择基于 DB 事件变化通知到 MQ 的方式做系统间解耦,通过订阅方消费 MQ 消息时的 ACK 机制,保证消息一定消费成功,达到最终一致性。由于消息可能会被重发,消息订阅方业务逻辑处理要做好幂等保证。

    所以目前只剩下需要实时同步做、有强一致性要求的业务场景了。在交易创建过程中,锁券和扣减库存是这样的两个典型场景。

    要保证多个系统间数据一致,乍一看,必须要引入分布式事务框架才能解决。但引入非常重的类似二阶段提交分布式事务框架会带来复杂性的急剧上升;在电商领域,绝对的强一致是过于理想化的,我们可以选择准实时的最终一致性。

    我们在交易创建流程中,首先创建一个不可见订单,然后在同步调用锁券和扣减库存时,针对调用异常(失败或者超时),发出废单消息到MQ。如果消息发送失败,本地会做时间阶梯式的异步重试;优惠券系统和库存系统收到消息后,会进行判断是否需要做业务回滚,这样就准实时地保证了多个本地事务的最终一致性。

     

     

     5. 支付宝及蚂蚁金融云的分布式服务 DTS 方案

    业界常用的还有支付宝的一种 xts 方案,由支付宝在 2PC 的基础上改进而来。主要思路如下,大部分信息引用自官方网站。

    分布式事务服务简介

    分布式事务服务 (Distributed Transaction Service, DTS) 是一个分布式事务框架,用来保障在大规模分布式环境下事务的最终一致性。DTS 从架构上分为 xts-client 和 xts-server 两部分,前者是一个嵌入客户端应用的 JAR 包,主要负责事务数据的写入和处理;后者是一个独立的系统,主要负责异常事务的恢复。

    核心特性

    传统关系型数据库的事务模型必须遵守 ACID 原则。在单数据库模式下,ACID 模型能有效保障数据的完整性,但是在大规模分布式环境下,一个业务往往会跨越多个数据库,如何保证这多个数据库之间的数据一致性,需要其他行之有效的策略。在 JavaEE 规范中使用 2PC (2 Phase Commit, 两阶段提交) 来处理跨 DB 环境下的事务问题,但是 2PC 是反可伸缩模式,也就是说,在事务处理过程中,参与者需要一直持有资源直到整个分布式事务结束。这样,当业务规模达到千万级以上时,2PC 的局限性就越来越明显,系统可伸缩性会变得很差。基于此,我们采用 BASE 的思想实现了一套类似 2PC 的分布式事务方案,这就是 DTS。DTS在充分保障分布式环境下高可用性、高可靠性的同时兼顾数据一致性的要求,其最大的特点是保证数据最终一致 (Eventually consistent)。

    简单的说,DTS 框架有如下特性:

    • 最终一致:事务处理过程中,会有短暂不一致的情况,但通过恢复系统,可以让事务的数据达到最终一致的目标。

    • 协议简单:DTS 定义了类似 2PC 的标准两阶段接口,业务系统只需要实现对应的接口就可以使用 DTS 的事务功能。

    • 与 RPC 服务协议无关:在 SOA 架构下,一个或多个 DB 操作往往被包装成一个一个的 Service,Service 与 Service 之间通过 RPC 协议通信。DTS 框架构建在 SOA 架构上,与底层协议无关。

    • 与底层事务实现无关: DTS 是一个抽象的基于 Service 层的概念,与底层事务实现无关,也就是说在 DTS 的范围内,无论是关系型数据库 MySQL,Oracle,还是 KV 存储 MemCache,或者列存数据库 HBase,只要将对其的操作包装成 DTS 的参与者,就可以接入到 DTS 事务范围内。

    以下是分布式事务框架的流程图 

     

     


    实现

    1. 一个完整的业务活动由一个主业务服务与若干从业务服务组成。

    2. 主业务服务负责发起并完成整个业务活动。

    3. 从业务服务提供 TCC 型业务操作。

    4. 业务活动管理器控制业务活动的一致性,它登记业务活动中的操作,并在活动提交时确认所有的两阶段事务的 confirm 操作,在业务活动取消时调用所有两阶段事务的 cancel 操作。”

    与 2PC 协议比较

    1. 没有单独的 Prepare 阶段,降低协议成本

    2. 系统故障容忍度高,恢复简单

    6. 农信网数据一致性方案

    1. 电商业务

    公司的支付部门,通过接入其它第三方支付系统来提供支付服务给业务部门,支付服务是一个基于 Dubbo 的 RPC 服务。

    对于业务部门来说,电商部门的订单支付,需要调用

    1. 支付平台的支付接口来处理订单;

    2. 同时需要调用积分中心的接口,按照业务规则,给用户增加积分。

    从业务规则上需要同时保证业务数据的实时性和一致性,也就是支付成功必须加积分。

    我们采用的方式是同步调用,首先处理本地事务业务。考虑到积分业务比较单一且业务影响低于支付,由积分平台提供增加与回撤接口。

    具体的流程是先调用积分平台增加用户积分,再调用支付平台进行支付处理,如果处理失败,catch 方法调用积分平台的回撤方法,将本次处理的积分订单回撤。

     

     

    (点击图片可以全屏缩放)

    2. 用户信息变更

    公司的用户信息,统一由用户中心维护,而用户信息的变更需要同步给各业务子系统,业务子系统再根据变更内容,处理各自业务。用户中心作为 MQ 的 producer,添加通知给 MQ。APP Server 订阅该消息,同步本地数据信息,再处理相关业务比如 APP 退出下线等。

    我们采用异步消息通知机制,目前主要使用 ActiveMQ,基于 Virtual Topic 的订阅方式,保证单个业务集群订阅的单次消费。

     

     

    总结

    分布式服务对衍生的配套系统要求比较多,特别是我们基于消息、日志的最终一致性方案,需要考虑消息的积压、消费情况、监控、报警等。

    参考资料

    • Base: An Acid Alternative (eBay 方案)

    In partitioned databases, trading some consistency for availability can lead to dramatic improvements in scalability.

    英文版 : http://queue.acm.org/detail.cfm?id=1394128 

    中文版: http://article.yeeyan.org/view/167444/125572

     

    原文地址:https://www.cnblogs.com/soundcode/p/5590710.html

     

    展开全文
  • 在大数据场景下,分布式数据库的数据一致性管理是其最重要的内核技术之一,也是保证分布式数据库满足数据库最基本的ACID特性中的“一致性”(Consistency)的保障,在分布式技术发展下,数据一致性的解决方法和技术也...
  • 分布式系统数据一致性解决方案

    千次阅读 2022-03-03 21:10:14
    本文讨论的都是互联网企业在分布式架构下如何应对数据一致性问题的。 2.典型的一致性问题 案例1:下单和减库存的一致性 下单减库存有一致性的需求,如果下单了但是没减库存造成的结果是超卖;如果减库存了但下单...

    1.背景

    微服务架构是一把双刃剑,我们在享受微服务拆分带来好处的同时,势必会遇到数据模型和服务之间不一致的问题。本文讨论的都是互联网企业在分布式架构下如何应对数据一致性问题的。

    2.典型的一致性问题

    案例1:下单和减库存的一致性

    下单减库存有一致性的需求,如果下单了但是没减库存造成的结果是超卖;如果减库存了但下单失败会导致少卖。

    案例2:缓存和数据库的数据一致性

    电商系统一般会将热点数据缓存来减少数据库访问压力,这要求缓存和数据库数据是一致的,如果数据库数据发生变更但同步到缓存失败,这时就产生了缓存何数据库数据的不一致。

    案例3:两系统协调的一致性

    其实上面两个案例都可以归结为此案例,系统是上下游的关系,由于超时等原因可能导致两系统数据的状态不对。

    3.一致性理论

    ACID原理

    即关系型数据库的事务特性:原子性、一致性、隔离性和持久性。ACID这里不多说,一般核心交易系统都要有强一致性的事务要求,因此在做技术选型时,核心数据基本也只考虑关系型数据库。

    CAP原理

    CAP其实是一种权衡平衡的思想,用于指导在系统可用性设计、数据一致性设计时做权衡取舍。CAP,即一致性、可用性、分区容忍性。一致性强调在同一时刻副本一致,可用性指的是服务在有限的时间内完成处理并响应,分区容忍性说的是分布式系统本身的特点可以独立运行并提供服务。

    4.一致性协议

    说到一致性协议,大家肯定都听过两阶段协议协议、三阶段提交协议、Paxos协议、Raft协议等。这里我们简单比较一下。

    两阶段提交协议

    两阶段提交协议,顾名思义分两个阶段:准备阶段(投票反馈阶段)和 提交阶段(执行阶段)。准备阶段参与者在本地执行事务,在本地写redo\undo log,但不提交,有点万事俱备只欠东风的态势。提交阶段由协调者发出。

    两阶段协议提交存在的问题还挺多,具体包含:

    1. 阻塞问题,所有参与者必须收到协调者发起的指令才会提交,否则资源会被锁定,但由于不可靠的网络,协调者可能无法收到所有反馈,参与者也可能无法接收到指令。
    2. 单点故障,如果协调者宕机,参与者没有协调者指挥就会一致阻塞。
    3. 数据不一致,协调者发出的指令可能导致部分参与者收到,部分参与者由于网络原因未收到,有数据不一致的风险。

    三阶段提交协议

    针对两阶段提交的一些问题,三阶段提交做了一些改进,比如:

    1. 通过超时机制解决阻塞问题。
    2. 通过增加询问环节降低锁资源导致阻塞的概率。

    三阶段即canCommit、preCommit、doCommit。三阶段提交解决了资源阻塞问题,但仍然存在单点故障和数据不一致的问题。

    Raft投票协议

    前面说的两阶段提交协议和三阶段提交协议都存在单点问题和数据不一致的风险。为此Raft、Paxos、Zab使用的机制都是大多数的投票机制来解决单点问题和消灭不一致风险。我们以Raft协议来说,它分两个过程:

    1. Leader选举。
    2. 日志复制。

    首先,Leader选举是用于解决单点问题。一开始所有的节点都是追随者,当节点感知不到Leader存在时就会转变身份称为竞选者,为了防止出现多个竞选者竞争Leader的局面出现,每个节点都会等待一个随机时间才能称为竞选者。竞选者发起投票,当获得大多数同意反馈时则称为了Leader。Leader会定期对Follower发起心跳以通知自己的存活。通过心跳+投票机制防止了单点故障。

    然后,我们看看Raft是如何解决不一致问题的,这里使用到一个单调递增的序列号,通过序列号 + 多数投票机制保证数据一致性。

    Raft一致性原理可参考我原来写过的《全面理解Raft协议》一文。

    TCC

    TCC是互联网公司业务系统保证数据一致性的一种常见方法,它将任务拆分为Try、Confirm、Cancel三个过程,本质上Try、Confirm思想和两阶段是一致的,只是TCC增加了逆向过程,因此具有一定的修复能力。但TCC还是存在不一致的风险,面对这个问题,商业公司一般做法是保证最终一致,通过一些自动化补偿手段尽可能做到数据一致,且不用人工干预。

    小结:两阶段提交协议是所有一致性协议的基础,它是一个强一致性协议,但可用性太差;三阶段提交协议改善了两阶段提交协议,但还是为解决单点问题和存在不一致的风险;可靠的、强一致性协议最后是通过Raft、Paxos等投票协议做成的。一致性协议都有一个共同的问题,就是实现复杂,性能不好,更多用于HA组件,而非业务系统本身。

    5.最终一致性模式

    业务系统对一致性大多数情况没那么高,更多强调高可用,因此,多数业务系统强调最终一致性,这其实也是在CAP权衡下倾向于A。我们本节来分析一下最终一致性方案。最终一致性都强调写操作失败后进行补偿补救,常见的最终一致性有4种形态,我们依次分析分析。

    查询模式

    对于任何写操作,API设计时都要提供对应的查询或批量查询接口。如下图所示。

    如下订单操作

    interface OrderService {
     boolean submitOrder(int ticketId, OrderEntity order);
     Order queryOrder(int ticketId);
    }

    重试+逆向模式

    即当写操作失败了上游系统提供重试接口和逆向取消接口。上游系统需要保障重试写接口与逆向接口的幂等性。

    举例:

    interface OrderService {
     boolean submitOrder(int ticketId, OrderEntity order);
     boolean cancelOrder(int ticketId);
    }

    补救任务模式

    写操作失败后,同步创建补救任务,通过定时执行补救任务来达到最终一致。如果补救任务是一个消息通知型任务,有时会将写操作和通知任务放在一个事务中来保证写操作成功通知任务一定成功,并最终能够执行。

    异步消息模式

    该模式下通过消息队列来保证最终一致性,为了保证消息的可靠性,可以在业务系统发送消息前将写操作和消息持久化做成事务,然后异步通过消息队列中间件发送消息。该模式可能会出现重复消息,因此消息消费方需要保证幂等性。

    6.典型案例的一致性方案

    上一节我们已经讲过互联网公司在CA中倾向了高可用,选择了高可用最终一致性。因此典型案例的一致性方案不会是使用一致性协议的强一致性方案。

    案例1:下单和减库存的一致性

    由于允许短暂的不一致,因此库存接口可提供扣减写接口、查询接口以及逆向增接口。

    interface InventoryService {
     boolean deduct(int ticketId, int skuId);
     OpLog queryDeductLog(int ticketId);
     boolean cancelDeduct(int ticketId, int skuId);
    }

    客户端可通过“重试 + 逆向”模式同步方式进行一致性保证,也可以走异步补救任务或异步消息进行补救。

    电商平台还会采用一种更加严格的一致性手段,扣减库存分两个阶段:锁库存、确认减库存。为了保证失败后能够回滚还会解锁库存。扣减库存其实思想和两阶段提交是一样的,客户端其实就是协调者角色,客户端的可用性由系统监控告警和运维人员保障,参与者就是服务端,这里只有一个参与者。当然为了保证最终一致性还会有重试、逆向回滚以及异步补偿任务、异步消息等方式。

    案例2:缓存和数据库的数据一致性

    缓存是为了应对高并发的读请求,但当数据发生变更是需要将变化同步到缓存。

    首先,我们这里并不探讨强一致,因此在高并发时很短暂的不一致是可以接受的。因此先写数据库成功,但写缓存还未完成而操作从缓存读到旧数据这种情况是可以接受的。

    其次,我们简单说下是淘汰缓存还是更新缓存的问题,在两线程并发修改同一对象写入顺序不确认,采用更新缓存方式问题其实很多,因此我们就不自添烦恼了,淘汰缓存虽然可能造成一次mismatch,但其实还好。因此我们的结论是淘汰缓存。

    最后,我们探讨一次写数据库和缓存的先后顺序问题。由于写数据库和写数据库有一个先后顺序,这样就可能导致前一个写操作成功而后一个写操作失败的情况出现,不管是先写数据库先还是写缓存先,这种情况都会出现长时间不一致性的情况出现,因此需要处理这种异常情况。

    1. 淘汰缓存成功、写数据库失败

    其实这时一个伪问题,我们更新数据当然希望持久生效,所以如果先淘汰缓存,写数据库失败当然需要千方百计保证写数据库成功,如果网络本省就不可用怎么写都失败,这样就违背我们的初衷,因此很显然是必须先操作数据库而不是缓存。

    2.写数据库成功、淘汰缓存失败

    如果操作数据库成功,淘汰缓存失败导致缓存和数据库不一致,因此可以通过我们前面提到的补救措施,比如重试、补救任务、异步消息来保证最终一致性。关键还是变更的数据持久生效!!!

    小结:针对缓存和数据库一致性的策略是:先写数据库,再淘汰缓存。缓存和数据库的不一致可通过最终一致性模式解决。如果强一致性有要求,可将写数据库和淘汰缓存做到一个事务中,当淘汰缓存失败则回滚数据库变更,这样缓存和数据库数据还是一致的。

    总结

    本文较全面的分析了分布式系统的数据一致性模式。我们首先介绍了两个重要的原理:ACID和CAP,理解这两个原理对于理解事务和分布式事务很重要,读者朋友细细体会以下ACID的事务特征和CAP中CA的权衡思想。文章介绍了强一致性协议P:两阶段协议、三阶段协议和典型的投票协议。分布式架构下理解CAP很重要,目前互联网公司倾向于高可用最终一致性方案,本文介绍了4种常用的最终一致性模式,文章最后针对“下单和减库存”以及“缓存和数据库一致性”给出了解决方案,希望读者朋友看完之后有帮助。

    展开全文
  • 分布式系统:数据一致性解决方案

    千次阅读 2020-12-14 23:02:27
    点击上方蓝色字体,选择“设为星标”回复”资源“获取更多资源大数据技术与架构点击右侧关注,大数据开发领域最强公众号!大数据真好玩点击右侧关注,大数据真好玩!在分布式系统中,随着系统架构演进...

    点击上方蓝色字体,选择“设为星标

    回复”资源“获取更多资源

    大数据技术与架构

    点击右侧关注,大数据开发领域最强公众号!

    大数据真好玩

    点击右侧关注,大数据真好玩!

    在分布式系统中,随着系统架构演进,原来的原子性操作会随着系统拆分而无法保障原子性从而产生一致性问题,但业务实际又需要保障一致性,下面我从学习和实战运用总结一下分布式一致性解决方案。

    1. CAP & Base理论

    

    CAP定理指的是在一个分布式系统中,一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)。这三个要素最多只能同时实现两点,不可能三者兼顾:

    • 一致性:在分布式系统中的所有数据备份,在同一时刻是否同样的值。

    • 分区容错性:可靠性,无论应用程序或系统发生错误,还是用户以意外或错误的方式使用,软件系统都能继续运行。

    • 可用性:在集群中一部分节点故障后,集群整体是否还能响应客户端的读写请求。

    

    

    CAP理论3选2是伪命题,实际上必须从A和C选择一个和P组合,更进一步基本上都会选择A,相比一致性,系统一旦不可用或不可靠都可能会造成整个站点崩溃,所以一般都会选择AP。但是不一致的问题也不能忽略,使用最终一致是比较好的办法。

    

    BASE理论是对CAP中一致性和可用性权衡的结果,其来源于对大规模互联网系统分布式实践的总结, 是基于CAP定理逐步演化而来的。BASE理论的核心思想是:即使无法做到强一致性,但每个应用都可以根据自身业务特点,采用适当的方式来使系统达到最终一致性。接下来看一下BASE中的三要素:

    • 基本可用(Basically Available):基本可用是指分布式系统在出现不可预知故障的时候,允许损失部分可用性。注意,这绝不等价于系统不可用。比如:

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

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

    • 软状态(Soft State):软状态指允许系统中的数据存在中间状态,并认为该中间状态的存在不会影响系统的整体可用性,即允许系统在不同节点的数据副本之间进行数据同步的过程存在延时。

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

    

    最终一致的核心做法就是通过记录对应操作并在操作失败时不断进行重试直到成功为止。

    2. 重试

    在出现一致性问题时如果系统的并发或不一致情况较少,可以先使用重试来解决。

    

    在调用Service B超时或失败时进行重试:

    • 同步调用,捕获异常重新调用Service B。

    • 异步消息,捕获异常发送延迟消息重新调用Service B。

    • 异步线程,捕获异常开启异步线程重新调用Service B。

    

    如果重试还是不能解决问题,那么需要使用分布式事务来解决。

    3. 分布式事务

    对于分布式一致性问题可以采用分布式事务来解决。

    3.1 2PC-XA协议

    XA事务由一个或多个资源管理器(Resource Managers)、一个事务管理器(Transaction Manager)以及一个应用程序(Application Program)组成。

    • 资源管理器(RM):参与者。提供访问事务资源的方法。通常一个数据库就是一个资源管理器。

    • 事务管理器(TM):协调者。分配标识符,监视事务的进度,并负责事务完成和故障恢复。

    • 应用程序(AP):发起者。定义事务的边界,制定全局事务中的操作。

    

    整个过程分为2个阶段:准备(prepare)和提交(commit),prepare前需要先执行对应的DML操作。

    

    

    Mysql XA事务语句:

    
    
    注:执行前需要先生成全局唯一的xid
    
    
    XA {START|BEGIN} xid [JOIN|RESUME]
    DML操作
    XA END xid [SUSPEND [FOR MIGRATE]]
    XA PREPARE xid //1.准备
    XA COMMIT xid [ONE PHASE] //2.提交
    XA ROLLBACK xid
    XA RECOVER
    

    简单的事例:

    
    
    //准备前阶段
    mysql> XA START 'xatest';
    Query OK, 0 rows affected (0.00 sec)
    
    
    mysql> INSERT INTO mytable (i) VALUES(10);
    Query OK, 1 row affected (0.04 sec)
    
    
    mysql> XA END 'xatest';
    Query OK, 0 rows affected (0.00 sec)
    //准备
    mysql> XA PREPARE 'xatest';
    Query OK, 0 rows affected (0.00 sec)
    //提交
    mysql> XA COMMIT 'xatest';
    Query OK, 0 rows affected (0.00 sec)
    

    XA看起来很美好,但还是存在一些问题:

    • commit丢失/超时导致数据不一致。A commit成功,B commit时网络超时导致数据库未收到commit请求。

    • 性能低。所有事务参与者在等待其它参与者响应的时候都处于同步阻塞状态。

    • 主备数据不一致。

    • 协调者单点故障,在任意阶段协调者发生故障都会导致分布式事务无法进行。

    

    3.2 3PC

    3PC通过在参与者加入超时机制解决2PC中的协调者单点带来的事务无法进行的问题,但是性能和一致性仍没有解决。

    

    3.3 TCC

    

    这样看下来强一致是很难做了,还是最终一致把。。。

    

    TCC是通过最终一致来达到分布式事务的效果,即:在短时间内无法保证一致性,但最终会一致。核心分为2个阶段:1.Try  2.Confirm or Cancel。先尝试(Try)操作数据,如果都成功则全部确认(Confirm)该修改,如果有任意一个尝试失败,则全部取消(Cancel)。简单点说就是增加了中间态和可回改能力。

    

    

    通过重试机制保障Confirm和Cancel一定能成功。TCC解决了性能问题,但是业务系统想要实现对业务代码的侵入性很大,可以学习一下阿里GTS是如何做的。

    

    3.4 事务管理器

    在实际运用中事务管理器(TM)一般是由应用程序(AP)兼职实现的,这样对业务代码侵入性大,最好是把TM做成中间层。接下来详细看一下TM的职责:协调者。分配标识符,监视事务的进度,并负责事务完成和故障恢复。TM需要具备持久化能力才能完成监控、故障恢复和协调,整个协调过程可以分为3个阶段:

    • 准备阶段:向TM注册全局事务并获取到全局唯一XID,这一步需要定义好事务的范围。

    • 执行阶段:应用程序AP执行业务功能操作自己的RM,全部执行完毕后向TM commit,如果无失败则整个事务成功。

    • 确认/回滚阶段:如果第2步出现异常会触发该阶段,TM咨询各个AP对应操作是否成功,如果成功则commit,如果失败则调用AP进行rollback。

    

    下面简单介绍几种实现方式。

    3.4.1 本地事务管理器

    对于简单的业务可能只要保障2个数据库之间的一致,这样在本地实现事务管理器比较快成本也不高。

    

    

    1. 1. 在做业务逻辑之前把对应事件添加到本地event表中(记录订正时所需要的关键数据)

    2. 2. 执行业务逻辑

    3. 1.本地业务逻辑,操作表数据等等

    4. 2.RPC调用其他服务

    5. 3.修改event状态为确认

    6. 4. 如果第2步不成功,则event状态还是预提交,通过定时任务捞取再执行订正逻辑

    7. 5. 检查业务逻辑中的操作是否完成,如未完成则执行订正逻辑

    8. 1.本地业务逻辑是否执行成功

    9. 2.RPC调用其他服务是否执行成功

    10. 6.返回订正结果

    11. 1.成功则修改event为确认提交

    12. 2.未成功则不操作,等待轮询订正

    3.4.2 外部事务管理器

    阿里GTS:https://help.aliyun.com/document_detail/157850.html

    3.5 DB和MQ之间的一致性

    

    在实际场景中,业务系统对本地DB数据变更后会广播对应的消息,消费者消费消息做自己的业务逻辑,按正常逻辑消息会在数据库变更后发出,如果消息发送超时且失败那么DB和MQ之间就产生了不一致问题,如何解决呢?使用可靠消息来解决,核心逻辑保证消息从投递到消费的过程中不会丢失:生产者confirm、消费者ack和持久化。理论上只要使用生产者确认机制即可,但是不使用消费者ack则没有意义。消费者需要开启手动ack同时做到幂等消费,MQ需要通过将exchange、queue和message进行持久化来保证消息不丢失,生产者则需要通过确认机制保证消息一定投递到MQ种,接下来重点讲解一下生产者确认机制。

    

    confirm机制是在消息投递到所有匹配的queue之后发送确认消息给生产者,这样生产者就知道消息投递成功,但是由于消息是在DB操作之后发出的,生产者必须增加记录表来记录消息投递状态,如果投递成功就在收到确认消息时把记录标记为投递成功,如果长时间未收到确认消息则大概率是消息丢失了,再定时重新投递,这样就可以保证消息最终一定能投递成功。核心逻辑其实就是通过全局事务ID来标识DB操作和MQ消息是在一个分布式事务中的。

    

    疑点:在学习RabbitMQ confirm机制时发现生产者接收到的确认消息只有消息ID,这个消息ID不能作为全局事务ID,所以无法解决DB和MQ之间的一致性问题,后续再看看其它MQ产品是怎么做的。

    

    上面的方式需要业务系统维护消息状态,这部分可以交给中间件来实现,实现逻辑会变得不一样。

    

    

    预投递的消息不会分发到queue中,只有在接收到确认投递的请求后才会进行投递,如果确认操作因为网络异常失败了,MQ在过一段时间之后主动询问业务系统该消息是否可投递(失败不断重试),这样就能在异常时做到最终一致,不过依赖MQ产品的能力。

    3.6 DB和缓存之间的一致性

    DB和缓存之间同样也存在不一致问题,先写DB再写缓存如果缓存写失败就不一致了,同样的需要重试更新缓存来做最终一致。方法可以参考“2.重试”部分,如果一定要保证重试不丢失可以用可靠消息或本地task表来记录重试操作,有条件的可以使用DB DRC消息对业务的侵入会小一些。需要注意的是同步更新和异步更新同时使用时可能会产生更新覆盖的问题,加上毫秒级的时间戳或版本号来丢弃旧的更新。

    4. 兜底核对

    虽然有了分布式事务,但是在实际场景中可能会因为bug导致数据不一致,这时需要兜底来做最后一道防线,通过定时核对数据是否一致,如不一致手动/自动进行订正。

    4.1 系统自核对

    如果系统数量和数据量不多的情况下可以由业务系统自行核对,通过发送延迟消息自消费或监听其他系统消息做相关数据核对并进行订正。

    

    4.2 搭建核对系统

    在核对工作繁多的情况下,由业务系统自己核对会存在很多耦合,这时可以选择搭建独立的核对系统进行核对和订正。

    

    1.监听drc消息

    

    

    2.监听业务消息

    

    参考:

    • 阿里GTS:https://help.aliyun.com/document_detail/157850.html?spm=a2c4g.11186623.6.554.47ae4df4Zy6hBI

    • 饿了么DRC:https://zhuanlan.zhihu.com/p/34958596

    • Mysql XA:https://dev.mysql.com/doc/refman/8.0/en/xa-statements.html

    版权声明:

    本文为大数据技术与架构整理,原作者独家授权。未经原作者允许转载追究侵权责任。

    编辑|冷眼丶

    微信公众号|import_bigdata

    欢迎点赞+收藏+转发朋友圈素质三连

    文章不错?点个【在看】吧! ????

    展开全文
  • 如何保证分布式系统数据一致性

    万次阅读 多人点赞 2018-12-24 10:26:05
    面试的时候,有面试官问到:选取你比较熟悉的项目,谈谈如何在做容灾负载的时候数据一致性问题,具体点比如你里面的派单,如何保证一个司机不在同一时间内接到两个订单,然后保证实时性?  一般的解决方案是在派单...
  • 分布式事务数据一致性解决方案

    千次阅读 2020-09-03 01:01:53
    2PC 两阶段提交 由一个事务协调器器去通知各事务执行者准备事务、提交或回滚事务,它解决了数据一致性问题,但是通信时间、资源锁定时间太长,系统的可用性受到影响 利用RocketMq的消息事务机制,将生产者本地...
  • 分布式一致性协议

    千次阅读 2022-03-22 23:37:11
    分布式一致性协议主要分为单主协议,多主协议。它们的核心区别在于是否允许多个节点发起写操作,单主协议只允许由主节点发起写操作,因此它可以保证操作有序性,一致性更强
  • #资源达人分享计划#
  • 分布式下的数据一致性问题

    万次阅读 多人点赞 2020-07-31 14:03:53
    分布式下的数据一致性问题 CAP原则 在分布式系统要满足CAP原则,一个提供数据服务的存储系统无法同时满足:数据一致性、数据可用性、分区耐受性。 C数据一致性:所有应用程序都能访问到相同的数据。 A数据可用性:...
  • 1、数据一致性,往往指的是缓存和数据库的一致性。 2、事务的一致性,和原子性类似,都是从一个状态变到另一个状态,但不同的是,原子性追求这个过程不能出错,不论结果对不对,不能出错。但一致性更追求结果一致,...
  • 细说分布式下的数据一致性

    万次阅读 2018-08-29 11:21:47
    细说分布式下的数据一致性 名词解释 强一致性 最终一致性 XA事物 JDBC事物、JTA事物 TCC 产生场景 单一数据库、单一系统无法支撑业务和数据的增长而出现拆分化的演进,数据存储于不同的事物管理单元但又要...
  • 分布式数据一致性(库存)

    千次阅读 2018-08-21 17:24:06
    库存冻结现状 目前购物车添加商品、删除商品、修改商品数量、购物车过期库存解冻、成单后清空购物车,都涉及库存变化。...购物车与库存数据一致性 因购物车和库存系统分属不同的数据库,此处涉及分布式事务...
  • 最近在思考分布式一致性的理论与实现时,感觉自己有所收获,这里分享分享一下自己的经验。 什么是一致性? 至于原理什么的,这里就不赘述了,总的来说目前的分布式系统实现起来基本上都是基于BASE理论的,业务需要...
  • #资源达人分享计划#
  • 介绍分布式理论的文档:Paxos/Raft 分布式一致性算法原理 剖析及其在实战中的应用
  • 分布式系统的一致性问题(汇总)

    万次阅读 多人点赞 2019-09-02 15:32:19
    保证分布式系统数据一致性的6种方案 问题的起源 在电商等业务中,系统一般由多个独立的服务组成,如何解决分布式调用时候数据的一致性? 具体业务场景如下,比如一个业务操作,如果同时调用服务 A、B、C,需要...
  • 保证分布式系统数据一致性的6种方案 问题的起源: 在电商等业务中,系统一般由多个独立的服务组成,如何解决分布式调用时候数据的一致性? 具体业务场景如下,比如一个业务操作,如果同时调用服务 A、B、C,需要...
  • 分布式系统一致性问题解决方案,列举了分布式系统面临的一致性问题背景及解决方案
  • 微服务下数据一致性的特点,总结了下目前的保障微服务下数据一致性的几种实现方式如下,以备后查。此篇文章旨在给大家一个基于微服务的数据一致性实现的大概介绍,并未深入展开,具体的实现方式本人也...
  • 分布式系统的一致性算法

    千次阅读 2020-08-08 15:50:38
    文章目录一,什么是一致性为什么需要一致性共识性二,强一致性算法PaxosBasic-Paxos角色介绍步骤和阶段缺陷Raftleader选举日志复制Zab原理崩溃恢复Zab 协议如何保证数据一致性 一,什么是一致性 对于一个分布式系统...
  • 分布式数据库一致性和可用性方法优化方案研究_张宇.论文。
  • 服务发现工具的主要目标是用来服务查找和相互对话,为此该工具需要知道每个服务,这不是一个新概念,在Docker之前就已经存在很多类似的工具了,然而,容器带给了这些工具一个全新水平的需求。
  • 面试问题(如何保证分布式数据最终一致性

    万次阅读 多人点赞 2018-03-01 10:51:42
    保证分布式系统数据一致性的6种方案编者按:本文由「高可用架构后花园」群讨论整理而成。有人的地方,就有江湖有江湖的地方,就有纷争问题的起源在电商等业务中,系统一般由多个独立的服务组成,如何解决分布式调用...
  • #资源达人分享计划#
  • 点击打开链接

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 361,263
精华内容 144,505
关键字:

分布式数据一致性

友情链接: DetectionEquipment.rar