当前位置: 首页 > news >正文

分布式事物理论与实践

在日常讨论技术方向的时候,经常听伙伴抛出一些概念高可用性,一致性关键词。但是未必每个
人都能把这些概念说清楚。今天我们就来聊聊分布式事物那些事,分享一下我们在项目中是如何使用的。
一、CAP理论

1.什么是CAP理论

2000年,Eric Brewer教授在PODC的研讨会上提出了一个猜想。一致性、可用性和分区容错性三者无法在分布式系统中被同时满足,并且最多只能满足其中两个!Brewer教授当时想象的分布式场景是webservice,一组websevrice后台运行着众多的server,对service的读写会反应到后台的server集群。
图片描述

强一致性 (Consistency):系统在执行过某项操作后仍然处于一致的状态。在分布式系统中,更新操作执行成功后所有的用户都应该读取到最新的值,这样的系统被认为具有强一致性。
可用性 (Availability):每一个操作总是能够在一定的时间内返回结果,超时和不能返回结果均不符合条件。
分区容错性(Partition Tolerance):分区容错性可以理解为系统在存在网络分区的情况下仍然可以接受请求。这里网络分区是指由于某种原因网络被分成若干个孤立的区域,而区域之间互不相通。还有一些人将分区容错性理解为系统对节点动态加入和离开的处理能力,因为节点的加入和离开可以认为是集群内部的网络分区。

2.系统为什么不能同时满足CAP特性

如下图所示,在网络中有两个节点分别为G1和G2,这两个节点上存储着同一数据的不同副本,现在数据是一致的,两个副本的值都为V0,A、B分别是运行在G1、G2上与数据交互的应用程序。

图片描述

在正常情况下,操作过程如下(如下图所示):
(1) A将V0更新,数据值为V1;
(2) G1发送消息m给G2,数据V0更新为V1;
(3) B读取到G2中的数据V1。

图片描述

如果发生网络分区故障,那么在操作的步骤(2)将发生错误:G1发送的消息不能传送到G2上。这样数据就处于不一致的状态,B读取到的就不是最新的数据,如下图所示。如果我们采用一些技术如阻塞、加锁、集中控制等来保证数据的一致,那么必然会影响到系统的可用性和分区容错性。所以同时满足三点,总是需要放弃一部分。

图片描述

系统满足三个条件中不同的两个条件会具有不同的特点
放弃P,保证AC:如果想避免分区容错性问题的发生,一种做法是将所有的数据(与事务相关的)都放到一台机器上。
放弃A,保证CP:一旦遇到分区容错故障,那么受到影响的服务需要等待数据最终一致性
放弃C,保证AP:这里所说的放弃一致性,而保留数据的最终一致性。该方式也是解决分布式事物的主流方式。

二、分布式事物解决方案

eBay的架构师Dan Pritchett 在2008年发给ACM的文档。文章中描述了一个最常见的场景,如果产生了一笔交易,需要在交易表增加记录,同时还要修改用户表的金额。这两个表属于不同的远程服务,涉及到分布式事务一致性的问题。经典的解决方法,引入本地消息表和消息中间件,将写入本地消息表、更新用户表,发送Q放在一个本地事务中完成。同时为了避免重复消费用户表消息带来的问题,保证幂等性增加一个接收端记录表。
举个例子,系统中有以下两个表user,transaction.

图片描述

其中user表记录用户交易汇总信息,transaction表记录每个交易的详细信息。transaction表和user表存储在不同的节点上,那么上述事务是一个分布式事务。要消除这一分布式事务,将它拆分成两个子事务。保证消息的幂等性还需要在接收端创建消息接收表message_applied(msg_id),保证不能重复接收消息。

begin transaction
  insert into transaction(xid, $seller_id, $buyer_id, $amount);
  put_to_queue "update user("seller",$seller_id,amount)";
  put_to_queue "update user("buyer",$buyer_id,amount)";
end transaction
--------------------------------------------------------
for each message in queue
  peek message
  begin transaction
    select count(*) as cnt from message_applied where msg_id=message.id
        and balance = message.balance and user_id=message.user_id
    if cnt == 0 
then
          if message.type = “seller” then
    update user SET amt_sold = amt_sold + message.amount where id = message.user_id;
else
update user set amt_bought = amt_bought + message.amount where id = message.user_id;
         insert into message_applied values(message.id); 
end
end transaction
end fors

第一阶段:transation表和操作队列在同一实例上,可以通过本地的数据库的事务保证。
第二阶段:message_applied表和user表在同一个实上,可以通过本地的数据的事务保证,当有重试或者重复消息过来时,通过message_applied表可以判断是否是重复数据。

三、实际项目对理论的实践

  1. A、B两个系统服务进行异步数据通信
    本场景我们采用Q作为消息中间件。可以借鉴ebay模式。

①应用A的业务逻辑、写本地消息表、写消息队列放在一个队列里。写消息队列业务逻辑放在最后。
②所有步骤执行成功,事物提交。
③有一步骤执行失败,则进行回滚。
④此方案需要在记录服务A发送的完整消息日志,以防Q出现问题进行消息补发,在B端创建接收表,去重,保证消息的幂等性。

  1. D调用A、B、C三个服务

本场景保证事物一致性有两种解决方案,一种是调用中间服务出错后回滚掉其他所有服务的数据,这需要每个应用提供回滚服务。另一种认为服务一定会调用成功,一旦出现问题,会不断重试。下面会根据这两种情况进行详细说明。
第一, 服务调用采用回滚方式处理,如下示意图所示

图片描述

以上思路还是借鉴ebay模型来解决最终一致性问题。
第二,不断重试保证消息一致性相对第一种情况要简单一些。一旦调用异常需要记录到错误表中不断的进行重试。

相关文章:

  • OpenCV中的新函数connectedComponentsWithStats使用
  • ASP.NET Core 运行原理解剖[2]:Hosting补充之配置介绍
  • Spring Boot整合Quartz实现定时任务表配置
  • Arcgis for Js实现graphiclayer的空间查询(续)
  • 【树莓派】服务配置相关2:基于RPi Desktop的服务配置
  • (推荐)叮当——中文语音对话机器人
  • 睿仁医疗郑世斌:医疗智能硬件数据精度应放在第一位
  • 软件开发的流程
  • 理解.NET中的异常(二)
  • Spring 和 SpringMVC 常用注解
  • python并开发编程之协程
  • 探索我的项目管理之路之:软件质量的六个考核要素
  • 使用交换机实现数据单向访问控制
  • 为恶意文件“画像” 瀚思科技基于深度学习技术快速锁定未知威胁
  • 真实案例:一位网页开发者几乎毁掉一家小公司
  • 【跃迁之路】【641天】程序员高效学习方法论探索系列(实验阶段398-2018.11.14)...
  • Angular4 模板式表单用法以及验证
  • Essential Studio for ASP.NET Web Forms 2017 v2,新增自定义树形网格工具栏
  • JavaScript设计模式与开发实践系列之策略模式
  • Java编程基础24——递归练习
  • jQuery(一)
  • Webpack4 学习笔记 - 01:webpack的安装和简单配置
  • 翻译:Hystrix - How To Use
  • 深度学习在携程攻略社区的应用
  • 我是如何设计 Upload 上传组件的
  • 异步
  • MiKTeX could not find the script engine ‘perl.exe‘ which is required to execute ‘latexmk‘.
  • Mac 上flink的安装与启动
  • ​​​​​​​​​​​​​​Γ函数
  • # 数论-逆元
  • $con= MySQL有关填空题_2015年计算机二级考试《MySQL》提高练习题(10)
  • (06)Hive——正则表达式
  • (1)Map集合 (2)异常机制 (3)File类 (4)I/O流
  • (BFS)hdoj2377-Bus Pass
  • (二)windows配置JDK环境
  • (附源码)springboot建达集团公司平台 毕业设计 141538
  • (免费领源码)python+django+mysql线上兼职平台系统83320-计算机毕业设计项目选题推荐
  • (南京观海微电子)——COF介绍
  • (十一)JAVA springboot ssm b2b2c多用户商城系统源码:服务网关Zuul高级篇
  • (四)汇编语言——简单程序
  • (一)RocketMQ初步认识
  • (一)基于IDEA的JAVA基础12
  • (转载)CentOS查看系统信息|CentOS查看命令
  • (自适应手机端)响应式新闻博客知识类pbootcms网站模板 自媒体运营博客网站源码下载
  • ***利用Ms05002溢出找“肉鸡
  • *1 计算机基础和操作系统基础及几大协议
  • *p++,*(p++),*++p,(*p)++区别?
  • .net core MVC 通过 Filters 过滤器拦截请求及响应内容
  • .net连接oracle数据库
  • .NET命令行(CLI)常用命令
  • @NoArgsConstructor和@AllArgsConstructor,@Builder
  • [ vulhub漏洞复现篇 ] struts2远程代码执行漏洞 S2-005 (CVE-2010-1870)
  • [1] 平面(Plane)图形的生成算法
  • [2016.7 test.5] T1
  • [2016.7.Test1] T1 三进制异或