为什么80%的码农都做不了架构师?>>>   

摘要: 在阿里巴巴,“柔性事务” 已经是重构分布式事务的标准方法,覆盖了商品、交易、支付各个大规模应用场景,并且经受了双十一的考验。

DRDS 是阿里云提供的一款分布式数据库产品,它的原型是在阿里内部使用了 10 年的数据库中间件 TDDL。DRDS 在 TDDL 提供的数据切分和 SQL 路由能力上,强化了分布式查询,事务和水平扩容能力。

什么是柔性事务?

在分布式数据库中,数据存储在多个节点将引入两个问题:

  • 分布式事务 - 业务需要更新多个节点的数据。
  • 全局二级索引 - 查询无法准确的定位数据位于哪个节点。

由于全局二级索引的同步依赖于事务,因此 分布式事务 是所有分布式数据库产品都需要解决的核心问题。这一问题的关键是 —— 数据存储在多个节点,原本在单机数据库上不难实现的 ACID 特性在分布式环境下变得困难:

  1. 因为网络通信的不可靠,事务的原子性需要用多次日志和网络通信来保证。
  2. 存储节点的增加,放大了单个存储节点在事务过程中出现故障的风险。
  3. 用锁实现的事务隔离性,在故障或网络抖动时严重影响性能。

因此,在高可用与高性能的应用场景,分布式事务的最佳实践是放弃 ACID,遵循 BASE 的原则重构业务流程:

区别于 ACID 特性的数据库事务,这种放弃强一致性,采取最终一致方式执行的分布式事务称为 “柔性事务” (Flexible Transactions)。

在阿里巴巴,“柔性事务” 已经是重构分布式事务的标准方法,覆盖了商品、交易、支付各个大规模应用场景,并且经受了双十一的考验。阿里内部最常用的柔性事务方案有 “消息事务” 与 “TCC 事务” (Try / Confirm / Cancel),它们的基本原理是一致的:

  1. 将业务中的分布式事务分解成一个个在独立分库上执行的子事务。
  2. 用异步重试的方式执行这些子事务,由框架或应用保证重试的 “幂等”(相同的业务逻辑不会被重复执行)。
  3. 如果需要回滚,以同样方式执行另一组子事务组成的补偿操作,恢复事务前的业务状态。

柔性事务放弃了隔离性,减小了事务中锁的粒度,使得应用能够更好的利用数据库的并发性能,实现吞吐量的线性扩展。异步执行方式可以更好的适应分布式环境,在网络抖动、节点故障的情况下能够尽量保障服务的可用性 (Availability)。因此在高可用、高性能的应用场景,柔性事务是最佳的选择。

但是,现有的柔性事务方案都存在一个共同问题:它们是以框架或者中间件的形式存在,应用需要付出较大的改造成本:

  1. 框架和中间件的接口带来了学习成本。
  2. 用户需要理解一些概念(例如 “可靠消息” “幂等”)才能正确的使用。
  3. 需要业务流程去适配工具,应用不但在架构上要大幅调整,而且还影响业务流程的直观性。

有没有更好的方案?

有。 DRDS / TDDL 在新发布的 5.3 版本开始提供两种类型的分布式事务:柔性事务 (FLEXIBLE) 和两阶段提交事务 (XA)。前者将柔性事务与传统数据库的使用方式相结合,提供了简单易用、低成本、高性能的 DRDS 分布式事务功能。

使用 DRDS 柔性事务

开启 DRDS 柔性事务只需要一行代码:

SET drds_transaction_policy = 'flexible';SHOW VARIABLES LIKE 'drds_transaction_policy';
+-------------------------+----------+
| VARIABLE_NAME           | VALUE    |
+-------------------------+----------+
| drds_transaction_policy | FLEXIBLE |
+-------------------------+----------+
1 row in set (0.07 sec)

除了一行代码,DRDS 柔性事务的使用方法和普通事务完全相同:应用首先用 SET autocommit = 0和 SET drds_transaction_policy = 'flexible' 开启柔性事务;然后在同一个会话中执行事务的 SQL 语句 —— 最后当应用发起 commit 或 rollback 后,DRDS 将保证这些 SQL 语句执行的原子性:全部成功,或者全部失败。

相比 TCC 或消息事务, DRDS 不需要业务编写补偿操作的回滚语句。DRDS 会根据事务中 SQL 语句的语义,自动生成相应的补偿操作。

例如,如果业务执行的是一条典型的资金扣减操作:

UPDATE account SET balance = balance - 100 WHERE id = 123 AND balance >= 100

DRDS 会自动生成对应的反向退款操作:

UPDATE account SET balance = balance + 100 WHERE id = 123

由于柔性事务的弱隔离性,应用通常会担心:提交失败后,异步回滚操作是否会覆盖并发的更新,造成 "Lost update" 或者 “回滚覆盖” 问题。在传统 TCC 或消息事务中,回滚覆盖问题需要由应用引入状态、版本号、或乐观锁机制来规避。

DRDS 柔性事务则使用了一些创新的方式来解决这个问题:

1. 增量回滚

前面的例子已经展示了增量回滚是如何工作的:如果 DRDS 识别应用的 UPDATE 语句中包含 “增量操作”,例如:balance = balance - 100,则会在回滚语句中使用 balance = balance + 100 进行补偿。由于增量操作的结果与顺序无关,即使事务异步回滚,也不会覆盖任何一笔业务的更新结果。

增量操作的定义是 UPDATE 语句符合以下格式:

UPDATE {表名} SET {列名} = {列名} [+/-] {常量表达式}, ... WHERE {条件表达式}

增量回滚对账户、积分、库存这样的字段非常有用,而这些字段又通常是需要用分布式事务严格保证一致性的关键数据。建议在应用中尽量对这一类字段采用 “增量操作” 的方式更新,既节省了一次数据库操作(SELECT),又避免了柔性事务 “回滚覆盖” 的风险。

2. 关键事务

另一个防止回滚覆盖的方法是 “关键事务”。

在 DRDS 柔性事务中,应用第一次在事务内执行的 DML(INSERT/UPDATE/DELETE) 操作被放入 “关键事务” 内执行。在柔性事务的执行流程中,“关键事务” 总是第一个开始,最后一个提交。

DRDS “关键事务” 的执行机制与单机事务相同,不需要记录补偿操作,也不需要异步回滚。因此,把具有回滚覆盖风险的 UPDATE 操作放入 “关键事务” 内执行,是一个防止异步回滚的好方法。

“关键事务” 的设计,可以让一个 DRDS 单机事务自然切换到分布式事务。在传统的柔性事务方案中,应用需要识别业务场景是不是存在分布式事务,然后再根据场景采用不同的事务方式。而 DRDS 的特殊设计,可以做到开启柔性事务,执行单机事务也不产生任何额外代价。

3. 后置执行

第三个方法是使用 “后置执行” 优化事务流程,防止产生回滚。

DRDS 提供了一个全新的 SQL 执行方式:“后置执行”。用来优化分布式事务中不影响业务最终执行结果的跨库操作。在分布式事务理论中,这一类优化被称为 “Best Efforts 1PC”:

使用 “后置执行” 非常简单,只需要在 SQL 语句的头部加入 /*TDDL:DEFER*/:

/*TDDL:DEFER*/ UPDATE account SET balance = balance + 100 WHERE id = 123

DRDS 保证后置执行的 SQL 仅仅执行一次,不需要应用关心出错重试或者幂等的问题。

“后置执行” 将事务中同步执行的操作转移至异步执行,减少了分布式事务中持有锁的时间,提高了事务执行的并行度,因此可以很好的提升分布式事务的性能。同时,由于 “后置执行” 用异步重试替代了回滚,它也是解决回滚覆盖问题的另一个方法。

使用 DRDS XA 事务

新版本 DRDS 也支持 XA 事务,在柔性事务的基础上提供了强一致能力。

SET drds_transaction_policy = 'XA';SHOW VARIABLES LIKE 'drds_transaction_policy';
+-------------------------+-------+
| VARIABLE_NAME           | VALUE |
+-------------------------+-------+
| drds_transaction_policy | XA    |
+-------------------------+-------+
1 row in set (0.07 sec)

DRDS XA 事务使用两阶段提交协议 (XA Protocol) 保护子事务的提交与回滚,消除了柔性事务的异步回滚问题。由于 XA Protocol 在提交与回滚阶段始终加锁,避免了事务结束前的脏读和覆盖,但是对性能有较大影响。

“后置执行” 功能在 DRDS XA 事务中同样可用,能够减少 XA 协议中的锁,提供了进一步的性能优化空间。

由于 MySQL XA 实现机制的限制,我们建议只有在 DRDS 后端是 MySQL 5.7 版本以上才启用 XA 事务功能。

低成本、高性能

从稳定性和成本出发,DRDS 柔性事务不引入额外的服务和存储节点,而是利用后端的 RDS/MySQL 存储事务日志和回滚信息。在实现上,DRDS 尽可能的减少了事务过程中的数据传输和日志开销,以提升分布式事务的性能。

使用 sysbench 压测工具表明,在标准的 8core 16G 规格 DRDS 实例上,开启柔性事务可以达到 9000 QPS 的优异性能。相比不开启事务的 sysbench 压测结果,性能差异不到 10%.

小结

从分布式事务的原理出发,最终一致的 “柔性事务” 与提供 ACID 保证的 “强一致事务” 是两个独立的发展方向。前者实现了更高的水平扩展能力与性能,代价是应用需要付出额外的开发成本;后者提供了强一致的数据访问和更好的开发体验,但存在性能上的限制。

作为行业领先的云原生分布式数据库,DRDS 同时在两个方向拓展产品的边界:

  • 降低应用使用 “柔性事务” 的开发成本。
  • 持续创新,提升 “强一致事务” 的性能和扩展性。

DRDS 新版本提供的分布式事务功能(柔性事务以及 XA 事务)正是第一阶段的成果。

未来的 DRDS 产品将为企业用户提供更多、更好的选择:作为基础的 “强一致事务”、标准的全局事务隔离级别、基于分布式 MVCC 的一致性读、以及为高性能应用提供的 “柔性事务” 。在默认配置下,DRDS 将提供标准的事务 ACID 保证,以及高于业界水准的性能;而应用只需要付出较少的代价,就可以适配 DRDS 的特性,获得更高的水平扩展能力和性能保证。

原文链接

本文为云栖社区原创内容,未经允许不得转载。

转载于:https://my.oschina.net/yunqi/blog/1828165

DRDS 柔性事务漫谈相关推荐

  1. 事务对性能影响_DRDS 柔性事务漫谈

    DRDS 是阿里云提供的一款分布式数据库产品,它的原型是在阿里内部使用了 10 年的数据库中间件 TDDL.DRDS 在 TDDL 提供的数据切分和 SQL 路由能力上,强化了分布式查询,事务和水平扩 ...

  2. mysql 分库分表 ~ 柔性事务

    一 定义 TCC方案是可能是目前最火的一种柔性事务方案 二 具体 内容 TCC=try(预设)-confrim(应用确认)-canal(回滚取消) 三 目的 解决跨服务调用场景下的分布式事务问题,避免 ...

  3. 架构设计 | 基于消息中间件,图解柔性事务一致性

    简介:分布式事务基于可靠消息最终一致性的实现方案,既然是可靠消息,则要求MQ必须支持事务管理,这样才能保证业务前后一致性. 一.最大努力通知 TCC分段提交适用分布式架构中对一致性.实时性要求较高的业 ...

  4. 分布式事务解决方案——柔性事务与服务模式

    转载自   分布式事务解决方案--柔性事务与服务模式 初识分布式系统 关于分布式一致性的探究 分布式系统的CAP理论(需要到博客中查看) 分布式系统的BASE理论(需要到博客中查看) Java中的事务 ...

  5. 事务超时时间无效_架构设计 | 基于消息中间件,图解柔性事务一致性

    简介:分布式事务基于可靠消息最终一致性的实现方案,既然是可靠消息,则要求MQ必须支持事务管理,这样才能保证业务前后一致性. 一.最大努力通知 TCC分段提交适用分布式架构中对一致性.实时性要求较高的业 ...

  6. 分布式事务(三)、柔性事务之 TCC、Saga、本地消息表、事务消息、最大努力通知

    目录 [前言] TCC Saga [通知型事务] 本地消息表 MQ事务消息 最大努力通知 总结 分布式事务: 分布式事务(一).CAP,BASE理论 分布式事务(二).刚性事务之 2PC.3PC [前 ...

  7. 从0-1事务-柔性事务-分布式事务

    事务的概念: 事务从数据库引申而来,事务即一组原子性的sql查询. ACID(别名:酸碱平衡理论): 事物的原子性(A: Atomicity):一个事务必须被设为一个不可分割的最小工作单元,整个事务中 ...

  8. 分布式柔性事务详解--基于事务型MQ

    一.概述 咱们今天聊聊分布式事务系列中的最后一个方案:最大努力通知事务.最大努力通知事务的主流实现仍是基于MQ来进行事务控制.最大努力通知事务和事务消息都是通知型事务,主要适用于那些需要异步更新数据, ...

  9. 认清阿里的数据库产品

    ApsaraDB:  是阿里云在线数据库服务产品总称,不是具体的数据库产品.它包含如下数据库服务: 注:绿色文字部分为高度自研产品,赞. 关系型数据库 云数据库 MySQL 版 AliSQL研发:  ...

  10. 分布式系统漫谈【拾】_分布式事务一致性:阿里方案

    上篇文章:分布式系统漫谈[玖]_分布式事务一致性:协议支持 其实对于生产环境的分布式事务一致,各大互联网公司都是自己实现的解决方案,总结起来无非是异步.补偿.实时查询.定期校对几种模式,大部分场景都是 ...

最新文章

  1. C - Multiplication Table CodeForces - 448D
  2. 淘宝双十一用哪些“潜规则”冲击1500亿?
  3. 零基础入门NLP之搭建中文分词工具
  4. 基因分子生物学(1)-基因常识与DNA常识
  5. 以太坊geth节点各种报错(求助)
  6. UI设计师如何正确打开暗黑模式|实用素材拿走
  7. 利用xsl和xml转html没有内容_HTML文档元素的属性介绍
  8. NFT游戏Illuvium获500万美元种子轮融资,Framework Ventures领投
  9. 人教版三年级下册计算机课教案,人教版三年级下册19课教案
  10. 一般3d模型代做多少钱_重庆涪陵办一场婚宴一般需要多少钱?婚庆布置报价一般多少钱?...
  11. html点击按钮切换图片代码_单次点击实现远程代码执行:内容管理框架Drupal恶意图片上传漏洞利用链分析...
  12. 人人商城小程序消息服务器配置,人人商城小程序前端对接教程
  13. solidity之view和pure函数的用法总结
  14. Eclipse下载以及旧版本下载
  15. django generic view - ListView
  16. 一张图回顾Hadoop十年:Hadoop老矣,尚能饭否?
  17. 报表设计器——设计自己的报表
  18. 身份证,银行卡,姓名用*号隐藏中间数字
  19. alert的使用方法
  20. 如何用mysql求质数_PLSQL计算质数

热门文章

  1. MYSQL的Commit与程序的原子性
  2. java restful返回json_java 调用接口的时候报的错 用的是restful的post方式,请求返回的是json...
  3. Leetcode91. Decode Ways
  4. 关于sophus模板类需要注意的情况(error: missing template arguments before ‘SO3_R’)
  5. 软件测试--缺陷报告常见问题03
  6. Java-bug记录【1】
  7. PHP curl_setopt函数用法介绍
  8. c++实现gray code(格雷码)
  9. 转:使用Android API最佳实践
  10. android 抓包 2