吊打面试官----精华汇总之分布式事务

先介绍常见的几种分布式事务解决方案,属于近两年面试必问题目。

1.两阶段提交(2PA)

两阶段提交,有一个事务管理器的概念,负责协调多个数据库(资源管理器)的事务,事务管理器先问问各个数据库你准备好了吗?如果每个数据库都回复ok,那么就正式提交事务,在各个数据库上执行操作;如果任何一个数据库回答不ok,那么就回滚事务。

这种分布式事务方案,比较适合单块应用里,跨多个库的分布式事务。但是因为严重依赖于数据库层面来搞定复杂的事务,效率很低,绝对不适合高并发的场景。

这个方案,我们很少用,一般来说某个系统内部如果出现跨多个库的这么一个操作,是不合规的。 现在流行微服务,一个大的系统分成几百个服务,几十个服务。一般来说,我们的规定和规范,要求每个服务只能操作自己对应的一个数据库。

2.补偿事务(TCC)

TCC的全程是:Try、Confirm、Cancel

1)Try阶段:这个阶段对各个服务的资源做检测以及对资源进行锁定或者预留

2)Confirm阶段:这个阶段是在各个服务中执行实际的操作

3)Cancel阶段:如果任何一个服务的业务方法执行出错,那么就需要进行补偿,即执行已经执行成功的业务逻辑的回滚操作

这种模式也很少用,因为这个事务回滚严重依赖于手写代码来回滚和补偿,需要大量的具体业务补偿代码。一般来说跟钱相关的,跟钱打交道的,支付、交易相关的场景,我们会用TCC,严格严格保证分布式事务要么全部成功,要么全部自动回滚,严格保证资金的正确性。这样造成业务代码非常复杂,难于维护和扩展。

3.本地消息表(异步确保)

  1. 在分布式事务操作的A方完成写业务数据的操作之后向本地消息表发送一个消息,本地事务能保证这个消息一定会被写入本地消息表中。
  2. 之后将本地消息表中的消息转发到 Kafka 等消息队列中,如果转发成功则将消息从本地消息表中删除,否则继续重新转发。
  3. 在分布式事务操作的B方从消息队列中读取一个消息,并执行消息中的操作。

这是一种非常经典的实现,避免了分布式事务,实现了最终一致性,但是严重依赖本地消息表,本地消息表跟业务表耦合度高,不可公用,消息服务性能会受到关系型数据库并发性能的局限,遇到高并发场景也不太好扩展。

4.MQ事务消息(最终一致性)

优点:

  • 消息数据独立存储,降低业务系统与消息系统之间的耦合。

  • 吞吐量优于本地消息表方案。

缺点:

  • 一次消息发送需要两次网络请求(half消息 + commit/rollback)。

  • 需要实现消息回查接口。

 目前国内互联网公司大都是这么玩儿的,要么用RocketMQ支持,要么基于类似ActiveMQ/RabbitMQ封装一套类似的逻辑出来。

大概流程描述如下:

1)A系统先发送一个prepared消息到mq,如果这个prepared消息发送失败那么就直接取消操作。

2)如果这个消息发送成功,那么接着执行本地事务,如果本地事务成功就向mq发送确认消息,如果失败通知mq回滚消息。

3)如果发送了确认消息,那么此时B系统会接收到确认消息,然后执行B本地的事务。

4)mq会自动定时轮询所有prepared消息回调你的接口,询问这个消息是不是本地事务处理失败了,所有没发送确认消息;那是继续重试还是回滚?一般来说这里你就可以查下数据库看之前本地事务是否执行,如果回滚,那么这里也回滚吧。这个就是避免可能本地事务执行成功了,别确认消息发送失败了。

5)这个方案里,要是系统B的事务失败了咋办?重试咯,自动不断重试直到成功,如果实在是不行,比如针对重要的资金类业务进行回滚,B系统本地回滚后,通知系统A也回滚;或者是发送报警由人工来手工回滚和补偿。

5.最终一致性

Saga模式(即最终一致性模式)是一种分布式异步事务,一种最终一致性事务,是一种柔性事务,有两种不同的方式来实现saga事务:

A、 事件/编排Choreography:没有中央协调器(没有单点风险)时,每个服务产生并聆听其他服务的事件,并决定是否应采取行动。

举例处理流程:

订单服务保存新订单,将状态设置为pengding挂起状态,并发布名为ORDER_CREATED_EVENT的事件。

支付服务监听ORDER_CREATED_EVENT,并公布事件BILLED_ORDER_EVENT。

库存服务监听BILLED_ORDER_EVENT,更新库存,并发布ORDER_PREPARED_EVENT。

货运服务监听ORDER_PREPARED_EVENT,然后交付产品。最后,它发布ORDER_DELIVERED_EVENT。

最后,订单服务侦听ORDER_DELIVERED_EVENT并设置订单的状态为concluded完成。

假设库存服务在事务过程中失败了。进行回滚:

  1. 库存服务产生PRODUCT_OUT_OF_STOCK_EVENT

  2. 订购服务和支付服务会监听到上面库存服务的这一事件:

    ①支付服务会退款给客户。

    ②订单服务将订单状态设置为失败

这种模式很简单,容易理解,不需要太多的努力来构建,所有参与者都是松散耦合的,因为他们彼此之间没有直接的耦合。如果事务涉及2至4个步骤,是非常合适的。

 

        B.命令/协调orchestrator:中央协调器负责集中处理事件的决策和业务逻辑排序。

           订单服务保存pending状态,并要求订单Saga协调器(简称OSO)开始启动订单事务。

           OSO向收款服务发送执行收款命令,收款服务回复Payment Executed消息。

           OSO向库存服务发送准备订单命令,库存服务将回复OrderPrepared消息。

          OSO向货运服务发送订单发货命令,货运服务将回复Order Delivered消息。

优点:

避免服务之间的循环依赖关系,因为saga协调器会调用saga参与者,但参与者不会调用协调器。

集中分布式事务的编排。

只需要执行命令/回复(其实回复消息也是一种事件消息),降低参与者的复杂性。

在添加新步骤时,事务复杂性保持线性,回滚更容易管理。

如果在第一笔交易还没有执行完,想改变有第二笔事务的目标对象,则可以轻松地将其暂停在协调器上,直到第一笔交易结束
 

缺点:协调器中集中太多逻辑的风险。

 

 

 

 

ACID

指数据库事务正确执行的四个基本要素:

  • 原子性(Atomicity)

  • 一致性(Consistency)

  • 隔离性(Isolation)

  • 持久性(Durability)

CAP

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

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

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

分区容忍性:以实际效果而言,分区相当于对通信的时限要求。系统如果不能在时限内达成数据一致性,就意味着发生了分区的情况,必须就当前操作在C和A之间做出选择。
 

BASE理论

BASE理论是对CAP中的一致性和可用性进行一个权衡的结果,理论的核心思想就是:我们无法做到强一致,但每个应用都可以根据自身的业务特点,采用适当的方式来使系统达到最终一致性。

Basically Available(基本可用)

Soft state(软状态)

Eventually consistent(最终一致性)
 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值