阿里业务研发经典案例:另类解法,分布式一致

本文涉及的产品
智能数据建设与治理Dataphin,200数据处理单元
简介:

背景

在大型互联网系统中,基于成本的考虑,普遍会使用MySQL数据库;同时由于业务量很大,通常会按照用户维度对数据做垂直拆分,即大家常说的分库分表。

在阿里巴巴的红包系统中,红包的发放操作会涉及两个数据库的事务操作,一个数据库进行预算的扣减,另一个进行用户红包数据的写入,那么如何保证这两个事务操作的一致性呢?

问题及原因分析

开发人员首先想到的就是使用MySQL 的XA 协议,它使用的是两阶段提交协议,如图1所示。由事务协调者来保证所有的事务参与者都完成了第一阶段的准备工作,如果所有参与者都准备好了,那么就通知所有的参与者进行提交。MySQL 数据库仅能扮演参与者的角色,协调者(事务管理器)需要由另外的应用担任。

bb3c8a013cafc98e347dd9f6672944ecd864bc8b

图1 两阶段提交协议

两阶段提交协议对于红包系统来说,在XA 事务中的第一阶段,预算端需要做的事情是冻结要扣除的预算,红包数据端需要插入一条不可用的红包数据。在XA 事务的第二阶段,如果事务需要提交,那么预算端需要将第一阶段的冻结的预算转化为实际的扣除,红包数据端需要将刚才插入的那一条不可用的红包数据变为可用;如果事务需要回滚,那么预处端需要将第一阶段的冻结的预算进行撤销操作,红包数据端需要删除刚才插入的不可用的红包数据。

两阶段提交协议对于红包系统来说,在XA 事务中的第一阶段,预算端需要做的事情是冻结要扣除的预算,红包数据端需要插入一条不可用的红包数据。在XA 事务的第二阶段,如果事务需要提交,那么预算端需要将第一阶段的冻结的预算转化为实际的扣除,红包数据端需要将刚才插入的那一条不可用的红包数据变为可用;如果事务需要回滚,那么预处端需要将第一阶段的冻结的预算进行撤销操作,红包数据端需要删除刚才插入的不可用的红包数据。

对于任何一次不论是成功还是失败的发放操作,预算端都会涉及两次针对于预算纪录的事务操作。众所周知的是,该条记录的操作会存在热点写的问题,使用XA 事务的方案会将热点写问题放大一倍。在业务场景中,使用XA 事务的方案看起来有些过于“悲观”了,事实上红包发放的成功与否几乎完全取决于预算是否扣减成功。回到业务的根本需求上来,有以下两个关键点。

(1)希望预算扣减成功与产生用户红包数据这两件事要么同时成功,要么同时失败,只要预算足够,那么理论上是肯定成功的。

(2)不可能将每一个发放操作变成一个一个顺序的独立事务,这样不但性能非常差,同时后面的事务也并不关心预算的具体剩余金额。所以实际上在发放操作中,很有可能看到一个是中间态的预算剩余金额,这是允许的。

如果能存在一起机制,它能保证预算扣减成功后100%会通知到我们,这样就可以利用这个机会去产生用户红包数据,如果产生失败,那么我们可以对已经扣减的预算进行一笔反向操作。

解决方案

最终的解决方案是开发人员设计了一个轻型的一致性消息组件,把预算扣减成功等诸多业务操作事件写入数据库中,该消息组件保证事件与业务操作处在同一个数据库中,所以仅仅是一次简单的本地事务操作。该消息组件会对写入的事件进行分发,通知每一个事件订阅者(比如在当前的场景中就是进行用户红包数据写入),然后对事件的处理结果进行记录。


在一个成功的红包发放操作中,对于预算端来说,进行了一次预算的扣减,一次事件写入,可能会进行一次事件读取,一次事件状态更新;对于用户红包数据端,仅需要进行一次用户红包数据的写入。可以看到,对于预算扣减的热点数据操作,新的方案并没有放大它。同时,失败的红包发放操作就更简单了,仅仅是一次失败的预算扣减,没有事件,没有用户红包端的任何操作。

另外,在实际使用中开发人员发现,使用这样的一套方案还可以降低系统的编码以及运维的复杂度,不再需要为预算端设计冻结操作以及用户红包数据端设计不可用数据,也不需要引入另外一套独立的事务协调系统。

这套系统命名为MiniBus,即微型总线,如图2所示。

81e5440d0247c0a94381d634e49fd3b1b5f44694


图2 微型消息总线系统架构

它包括以下三部分。

(1)事件发布者Publisher。由业务逻辑在业务事务中调用,将事件写入到与业务相同的数据库中。

(2)事件配置Metadata。管理事件的基本信息,订阅关系等。

(3)事件调试器Scheduler。读取待分发的事件,根据订阅关系进行分发,调用相应的事件处理器,然后记录事件分发的结果。

该方案并不仅仅解决了红包发放操作中的事务一致性问题,事实上,只要业务上满足如下的两个要求,它都适用。

(1)短暂的中间状态是可以接受的。

(2)要求最终一终性。

同时,还有如下4 个方面的优点。

(1)较XA 方案更易于编码和理解,已有代码的改造成本很低。

(2)数据库消耗增加较少。

(3)系统简单,外部依赖少,易于维护。

(4)兼容数据库上的其他他SQL 优化。

小结

好的技术方案都是对于业务场景的深刻理解和权衡之后获得的,虽然通用的方案是首选,但它并不是唯一的好的选择。


原文发布时间为:2017-12-8

本文作者:逆流而上书摘

本文来自云栖社区合作伙伴“阿里数据”,了解相关信息可以关注“阿里数据”微信公众号

相关文章
|
6月前
|
缓存 算法 架构师
阿里P9架构师终于把毕生心血而成的分布式高可用算法笔记开源了
说在前面的话 分布式系统无处不在。 一台计算机内部多个互联的处理器组成了一个分布式系统,它们通过“一致性缓存”算法使每个处理器核心看到相同的数据。近三十年来,随着互联网的发展,越来越多的互联网后台系统采用计算机集群的方式来应对海量请求和数据的需求,这个计算机集群也是分布式系统。 为了简化分布式系统的开发,出现了很多为开发者提供分布式框架的开源项目,例如Apache基金会旗下的ZooKeeper项目就是一个应用广泛的分布式框架。 同时,国内也有很多关于如何使用这些分布式框架来搭建应用的书籍,它们极大地推动了分布式系统在国内的应用。我们不仅要知道如何使用这些现成的分布式框架来搭建应用,而且应
|
4月前
|
安全 Java 测试技术
高并发、多线程、分布式都不懂,你拿什么跳槽阿里、腾讯、京东?
Java多线程与高并发实战实践 先来看看高并发多线程一些大厂并发面试题,看你能答出几道!
|
4月前
|
算法 NoSQL Java
2023年阿里高频Java面试题:分布式+中间件+高并发+算法+数据库
又到了一年一度的金九银十,互联网行业竞争是一年比一年严峻,作为工程师的我们唯有不停地学习,不断的提升自己才能保证自己的核心竞争力从而拿到更好的薪水,进入心仪的企业(阿里、字节、美团、腾讯.....)
|
9月前
|
存储 SQL 分布式计算
Kubernetes云原生实战:分布式GeaFlow实现图研发,构建第一个商业智能应用
Kubernetes在云原生应用中扮演着至关重要的角色,为商业智能(BI)强大赋能。不同于传统的BI,容器化部署在集群中可以获得更高的可靠性、弹性和灵活性。
Kubernetes云原生实战:分布式GeaFlow实现图研发,构建第一个商业智能应用
值得一看!阿里又杀疯了开源内部“M9”级别全彩版分布式实战笔记
系统架构大致经历了单体应用架构→垂直应用架构→分布式架构→SOA架构→微服务架构的演变
|
6月前
|
搜索推荐 Java 测试技术
79分布式电商项目 - 阿里大于短信发送
79分布式电商项目 - 阿里大于短信发送
42 0
|
7月前
|
安全 Java 测试技术
高并发、多线程、分布式都不懂,你拿什么跳槽阿里、腾讯、京东?
Java多线程与高并发实战实践 先来看看高并发多线程一些大厂并发面试题,看你能答出几道! (1)synchronized的CPU原语级别是如何实现的? (2)无锁、偏向锁、轻量级锁、重量级锁有什么差别,升级过程如何? (3)线程间通信,同机器进程间通信,跨机器进程间通信,各有什么方法? (4)下列三种业务,应该如何使用线程池:
|
8月前
|
算法 NoSQL Java
2023年阿里高频Java面试题:分布式+中间件+高并发+算法+数据库
又到了一年一度的金九银十,互联网行业竞争是一年比一年严峻,作为工程师的我们唯有不停地学习,不断的提升自己才能保证自己的核心竞争力从而拿到更好的薪水,进入心仪的企业(阿里、字节、美团、腾讯.....)
|
8月前
|
算法 NoSQL Java
2021年阿里高频Java面试题:分布式+中间件+高并发+算法+数据库
又到了一年一度的金九银十,互联网行业竞争是一年比一年严峻,作为工程师的我们唯有不停地学习,不断的提升自己才能保证自己的核心竞争力从而拿到更好的薪水,进入心仪的企业(阿里、字节、美团、腾讯.....)
|
8月前
|
关系型数据库 数据库 OceanBase
OceanBase是阿里巴巴自主研发的分布式关系型数据库系统
OceanBase是阿里巴巴自主研发的分布式关系型数据库系统
269 1

热门文章

最新文章