系统分布式情况下最终一致性方案梳理

合集下载

分布式系统架构中的数据一致性问题与解决方案

分布式系统架构中的数据一致性问题与解决方案

分布式系统架构中的数据一致性问题与解决方案在当今互联网时代,分布式系统架构被广泛应用于各个领域,尤其是大型网站、云计算和物联网等。

然而,分布式系统面临的一个核心挑战就是数据一致性问题。

本文将探讨分布式系统中数据一致性问题的原因,并介绍一些常见的解决方案。

一、数据一致性问题的原因1. 网络延迟:在分布式环境下,系统中的不同节点之间通过网络进行通信。

由于网络延迟等原因,数据在不同节点之间的同步存在一定的延迟,容易导致数据一致性问题。

2. 节点故障:分布式系统中的节点数量通常较多,节点之间可能存在软件或硬件故障。

节点故障会导致数据同步失败,进而引发数据不一致的问题。

3. 并发操作:分布式系统中的节点通常是并发运行的,多个操作同时对同一份数据进行读写操作,容易导致数据不一致的情况发生。

二、数据一致性问题的解决方案1. 强一致性强一致性要求系统中的所有节点在任意时刻都能够访问到一致的数据副本。

为了实现强一致性,可以采用以下方法:(1)原子操作:将多个操作包装成原子性的操作,要么全部执行成功,要么全部执行失败。

例如,可以使用分布式事务来保证数据一致性。

(2)主从复制:将数据分为主节点和从节点,主节点负责处理写操作,从节点负责复制主节点的数据并处理读操作。

主节点和从节点之间通过同步协议保持数据一致。

(3)多数投票:在系统中的多个节点中,若有超过半数的节点达成一致意见,则视为数据同步成功。

通过多数投票来保证数据的一致性。

2. 弱一致性弱一致性允许系统在某一时间点上出现数据不一致的情况,但最终数据会达到一致。

为了实现弱一致性,可以采用以下方法:(1)最终一致性:系统允许一段时间内的数据不一致,但最终会通过一定的机制使得数据最终达到一致。

例如,可以使用版本向量或向量时钟来记录和追踪数据的变更。

(2)基于时间戳:为每个操作添加时间戳,并根据时间戳进行数据的读写操作。

通过时间戳来解决数据冲突和同步的问题。

(3)可扩展性设计:通过设计合理的分布式算法和架构,将大规模的数据分片存储,并保持各个分片的数据一致性。

分布式系统的一致性与可靠性

分布式系统的一致性与可靠性

分布式系统的一致性与可靠性在现代计算机领域,分布式系统扮演着至关重要的角色。

分布式系统是由多个独立计算机或节点组成的,这些节点通过网络进行通信和协作,共同完成各种任务。

然而,由于涉及多个节点的操作,分布式系统面临着一致性和可靠性的挑战。

一、一致性一致性是指分布式系统中的各个节点在进行操作时所观察到的数据的状态是一致的。

具体来说,一致性要求在任何时间点,无论用户从哪个节点发起的操作,最终都能够得到一致的结果。

1. 强一致性强一致性是最严格的一致性要求,保证了分布式系统中所有节点在进行操作时都能够立即同步更新。

这意味着无论用户从哪个节点发起的操作,所有其他节点都会立即观察到该变动。

2. 弱一致性与强一致性相比,弱一致性要求更宽松。

它允许在不同节点之间的数据更新存在一定的延迟,因此在操作过程中节点之间的数据可能会呈现不一致的状态。

3. 最终一致性最终一致性是弱一致性范围内的一种形式,它强调了在分布式系统中,节点之间的数据最终会达到一致的状态。

即使在操作过程中存在一段时间的不一致,系统最终会通过合适的同步机制来达到一致。

二、可靠性可靠性是分布式系统变得健壮和稳定的关键特性。

可靠性要求系统能够在面对节点故障、通信错误等异常情况下继续提供正确的服务。

为了实现可靠性,分布式系统采取了多种技术和策略。

1. 冗余备份冗余备份是一种常见的提高系统可靠性的方法。

通过在不同的节点上复制数据或任务,当某个节点出现故障时,其他节点能够顶替它的工作,保证系统的连续性。

2. 容错机制容错机制是指系统在面对节点故障时,能够自动检测和处理故障,确保分布式系统的正常运行。

通过使用心跳机制、故障检测和自动恢复等技术,系统能够尽可能地减少故障对整体系统性能的影响。

3. 事务管理事务管理是实现分布式系统可靠性的重要手段。

事务管理软件能够确保系统中多个操作的一次性执行,即要么所有操作成功,要么所有操作失败。

这样能够保证系统在面对节点故障时不会出现数据丢失或不一致的情况。

保证分布式系统数据一致性的6种方案

保证分布式系统数据一致性的6种方案

保证分布式系统数据一致性的6种方案问题的起源在电商等业务中,系统一般由多个独立的服务组成,如何解决分布式调用时候数据的一致性?具体业务场景如下,比如一个业务操作,如果同时调用服务A、B、C,需要满足要么同时成功;要么同时失败。

A、B、C 可能是多个不同部门开发、部署在不同服务器上的远程服务。

在分布式系统来说,如果不想牺牲一致性,CAP 理论告诉我们只能放弃可用性,这显然不能接受。

为了便于讨论问题,先简单介绍下数据一致性的基础理论。

强一致当更新操作完成之后,任何多个后续进程或者线程的访问都会返回最新的更新过的值。

这种是对用户最友好的,就是用户上一次写什么,下一次就保证能读到什么。

根据CAP 理论,这种实现需要牺牲可用性。

弱一致性系统并不保证续进程或者线程的访问都会返回最新的更新过的值。

系统在数据写入成功之后,不承诺立即可以读到最新写入的值,也不会具体的承诺多久之后可以读到。

最终一致性弱一致性的特定形式。

系统保证在没有后续更新的前提下,系统最终返回上一次更新操作的值。

在没有故障发生的前提下,不一致窗口的时间主要受通信延迟,系统负载和复制副本的个数影响。

DNS 是一个典型的最终一致性系统。

在工程实践上,为了保障系统的可用性,互联网系统大多将强一致性需求转换成最终一致性的需求,并通过系统执行幂等性的保证,保证数据的最终一致性。

但在电商等场景中,对于数据一致性的解决方法和常见的互联网系统(如MySQL 主从同步)又有一定区别,群友的讨论分成以下 6 种解决方案。

1. 规避分布式事务——业务整合业务整合方案主要采用将接口整合到本地执行的方法。

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

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

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

Redis分布式系统的数据一致性保证方法

Redis分布式系统的数据一致性保证方法

Redis分布式系统的数据一致性保证方法Redis是一种开源的分布式系统,被广泛用于缓存、队列和数据存储等场景。

在分布式环境中,数据一致性是一个重要的问题,因为多个节点之间的数据同步可能会出现延迟或者错误。

为了保证Redis分布式系统的数据一致性,我们可以采用以下几种方法:一、主从复制(Master-Slave Replication)主从复制是Redis最常用的一种数据一致性保证方法。

在主从复制中,一个节点(称为Master节点)将自己的数据复制到一个或多个从节点(Slaves节点)。

当Master节点的数据发生变化时,它会将变化的数据同步给所有的从节点,从节点接收并应用这些变化,以保持数据的一致性。

主从复制的优点是简单可靠,从节点可以提供读取服务而不影响Master节点的性能。

然而,主从复制并不能保证数据的强一致性,因为从节点接收到的变化可能存在一定的延迟。

二、哨兵模式(Sentinel)哨兵模式是Redis提供的高可用性解决方案之一。

在哨兵模式中,多个节点组成一个群集,其中一个节点被选为Master节点,其他节点作为从节点。

哨兵节点负责监控Master节点的状态,并在Master节点宕机时自动切换到一个可用的从节点作为新的Master节点。

哨兵模式通过Master节点的自动切换保证了系统的高可用性,但并不能解决数据一致性问题。

当Master节点发生切换时,新的Master节点会从旧的Master节点同步数据,但这个过程可能存在一定的延迟。

三、cluster模式Redis的cluster模式是一种分布式解决方案,可以将数据分布在多个节点上,提供高可用性和性能扩展。

在cluster模式中,Redis将数据分片存储在多个节点上,并通过Gossip协议进行节点间的通信和数据同步。

cluster模式通过数据分片和自动的数据迁移保证了系统的可用性和性能扩展,但并不能保证强一致性。

由于数据分片和数据迁移的过程中可能存在并发操作和网络延迟,数据一致性需要开发人员自行保证。

分布式事务解决方案3--本地消息表(事务最终一致方案)

分布式事务解决方案3--本地消息表(事务最终一致方案)

分布式事务解决⽅案3--本地消息表(事务最终⼀致⽅案)⼀、本地消息表原理1、本地消息表⽅案介绍本地消息表的最终⼀致⽅案采⽤BASE原理,保证事务最终⼀致在⼀致性⽅⾯,允许⼀段时间内的不⼀致,但最终会⼀致。

在实际系统中,要根据具体情况,判断是否采⽤。

(有些场景对⼀致性要求较⾼,谨慎使⽤)2、本地消息表的使⽤场景基于本地消息表的⽅案中,将本事务外操作,记录在消息表中其他事务,提供操作接⼝定时任务轮询本地消息表,将未执⾏的消息发送给操作接⼝。

操作接⼝处理成功,返回成功标识,处理失败,返回失败标识。

定时任务接到标识,更新消息的状态定时任务按照⼀定的周期反复执⾏对于屡次失败的消息,可以设置最⼤失败次数超过最⼤失败次数的消息,不进⾏接⼝调⽤等待⼈⼯处理例如使⽤⽀付宝的⽀付场景,系统⽣成订单,⽀付宝系统⽀付成功后,调⽤我们系统提供的回调接⼝,回调接⼝更新订单状态为已⽀付。

回调通知执⾏失败,⽀付宝会过⼀段时间再次调⽤。

3、本地消息表架构图4、优缺点优点:避免了分布式事务,实现了最终⼀致性缺点:注意重试时的幂等性操作⼆、本地消息表数据库设计整体⼯程复⽤前⾯的my-tcc-demo1、两台数据库 134和129。

user_134 创建⽀付消息表payment_msg, user_129数据库创建订单表t_order2、使⽤MyBatis-generator ⽣成数据库映射⽂件,⽣成后的结构如下图所⽰三、⽀付接⼝1、创建⽀付服务PaymentService@Servicepublic class PaymentService {@Resourceprivate AccountAMapper accountAMapper;@Resourceprivate PaymentMsgMapper paymentMsgMapper;/*** ⽀付接⼝* @param userId ⽤户Id* @param orderId 订单Id* @param amount ⽀付⾦额* @return 0: 成功; 1:⽤户不存在 2:余额不⾜*/public int payment(int userId, int orderId, BigDecimal amount){//⽀付操作AccountA accountA = accountAMapper.selectByPrimaryKey(userId);if(accountA == null){return 1;}if(accountA.getBalance().compareTo(amount) < 0){return 2;}accountA.setBalance(accountA.getBalance().subtract(amount));accountAMapper.updateByPrimaryKey(accountA);PaymentMsg paymentMsg = new PaymentMsg();paymentMsg.setOrderId(orderId);paymentMsg.setStatus(0); //未发送paymentMsg.setFailCnt(0); //失败次数paymentMsg.setCreateTime(new Date());paymentMsg.setCreateUser(userId);paymentMsg.setUpdateTime(new Date());paymentMsg.setUpdateUser(userId);paymentMsgMapper.insertSelective(paymentMsg);return 0;}}2、创建Controller层@RestControllerpublic class PaymentController {@Autowiredprivate PaymentService paymentService;//localhost:8080/payment?userId=1&orderId=10010&amount=200@RequestMapping("payment")public String payment(int userId, int orderId, BigDecimal amount){int result = paymentService.payment(userId, orderId,amount);return "⽀付结果:" + result;}}3、调⽤接⼝localhost:8080/payment?userId=1&orderId=10010&amount=200查看表。

分布式数据同步方案

分布式数据同步方案

分布式数据同步方案引言在分布式系统中,数据的同步是一个重要的问题。

由于分布式系统中的节点分布在不同的地理位置和网络环境下,数据同步的实现变得非常困难。

本文将介绍一种分布式数据同步的方案,该方案可以有效地解决数据同步的问题,并确保数据在分布式系统中的一致性。

方案概述我们提出的分布式数据同步方案基于主从式架构。

主节点负责接收数据更新并传播给从节点,从节点则负责接收并应用这些更新。

主从节点之间通过一种可靠的通信通道进行数据传输,以确保数据的可靠性和一致性。

方案细节节点角色我们的方案中共有两种节点角色:主节点(master)和从节点(slave)。

•主节点:主节点负责接收来自系统中的其他节点发送的数据更新,并将这些更新传播给从节点。

主节点保持了整个分布式系统中的数据状态的真实拷贝。

•从节点:从节点接收主节点发送的数据更新,并将其应用到本地数据状态中,以保持与主节点的数据一致。

数据更新传播数据更新是通过主节点向从节点发送消息来实现的。

主节点将数据更新打包成一条消息,并通过网络发送给从节点。

从节点收到消息后,将其解析并将数据更新应用到本地数据状态中。

为了确保数据的可靠性和一致性,我们提出了以下几个机制:1.确认机制:主节点在发送数据更新给从节点后,等待从节点的确认消息。

只有在收到从节点的确认消息后,主节点才认为数据更新已经成功传播给从节点。

2.重试机制:如果主节点在发送数据更新给从节点时遇到网络错误或者从节点没有及时响应,主节点将进行重试。

主节点将会持续尝试发送数据更新,直到收到从节点的确认消息。

3.容错机制:在分布式系统中,节点的故障是不可避免的。

为了应对节点故障,我们引入了备份节点的概念。

备份节点可以接管主节点的工作,确保数据更新的传播不受到影响。

数据一致性数据一致性是分布式数据同步的关键问题之一。

为了保持数据的一致性,我们使用了以下的策略:1.顺序保证:主节点按照更新顺序将数据发送给从节点。

从节点按照接收到数据的顺序应用到本地数据状态中。

分布式事务最终一致性的简单案例

分布式事务最终一致性的简单案例

分布式事务最终⼀致性的简单案例1.问题背景最近项⽬中遇到⼀个场景。

为了减少单库的数据量,系统采⽤了分库的⽅式,分为1个主库和N个分库。

现在,在分库中的A表,需要收敛成⼀个汇总的数据,并写⼊主库中的B表。

需要保证分库更改A表的处理状态和插⼊主库B表两个动作具有原⼦性,那么,这就涉及到了跨库的分布式事务的⼀致性问题。

经过⼀番学习了解,由于该场景是采⽤定时任务的⽅式完成,不要求实时的强⼀致性,最后参考了本地消息表的⽅式,保证事务的最终⼀致性。

2.本地消息表可以通过这篇⽂章了解⼀下分布式事务,包括本地消息表。

摘取其中关于本地消息表的案例讲解。

本地消息表这个⽅案最初是ebay提出的 ebay的完整⽅案https:///detail.cfm?id=1394128。

此⽅案的核⼼是将需要分布式处理的任务通过消息⽇志的⽅式来异步执⾏。

消息⽇志可以存储到本地⽂本、数据库或消息队列,再通过业务规则⾃动或⼈⼯发起重试。

⼈⼯重试更多的是应⽤于⽀付场景,通过对账系统对事后问题的处理。

对于本地消息队列来说核⼼是把⼤事务转变为⼩事务。

还是举上⾯⽤100元去买⼀瓶⽔的例⼦。

1.当你扣钱的时候,你需要在你扣钱的服务器上新增加⼀个本地消息表,你需要把你扣钱和写⼊减去⽔的库存到本地消息表放⼊同⼀个事务(依靠数据库本地事务保证⼀致性。

2.这个时候有个定时任务去轮询这个本地事务表,把没有发送的消息,扔给商品库存服务器,叫他减去⽔的库存,到达商品服务器之后这个时候得先写⼊这个服务器的事务表,然后进⾏扣减,扣减成功后,更新事务表中的状态。

3.商品服务器通过定时任务扫描消息表或者直接通知扣钱服务器,扣钱服务器本地消息表进⾏状态更新。

4.针对⼀些异常情况,定时扫描未成功处理的消息,进⾏重新发送,在商品服务器接到消息之后,⾸先判断是否是重复的,如果已经接收,在判断是否执⾏,如果执⾏在马上⼜进⾏通知事务,如果未执⾏,需要重新执⾏需要由业务保证幂等,也就是不会多扣⼀瓶⽔。

分布式系统中的一致性:CAP定理和BASE理论的应用

分布式系统中的一致性:CAP定理和BASE理论的应用

分布式系统中的一致性:CAP定理和BASE理论的应用随着网络技术的发展,分布式系统越来越成为了一个普遍存在的现象。

然而,在分布式系统中,数据的一致性一直以来都是一个重要的问题。

为了解决这个问题,CAP定理和BASE理论应运而生。

CAP定理:在分布式系统中,CAP定理是最为重要的一条定理。

它指出:在一个分布式系统中,一致性(Consistency)、可用性(Availability)和分区容错性(Partition Tolerance)无法同时保证。

它意味着随着系统的增加,我们需要牺牲其中之一。

在CAP定理中,“一致性”指的是在分布式系统中的数据一致性,即当多个节点访问同一数据时,各个节点所看到的数据都应该是一致的。

这里的“可用性”指的是系统能够在合理的时间内处理请求,即系统能够正常运作,并向用户提供服务。

最后,“分区容错性”指的是系统能够容忍网络分区的情况,即在分布式系统中,有些节点无法与其它节点通信时,仍能够继续工作。

CAP定理指出了在分布式系统中需要牺牲某一方面的情况。

一般来说,为了保证分布式系统的高可用性和分区容错性,通常需要牺牲掉数据的一致性。

因此,一般情况下我们只能在一致性和可用性之间做出权衡。

随着技术的不断改进,我们可以采用多种策略来保证分布式系统的一致性和可用性。

例如,引入数据分片技术、采用异步复制等技术,从而提高分布式数据库的可用性和分区容错性。

BASE理论:另一方面,BASE理论是对CAP定理的补充。

它指出,最终一致性是可以被接受的,而不是强一致性。

而“BASE”其实是三个英文单词的缩写:Basically Available(基本可用)、Soft-state(软状态)和Eventually Consistent(最终一致性)。

它是为了解决ACID模型无法解决的高可扩展性和高性能的问题,而被引入的一个适用于大规模分布式系统的数据存储架构理论。

在BASE理论中,基本可用指的是系统在没有故障的前提下,可以保证基本的可用性,即响应时间不会无限延长,能够正常的响应请求。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

系统分布式情况下最终一致性方案梳理
本文章来自于阿里云云栖社区
摘要:前言目前的应用系统,不管是企业级应用还是互联网应用,最终数据的一致性是每个应用系统都要面临的问题,随着分布式的逐渐普及,数据一致性更加艰难,但是也很难有银弹的解决方案,也并不是引入特定的中间件或者特定的开源框架能够解决的,更多的还是看业务场景,根据场景来给出解决方案。

前言
目前的应用系统,不管是企业级应用还是互联网应用,最终数据的一致性是每个应用系统都要面临的问题,随着分布式的逐渐普及,数据一致性更加艰难,但是也很难有银弹的解决方案,也并不是引入特定的中间件或者特定的开源框架能够解决的,更多的还是看业务场景,根据场景来给出解决方案。

根据笔者最近几年的了解,总结了几个点,更多的应用系统在编码的时候,更加关注数据的一致性,这样系统才是健壮的。

基础理论相关
说起事务,目前的几个理论,ACID事务特性,CAP分布式理论,以及BASE 等,ACID在数据库事务中体现,CAP和BASE则是分布式事务的理论,结合业务系统,例如订单管理,例如仓储管理等,可以借鉴这些理论,从而解决问题。

ACID 特性
o A(原子性)事务的原子操作单元,对数据的修改,要么全部执行,要么全部不执行;
o C(一致性)在事务开始和完成时,数据必须保持一致状态,相关的数据规则必须应用于事务的修改,以保证数据的完整性,事务结束时,所有的内部数据结构必须正确;
o I(隔离性)保证事务不受外部并发操作的独立环境执行;
o D(持久性)事务完成之后,对于数据的修改是永久的,即使系统出现故障也能够保持;
∙CAP
o C(一致性)一致性是指数据的原子性,在经典的数据库中通过事务来保障,事务完成时,无论成功或回滚,数据都会处于一致的状态,在分布式环境下,一致性是指多个节点数据是否一致;
o A(可用性)服务一直保持可用的状态,当用户发出一个请求,服务能在一定的时间内返回结果;
o P(分区容忍性)在分布式应用中,可能因为一些分布式的原因导致系统无法运转,好的分区容忍性,使应用虽然是一个分布式系统,但是好像一个可以正常运转的整体
∙BASE
o BA: Basic Availability 基本业务可用性;
o S: Soft state 柔性状态;
o E: Eventual consistency 最终一致性;
最终一致性的几种做法
单数据库情况下的事务
如果应用系统是单一的数据库,那么这个很好保证,利用数据库的事务特性来满足事务的一致性,这时候的一致性是强一致性的。

对于java应用系统来讲,很少直接通过事务的start和commit以及rollback来硬编码,大多通过spring的事务模板或者声明式事务来保证。

基于事务型消息队列的最终一致性
借助消息队列,在处理业务逻辑的地方,发送消息,业务逻辑处理成功后,提交消息,确保消息是发送成功的,之后消息队列投递来进行处理,如果成功,则结
束,如果没有成功,则重试,直到成功,不过仅仅适用业务逻辑中,第一阶段成功,第二阶段必须成功的场景。

对应上图中的C流程。

基于消息队列+定时补偿机制的最终一致性
前面部分和上面基于事务型消息的队列,不同的是,第二阶段重试的地方,不再是消息中间件自身的重试逻辑了,而是单独的补偿任务机制。

其实在大多数的逻辑中,第二阶段失败的概率比较小,所以单独独立补偿任务表出来,可以更加清晰,能够比较明确的直到当前多少任务是失败的。

对应上图的E流程。

业务系统业务逻辑的commit/rollback机制
这一点说的话确实不难,commit和rollback是数据库事务中的比较典型的概念,但是在系统分布式情况下,需要业务代码中实现这种,成功了commit,失败了rollback。

业务应用系统的幂等性控制
为啥要做幂等呢?原因很简单,在系统调用没有达到期望的结果后,会重试。

那重试就会面临问题,重试之后不能给业务逻辑带来影响,例如创建订单,第一次调用超时了,但是调用的系统不知道超时了是成功了还是失败了,然后他就重试,但是实际上第一次调用订单创建是成功了的,这时候重试了,显然不能再创建订单了。

∙查询
查询的API,可以说是天然的幂等性,因为你查询一次和查询两次,对于系统来讲,没有任何数据的变更,所以,查询一次和查询多次一样的。

∙MVCC方案
多版本并发控制,update with condition,更新带条件,这也是在系统设计的时候,合理的选择乐观锁,通过version或者其他条件,来做乐观锁,这样保证更新及时在并发的情况下,也不会有太大的问题。

例如update table_xxx set
name=#name#,version=version+1 where version=#version# ,或者是update table_xxx set quality=quality-#subQuality# where quality-#subQuality# >= 0 。

∙单独的去重表
如果涉及到的去重的地方特别多,例如ERP系统中有各种各样的业务单据,每一种业务单据都需要去重,这时候,可以单独搞一张去重表,在插入数据的时候,插入去重表,利用数据库的唯一索引特性,保证唯一的逻辑。

∙分布式锁
还是拿插入数据的例子,如果是分布是系统,构建唯一索引比较困难,例如唯一性的字段没法确定,这时候可以引入分布式锁,通过第三方的系统,在业务系统插入数据或者更新数据,获取分布式锁,然后做操作,之后释放锁,这样其实是把多线程并发的锁的思路,引入多多个系统,也就是分布式系统中得解决思路。

∙删除数据
删除数据,仅仅第一次删除是真正的操作数据,第二次甚至第三次删除,直接返回成功,这样保证了幂等。

∙插入数据的唯一索引
插入数据的唯一性,可以通过业务主键来进行约束,例如一个特定的业务场景,三个字段肯定确定唯一性,那么,可以在数据库表添加唯一索引来进行标示。

∙API层面的幂等
这里有一个场景,API层面的幂等,例如提交数据,如何控制重复提交,这里可以在提交数据的form表单或者客户端软件,增加一个唯一标示,然后服务端,根据这个UUID来进行去重,这样就能比较好的做到API层面的唯一标示。

∙状态机幂等
在设计单据相关的业务,或者是任务相关的业务,肯定会涉及到状态机,就是业务单据上面有个状态,状态在不同的情况下会发生变更,一般情况下存在有限状态机,这时候,如果状态机已经处于下一个状态,这时候来了一个上一个状态的变更,理论上是不能够变更的,这样的话,保证了有限状态机的幂等。

异步回调机制的引入
A应用调用B,在同步调用的返回结果中,B返回成功给到A,一般情况下,这时候就结束了,其实在99.99%的情况是没问题的,但是有时候为了确保100%,记住最起码在系统设计中100%,这时候B系统再回调A一下,告诉A,你调用我的逻辑,确实成功了。

其实这个逻辑,非常类似TCP协议中的三次握手。

上图中的B流程。

类似double check机制的确认机制
还是上图中异步回调的过程,A在同步调用B,B返回成功了。

这次调用结束了,但是A为了确保,在过一段时间,这个时间可以是几秒,也可以是每天定时处理,再调用B一次,查询一下之前的那次调用是否成功。

例如A调用B更新订单状态,这时候成功了,延迟几秒后,A查询B,确认一下状态是否是自己刚刚期望的。

上图中的D流程。

总结
上面的几点总结,更多的在业务系统中体现,在超复杂的系统中,数据的一致性,不是说简单的引入啥中间件能够解决的,更多的是根据业务场景,来灵活应对。

相关文档
最新文档