阿里数据 关注
手机版
  1. 云栖社区>
  2. 阿里数据>
  3. 博客>
  4. 正文

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

技术小能手 2017-12-11 10:13:16 浏览119 评论0 发表于: 阿里数据

云栖社区 分布式 mysql 数据库

摘要: 背景 在大型互联网系统中,基于成本的考虑,普遍会使用MySQL数据库;同时由于业务量很大,通常会按照用户维度对数据做垂直拆分,即大家常说的分库分表。 在阿里巴巴的红包系统中,红包的发放操作会涉及两个数据库的事务操作,一个数据库进行预算的扣减,另一个进行用户红包数据的写入,那么如何保证这两个事务操作的一致性呢? 问题及原因分析 开发人员首先想到的就是使用MySQL 的XA 协议,它使用的是两阶段提交协议,如图1所示。

背景

在大型互联网系统中,基于成本的考虑,普遍会使用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

本文作者:逆流而上书摘

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

本文为云栖社区原创内容,未经允许不得转载,如需转载请发送邮件至yqeditor@list.alibaba-inc.com;如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件至:yqgroup@service.aliyun.com 进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容。

用云栖社区APP,舒服~

【云栖快讯】中办国办印发《推进互联网协议第六版(IPv6)规模部署行动计划》加快推进基于 IPv6 的下一代互联网规模部署,计划指出2025年末中国 IPv6 规模要达到世界第一,阿里云也第一时间宣布了将全面提供IPv6服务,那么在全面部署 IPV6 前,你需要了解都在这儿  详情请点击

网友评论

一种稳定、可靠、容量和服务能力可弹性伸缩的分布式关系型数据库服务。

充分利用阿里云现有资源管理和服务体系,引入中间件成熟的整套分布式计算框架,以应用为中心,帮助企业级客户轻松构建并...

云上企业级一站式智能研发协同平台,为企业用户提供从需求、编码到测试、发布、反馈等端到端的持续交付服务。

为您提供简单高效、处理能力可弹性伸缩的计算服务,帮助您快速构建更稳定、安全的应用,提升运维效率,降低 IT 成本...