分布式系统的一致性问题解决方案

文章探讨了分布式系统中的一致性问题,介绍了ACID和BASE理论,以及两阶段提交、三阶段提交和TCC等分布式一致性协议。同时,讨论了超时处理模式,包括同步和异步调用的超时策略,以解决服务间的不一致状态。文章提供了多种一致性问题的解决方案,如查询模式、补偿模式等,旨在确保分布式环境的最终一致性。
摘要由CSDN通过智能技术生成

 

文章目录

前言

一、什么是分布式系统的一致性

二、酸碱平衡理论

三、分布式一致性协议

四、一致性问题的解决方案

五、超时处理模式

5.1 同步调用超时

5.2 异步调用超时 

总结



前言

  随着互联网的发展,对于后端服务的架构也需要随之进行改变。从传统的单体架构到服务化架构再到微服务架构,架构在不断的演变,在解决问题的同同时也带来了新的问题。在微服务架构下,服务之间的调用通过网络带宽进行数据的交流,在这个背景下由于网络的不稳定加上微服务间是自行管理自己的数据,所以会出现不一致的问题。本文针对分布式系统下微服务间的不一致性进行分析,并提供解决方案。

  该内容是阅读《分布式服务架构--原理、设计与实战》的读后总结笔记

一、什么是分布式系统的一致性

  为了满足需求,让后端服务更好的为用户提供服务,这时候就需要将我们的服务进行拆分,拆分又分为水平拆分和垂直拆分。

  • 水平拆分:由于一个节点无法满足性能需求,于是将一个节点扩展为多个具有一致功能的节点,这些节点共同分担任务
  • 垂直拆分:一个节点处理的功能逻辑比较多,于是将这个功能逻辑进行拆分,多个节点每个节点完成这个功能逻辑的一部分。这样就是的每个节点的功能职责单一、简单

  由于将一个系统拆分了多个系统,我们要使得多个系统之间的信息、工作进度、状态一致并协调有序的工作。这就是分布式系统饿一致性问题。

1.1 分布式系统一致性问题的案例

  1.   转账问题:A转账给B,A扣款成功,但是B账户加钱失败
  2. 同步调用超时问题:A服务调用B服务,但是由于网络超时A接受到超时错误,但是此时B并不知道超时,还继续处理任务,就导致A和B的不一致性
  3. 掉单:在分布式系统中,两个系统协调处理一个流程,分别为对方的上下游,如果一个系统中存在一个请求(通常是指订单)但是另外一个系统中不存在,则会导致掉单
  4. 缓存和数据库的不一致、本地缓存和分布式缓存以及数据库状态不一致

二、酸碱平衡理论

  什么是酸碱平衡理论,这个理论是如何解决分布式环境下的不一致性问题的

2.1 ‘酸’理论 ACID

  ACID主要是通过强一致性来解决不一致性的问题

  • A:原子性
  • C:一致性
  • I:隔离性
  • D:持久性

强一致性是指服务会从一个明确的状态变化到另外一个明确的状态,不存在中间的临时状态。

2.2 CAP (帽子理论)

  • C:一致性。在分布式系统中所有数据备份,在同一时刻具有同样的值,所有节点在同一时刻读到的数据都应该是最新的数据副本
  • A:可用性。在任何故障模型下,服务器都会在有限的时间内处理完成并进行响应
  • P:分区容忍性。尽管网络上有部分消息丢失,但是系统仍然可以继续工作

CAP原理证明,任何分布式系统只可同时满足以上两点,无法三者兼顾

2.3 BASE理论(碱)

  BASE模型包含如下三个元素

  • BA:基本可用
  • S:soft软状态,状态可以在一段时间内不同步
  • E:状态最终达到一致即可

BASE理论是相对于ACID理论的,它通过牺牲强一致性来达到可用性和最终一致性

三、分布式一致性协议

3.1 两阶段提交协议

  两阶段提交协议是将分布式事务分为两个阶段,一个阶段是准备阶段,第二个阶段是提交阶段


其中协调者为资源管理器,参与者为资源管理器。

两阶段提交协议的缺点:

  • 阻塞:对于每一个操作都需要收到明确的响应才会进行下一步,否则阻塞,占用的资源一直被锁定
  • 单点故障:如果协调者宕机,参与者没有协调者指挥则会一直阻塞
  • 脑裂:协调者发送事务给参与者,有的参与者接受到事务并执行,有的参与者没有接收到则没有执行,这就导致不一致情况的发生 

3.2 三阶段提交协议

三阶段提交和两阶段提交的区别在于三阶段提交增加了一个询问步骤,这样可以防止参与者本来服务就不可用导致阻塞的问题,然后准备阶段增加了超时,如果参与者超时则默认成功,并提交事务。较于两阶段提交三阶段提交不容易阻塞。

3.3 TCC协议

  TCC协议将事务分为三个阶段try、confirm、cancel。其实类似于两阶段提交协议,但是增加了一个cancel操作,在提交失败之后提供一个cancel的回滚操作。但是当cancel命令发送的时候如果有的节点接收到命令,有的节点没有接收到命令,这种情况导致的不一致性问题,TCC协议会先尝试进行修复,如果修复不了则最终需要人工修复。

四、一致性问题的解决方案

  通过上面的分析,分布式环境下的一致性问题我们可以通过一致性协议来实现强一致性,或者是使用酸碱理论来实现最终一致性。要实现强一致性,则需要使用到两阶段提交、三阶段提交和TCC。实现最终一致性有一些非常有效、简单的模式,下面就介绍这些模式及其应用场景。

  1.   查询模式:每一个服务都应该有一个查询接口用来向外输出操作执行的状态,服务的调用者可以通过查询接口得知服务操作执行的状态
  2. 补偿模式:当服务之间的调用发生超时的时候,由于调用方并不知道执行方是否接收到请求并执行了操作,所以需要调用查询模式提供的查询接口,如果状态不一致,则根据执行方的状态来选择是继续完成为完成的操作还是将已经完成的操作进行回滚,来达到最终一致性
  3. 异步确保模式:通过异步通知的方式来达到最终一致,这种方式解决了高峰时期系统的压力。比如A调用B,请求之后立刻返回,B将任务执行成功之后通过异步回调的方式通知A任务已执行完成。如果通知为任务执行失败,则A调用B的回滚接口
  4. 定时校对模式:不适用异步确保模式或者异步通知的情况也有可能出现异步调用超时的情况,可以使用定时任务定期扫描数据库,发现处于异常状态的数据则进行处理
  5. 可靠消息模式:在同步调用的时候容易出现调用超时,导致分布式环境下的不一致性的问题。通过可靠消息的方式充分解耦客户端和服务端,同时需要保证消息发送的可靠性和消息消费的可靠性

五、超时处理模式

  分布式环境下的不一致性主要的原因就是网络超时导致服务之间的状态不能相互通知,处理好网络超时异常发生时的数据,然后再结合上面的实现最终一致性的模式,就可以达到我们分布式系统的最终一致性。

  网络调用方式分为同步调用、异步调用以及基于消息队列的异步调用。下面就通过分析不同情况下的网络调用超时,以及超时之后的解决方案。

5.1 同步调用超时

  同步调用的情况下,请求者和执行者是通过定义接口的响应报文来通信的,接口的返回通常分为如下两种情况:

  • 两种状态:成功、失败
  • 三种状态:成功、失败、处理中

5.1.1 两种状态下的同步调用超时

  第一种情况就是客户调用服务器的时候发生了超时,这是时候由于不知道服务1是否已经接收到请求并已经在处理请求了,则可以调用服务1提供的查询接口,查询执行的状态,如果查询到执行状态为成功则继续在执行下面的操作,如果查询的结果是执行失败则需要重新请求。重新请求的情况需要注意,也有可能查询请求到达时第一个请求还没有到达,这种情况下重试就导致多次请求,这时就需要保证服务1的幂等性。

这个超时发生在服务1调用服务2的情况,这种情况由于服务1对外的接口只有成功或者失败,则这里必须使用快速失败策略,同时调用服务2的冲正接口,服务2的冲正接口判断开始时是否接收到请求并在接收到请求后回滚。

5.1.1  三种状态的同步调用超时

  

这种情况跟两种状态的时候一样,需要调用服务1的查询接口,根据响应的状态来判断后面需要执行的操作。

 服务1调用服务2的时候超时,这时候两种状态和三种状态的就不一样,三种状态的时候可以给客户段返回一个处理中的状态,然后通过定时任务去补偿数据。

5.2 异步调用超时 

5.2.1 发送同步请求超时

  

这种情况的超时需要通过服务1的查询接口来补齐状态,确保服务1已经接收到请求

 5.2.2  异步调用内部超时

由于这里使用的是异步任务的方式,所以对于响应时间没有要求,服务1需要调用服务2的查询接口查询状态,然后进行补偿。

5.2.3 第三种情况就是在异步通知的时候超时,这种情况可以使用重试的方式

5.3 消息队列超时 

  这点就需要去研究消息队列如何保证消息的可靠性了。

总结

  本文通过说明什么是分布式环境下的一致性,已经分布式环境下的酸碱理论说明达到分布式环境的一致性需要根据自己的需求是需要酸-强一致性还是碱-最终一致性,这样酸碱结合。然后阐述了分布式环境下不一致情况的解决方:查询法、补偿法等。以及在分布式环境下超时调用问题是产生不一致问题的主要原因,以及在调用链中产生了超时之后如何处理来保证一致性。最终是推荐使用三种状态的方法,保存一个中间状态来达到最终的一致性。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
第1章 课程介绍 介绍该课程的内容、学习成果、实例,还有学习所需的前提知识。 1-1 导学-分布式事务实践 第2章 事务原则与实现 介绍了事务的四大原则,并通过实例介绍数据库实现事务的方法,以及使用JDBC实现事务的方法。 2-1 事务原则与实现:事务 2-2 事务原则与实现:SQL事务 2-3 事务原则与实现:JDBC事务(上) 2-4 事务原则与实现:JDBC事务(下) 第3章 使用Docker搭建环境 介绍了Docker的使用,通过Docker将课程环境搭建起来,方便那些不了解这些技术的同学之后的学习。 3-1 docker简介与mysql安装-1 3-2 docker简介与mysql安装-2 3-3 SpringBoot基础 第4章 Spring事务机制 介绍了Spring的事务机制、事物抽象、内部事务和外部事物,以及常用的几种事务管理的实现,包括DataSource、JPA、JMS、JTA都通过实例进行说明。还有XA以及两阶段提交,并通过实例演示了使用JTA,通过两阶段提交,实现多数据源的事务实现。... 4-1 Spring事务机制_基本接口 4-2 Spring事务机制_实现 4-3 Jpa事务实例 4-4 Jms事务原理 4-5 Jms-session事务实例 4-6 Jms-spring事务实例 4-7 外部事务与JTA 4-8 JTA单数据源事务实例 4-9 JTA多数据源事务实例 第5章 分布式系统 介绍了分布式系统的定义、实现原则和几种形式,详细介绍了微服务架构分布式系统,并使用Spring Cloud框架演示了一个完整的微服务系统的实现过程。 5-1 CAP原则和BASE理论简介 5-2 分布式系统综述 5-3 SpringCloud微服务架构 5-4 实现registry 5-5 实现proxy 5-6 user服务 5-7 order服务 5-8 添加hystrix 5-9 使用feign 5-10 优化服务间调用 第6章 分布式事务实现,模式和技术 介绍分布式事务的定义、原则和实现原则,介绍使用Spring框架实现分布式事务的几种方式,包括使用JTA、Spring事务同步、链式事务等,并通过实战介绍其实现。除此以外还介绍了一些分布式事务相关的技术,如幂等性、全局一致性ID、分布式对象等。... 6-1 分布式事务介绍 6-2 spring分布式事务实现_使用JTA 6-3 spring分布式事务实现_不使用JTA 6-4 实例1-DB-DB 6-5 实例1-DB-DB.链式事务管理器 6-6 实例2-JPA-DB.链式事务管理器 6-7 实例3-JMS-DB.最大努力一次提交 6-8 分布式事务实现模式与技术 6-9 全局一致性ID和分布式对象_ 第7章 分布式事务实现:消息驱动模式 详细介绍3种分布式事务实现的模式中的消息驱动模式并通过完整实例演示了消息驱动模式下,实现微服务系统分布式事务的完整过程。 7-1 分布式事务实现:消息驱动模式 7-2 消息驱动模式实例:设计 7-3 消息驱动模式实例:创建ticket服务 7-4 消息驱动模式实例:实现基本ticket功能 7-5 消息驱动模式实例:锁票1 7-6 消息驱动模式实例:锁票2 7-7 按消息流程实现业务 7-8 支付过程 7-9 票转移 7-10 错误处理:锁票失败 7-11 错误处理:扣费失败 7-12 并发时的错误处理 第8章 分布式事务实现:Event Sourcing模式 详细介绍了分布式事务实现的模式中的Event Sourcing模式,并通过完整实例演示了Event Sourcing模式下,实现微服务系统分布式事务的完整过程。 8-1 事件溯源模式介绍 8-2 事件溯源模式与Axon框架-1 8-3 事件溯源模式与Axon框架-2 8-4 使用Axon框架的设计过程介绍 8-5 Axon框架-实例(上) 8-6 Axon框架-实例(下) 8-7 Saga模式和Axon Saga 8-8 聚合命令事件(上) 8-9 聚合命令事件(下) 8-10 实现saga 8-11 实现query 8-12 处理超时 8-13 并发测试 8-14 cloud-axon实例:分布式处理介绍 8-15 事件设计 8-16 事件与队列设计 8-17 实现User服务 8-18 实现Ticket服务 8-19 实现Order服务 8-20 实现读写分离 8-21 测试与并发 8-22 事件溯源模式与Axon框架总结 第9章 TCC模式和微服务架构的设计模式 本章介绍TCC模式,也对微服务系统的几种设计模式,以及这些模式下分布式事务的实现模式进行了介绍。 9-1 TCC模式介绍 9-2 微服务架构的设计模式 第10章 课程总
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值