重庆没建网站的企业,中国网库企业黄页,制作官网的公司性价比高,律师做几个网站作者#xff1a;季敏#xff0c;阿里云分布式事务产品负责人、Seata 开源项目创始人
微服务架构下数据一致性的挑战
微服务开发的痛点 在 2019 年#xff0c;我们基于 Dubbo Ecosystem Meetup#xff0c;收集了 2000 多份关于“在微服务架构#xff0c;哪些核心问题是开…作者季敏阿里云分布式事务产品负责人、Seata 开源项目创始人
微服务架构下数据一致性的挑战
微服务开发的痛点 在 2019 年我们基于 Dubbo Ecosystem Meetup收集了 2000 多份关于“在微服务架构哪些核心问题是开发者最关注的痛点”的调研问卷。最终分布式事务问题在调研中占比最大约占 54%。
在 Seata 出现之前大家谈到分布式事务的态度是能避则避大部分是靠写一些复杂的业务逻辑加消息最终一致性去解决数据一致性问题。但 Seata 开源之后这些问题都变得简单起来。比如这里提到的无损上下线核心关注的是服务的可用性还是其他问题。从我的理解角度看我觉得它最终关注的是数据问题。无论前端的业务怎么去做交互最终都会沉淀到数据的变化。如果业务的数据不一致前面无论是什么样的架构都变得意义不大因为最终数据才是企业的核心资产。 那么到底哪些场景会遇到分布式事务的问题呢
第一个场景单体架构在拆分成微服务架构之后不同的服务可能由不同的团队维护和负责这里会涉及上下游服务的发布部署联动。比如 C 服务发布的时候并不会通知 A 服务和 B 服务这个时候就会遇到末端服务上下线带来的数据一致性问题。
第二个场景不可靠不稳定的基础设施带来的系统稳定性问题进而引发数据一致性问题比如基础设施层的存储、计算和网络不稳定导致的业务问题等。
第三个场景timeout 是分布式架构中服务调用比较难解的状态一旦出现服务调用超时我们无法确定业务逻辑最终是执行了还是未执行这里最终会演化为数据的一致性的问题。从单体到分布式架构的演进服务从进程内调用演变为跨网络的调用在链路上糅合网络的因素加剧了数据一致性问题的出现的概率。
第四个场景业务链路里除了会涉及到数据库还会涉及到其他第三方的数据组件。比如库存类服务一般会涉及到 Redis 组件如何实现数据库和缓存的数据一致性也是事务链路需要考虑的业务场景。
第五个场景上下游服务调用时需要在调用链路中传递一些业务参数上游服务需要对这些参数做逻辑校验。当参数逻辑校验不合法时如何将上游服务的数据回滚到执行前的数据初态保证服务调用链的数据一致性。
总结起来分布式事务的业务场景主要包括跨库、跨服务和多样性资源的数据一致性。 分布式事务会尤其关注业务异常导致的事务回滚场景从异常分类上主要包括业务异常和系统异常。
那么分布式事务是不是微服务架构独有的问题呢其实不是它在单体应用里也有相同的问题只不过在微服务架构里这个问题更加凸显。
在单体架构下存在哪些分布事务的场景呢比如一个单体多模块应用要去操作多个数据库。本地事务是通过数据库连接上的一个 SQLSession 完成的只要跨出了本地事务那就会涉及到分布式事务问题即使不同的微服务去修改同一个数据库这也会涉及到分布式事务问题因为 SQLSession 是基于 Socket 连接的所以它本身是不能通过序列化和反序列化将对象传递到其他服务。
整体来看分布式事务是各类应用架构的通用问题应用场景非常广泛。
分布式事务的解决方案 市面上的分布式事务方案有以下几类
XA 模式它的性能相比其他事务模式要差一点但能保证最严格的数据一致性。XA 模式需要设置为串行化隔离级别相当于对数据添加了读写锁。另外连接资源需要在整个事务期间保持导致资源锁定问题影响到并发事务的吞吐。TCC 模式和 SAGA 模式可以归结为业务层面的分布式事务解决方案因为它不会拦截数据。比如 TCC 模式有 TryConfirm 和 Cancel 接口至于这个接口内的回滚和提交逻辑是业务层面需要去实现的在框架层面只负责分布式协调。这要求业务开发对业务逻辑有充分的理解和设计能力否则可能出现无法提交/回滚、提交和回滚逻辑的不对等、接口的幂等和时序问题 。消息最终一致性它最大的优点是可以实现异步化的解耦同时可以结合消息的削峰填谷的优点。但它本身存在着一些问题消息更多的是做单向 one way 的通知场景。在一些业务场景中可能存在消息消费失败的场景但它无法去回滚消息发送方的数据。比如现金红包的业务第一步从我的账户扣减红包金额第二步通过消息消费的方式提现到我的银行卡。消息消费的时候我这个账户已经被注销掉了那么消息消费即使去重试也会一直处在消费失败的状态。对于这类问题消息是无法再把消息发送方的数据回滚掉。所以消息适用于一致性要求不强的异步单向通知场景。定时任务补偿它的学习成本低但开发成本比较高。尤其是微服务存在多跳节点的链路在任意中间节点出现问题都需要考虑如何去补偿和订正所有已经完成变更的数据需要补偿逻辑编写的非常详尽和严谨比较适应于数据一致性和实时性要求不高的简单业务场景。AT 模式它对一致性和性能做了综合考量主要的特点是简单无侵入强一致学习成本低。缺点是需要遵守一定的开发规约它并不是对所有的 SQL 类型都支持有一定的使用限制。适应于通用的业务场景但它并不适应于热点数据的高并发场景像 sku 的库存的扣减。因为 AT 模式有应用层的全局锁当需要对相同的数据修改操作时需要使用全局锁控制事务的并发时序实现上存在锁排队等待的机制。
分布式事务 Seata 的架构演进
Seata 的起源 Seata 在阿里内部的产品代号叫 TXC起源于阿里集团的五彩石项目。五彩石是女娲补天用的石子当时阿里集团内正在做去 IOE 的架构演进从单体架构演进到分布式架构在演进的过程中必然会涉及到很多的中间件去解决分布式的问题TXC 承担的主要的角色是保证服务的数据一致性。
TXC 和集团内的三大件都做了深度的集成包括服务调用框架 HSF 和开源的 Apache Dubbo 相似的一个产品数据库层有分库分表的 TDDL 组件异步消息的 MetaQ 组件。这三大件基本满足业务开发的常规需求TXC 通过深度集成使开发人员无需设计和实现一致性逻辑框架层面能天然保证一致性对开发人员完全是透明无感知。
TXC 在集团内也有广泛的使用日均百亿级的事务调用标准 3 节点集群吞吐量可以达到近 10w TPS。TXC 产品的 SLA 包括可用性 SLA 和性能 SLA。因为对于分布式事务来说除了要保证基本的数据一致性外也要保证系统的性能和吞吐量SLO 指标定义每一次分布式事务调用额外的 rt 开销不能超过 xx ms。目前分布式事务的调用处理已能达到毫秒级基本接近我们推导的理论上限值在稳定性上能保证全年无故障。
分布式事务模型定义
下面我们一起来看下分布式事务模型的定义。 最开始去定义分布式事务模型时我们需要充分考虑分布式事务应该是在哪一层去实现
从开发者的视角看应用架构主要包括最上层是应用开发框架每个公司都有一套开发框架可能是自研框架或者 Spring Cloud 体系等。向下一层是服务调用框架由类似 Apache Dubbo 这类的框架承担在国内 Apache Dubbo 有着非常广泛的使用。再向下一层是数据中间件这层主要包括 ORM 框架、事务、同步、对账等类型的中间件。最下层是与数据库的连接层像 JDBC Java 版本的实现 mysql-connector-java 就属于这一层。
我们去做了一个简单的对比到底应该在哪层实现分布式事务更合适一些是在数据库、数据中间件层还是应用开发框架层
在应用框架层实现一致性相对比较弱。因为在开发框架层糅合了比较多的复杂的因素比如会把服务调用的异常给糅合进去。比如服务调用的超时和重试机制这就是为什么现在 TCC 模式它会有一些幂等、防悬挂和空回滚问题因为融入了 RPC 的因素所以会带来一些不确性问题。实际上Seata 已经在框架层面解决了这类的问题。
在数据中间件层它的一致性比应用框架要好它存在主要的问题是因为不在数据库层实现所以是有办法绕过中间件直接去修改数据库的这时候就会存在事务并发脏写问题归根到底是因为数据中间件不是修改数据的唯一界面但可以通过一定的开发规约来规范使用避免问题的产生。
最好的数据一致性是在数据库层去实现但在数据库层实现面临的主要问题是
1. 主要依赖数据库厂商的实现能力上参差不齐。 比如 MySQL 在 5.7.7 版本才把XA做到真正可用在之前的版本它对 XA prepare 持久化一直存在问题。
2. 无法约束跨服务的分布式事务。 数据库层实现的分布式事务以数据库为核心资源作用范围只能局限在数据库本身。如果要在更大的 scope 下做分布式事务比如应用要跨服务对于跨服务的分布式事务它就无法约束所以还是需要有一个第三方的协调者从全局去协调跨服务的数据一致性。
最终我们把差异化的 AT 事务模式做到了数据库中间件层TCC 和 Saga 事务模式做到了应用开发框架层。
分布式事务模型定义不仅仅只是定义一个开发组件它除了要实现了一整套的开发流程体系还要包括了对编程模型的定义性能运维安全数据审计可观测和高可用体系等。在理论模型上最初我们的理论是比较匮乏的后续逐步完善了角色模型的定义和 Spring 事务模型的延展。之所以是去延展了已有的模型而不是完全新创造一套理论体系是因为这样做对开发者能大幅度降低学习的成本。此外我们还做了一些基础理论的定义包括一致性的定义是解决多节点的一致性还是业务应用架构数据的一致性事务的模式定义事务交互模型和事务的隔离性等。 什么是分布式事务它在日常中解决了什么问题
举个例子我去做银行转账的时候我给你转 100 元恰好这个时候出现了网络超时那么这 100 元到底有没有扣减。如果不确定就可能出现资损的问题甚至可能影响企业的商誉。
我们都在谈分布式架构但从整个应用的宏观视角实际上并不是所有组件都是分布式的。比如从一个应用的架构的层面去看数据库当然也包括今天流行的分布数据库从整个应用层面来看它还是一个集中式的数据的存储。在分布式的应用架构里每个节点都只掌握了部分的信息如果要做一些问题的排查必然需要一个集中式的组件掌握全链路的信息。对于分布式事务它的核心工作是做分布式协调所以它需要掌握全局的事务和数据信息。
这就是为什么 Seata 有了 Transaction Coordinator 角色对分布式事务它要有一个上帝视角充当第三方的协调器真正去执行数据库操作的是 Resource Manager你可以认为它是数据库的灵魂充当了数据库的 Proxy。真正随着业务应用去做事务控制的是 Transaction Manager它伴随着业务的执行链路去控制事务的边界和决议。Transaction CoordinatorResource Manager 和 Transaction Manager 共同构成了分布式事务的角色模型。
分布式事务的架构演进 2019 年 1 月 Seata 正式开源从 0.1 版本我们将主打的 AT 事务模式开源0.4 版本正式纳入了 TCC 事务模式。AT 模式需要适配不同的数据库进行开发在现有阶段很难满足对所有关系数据库的支持以及业务链路的缓存资源支持这就需要 TCC 事务模式去做 AT 事务模式的补充。
随着 Seata 的不断迭代和发布对长事务解决方案的呼声越来越强。 在 0.9 版本正式纳入 Saga 事务模式它主要解决链路较长的微服务数据一致性问题同时兼顾了微服务的可视化编排。在 1.1 版本Seata 纳入了 XA 的事务模式。为什么纳入 XA 模式Seata 支持了 AT、TCC 和 Saga 事务模式之后市面上其他的事务模式主要包括消息最终一致性和 XA 模式。社区也陆续收到了用户的一些声音的反馈用户在较新的业务中使用了 AT 事务模式用户期望可以和原有的 XA 模式可以实现互联互通形成统一的分布式事务选型。
Seata 通过社区驱动的模式推动技术的演进打造了一站式的分布式事务的解决方案。 针对不同的业务场景Seata 都能使用不同事务模式满足业务的需求。如上图所示为什么 Seata 要有四种事务模式目前市面上没有一种分布事务的模式能解决不同业务场景的数据一致性问题。
分布式事务是一款和业务耦合比较深的组件从数据交互链路上看包括同步和异步长事务和短事务强一致和弱一致以及与性能的权衡考量。所以社区纳入了现在的四种事务模式它们从改造成本、性能和隔离性上各有所长这里就不展开介绍了。
如何基于 Seata 扩展 RPC 和数据库
Seata 开源社区现状 首先看一下 Seata 开源社区发展的现状。Seata 已经纳入了 AT、TCC、Saga、XA 四种事务模式对于市面上主流的关系数据库和 RPC 框架做了广泛的支持同时也被许多第三方社区做了主动和被动集成 目前已经和三十多个社区做了开源生态上的集成这些集成依赖于 Seata 现有的可插拔扩展机制设计。
Seata 有着丰富的多语言生态体系 除了最开始的 Java 版本对 Golang 的支持也变得越来越成熟欢迎大家去试用 Golang 版本给社区提出更多宝贵的意见和建议。另外社区还在建设多语言版本包括 PHP、Python 等。
目前 Seata 开源产品已被上千家企业在业务系统中应用金融企业也纷纷试点。 金融类的业务对分布式事务的需求是强需求而且对产品的各项能力要求非常严苛。像中信银行、光大银行、农行与社区也建立了合作使用 Seata 陆续改造它们的一些核心账务系统保证账务体系的数据一致性。这也一定程度上反映了 Seata 开源产品的成熟度。
目前 Seata 社区的 Star 数已经到达了 24kcontributor 超 300 多人。Seata 是非常开放的一个社区非常欢迎大家能够参与到 Seata 社区的建设中。
Seata 企业实践案例 接下来介绍一些 Seata 比较典型的企业案例。
第一个案例中航信航旅纵横项目。 中航信是 Seata 最早的天使用户接入的是 Seata 0.2 版本。如果大家出差比较频繁应该会用到它们航旅纵横的 APP。中航信使用 Seata 解决机票和优惠券业务的数据一致性问题在最早期的版本中用户陪社区踩了不少坑。
第二个案例滴滴出行二轮车事业部。 它在 Seata 0.6.1 版本引入到了二轮车事业部的各个业务中包括市面上大家看到青桔单车和内部资产的管理。
第三个案例美团基础架构。 美团基础架构团队基于开源 Seata 封装了内部分布式事务 Swan 项目作为美团内部各业务解决分布式事务问题的基础组件。
第四个案例盒马小镇。 盒马小镇游戏互动中通过 Seata 控制采花偷花的流程开发周期从原有的 20 天下降至 5 天大幅度减少了开发的成本。
综上可以发现分布式事务的两大价值。
业务数据的正确性因为只有数据一致再谈架构才有意义。提升开发效率架构师和开发者可以专注于业务的设计和开发而无需关注数据一致性的问题。
Seata 生态扩展 上图是 Seata 开放生态扩展点的分层结构。最上层定义了 API 这一层中间这一层包括注册配置中心、AT 数据库资源、分布式锁和负载均衡策略等下层包括集群的存储模式SQLParser协议层和传输控制。在集群模式中支持无状态的基于 DB 或 Redis 的存储模式此外社区正在做基于 Raft 的存算不分离的集群模式。
Seata 可插拔扩展点 Seata 在定义可插拔的扩展机制参考了 Dubbo SPI 的设计。Seata 的扩展点分为 Server 扩展点和 Client 扩展点。Client 扩展点大概有 30 个主要面向配置服务注册发现鉴权SQL 解析和执行器等。Server 侧的扩展点包括锁、存储、事务模式的处理。
从当前 Seata 的扩展机制来看比如你要去支持一个国产信创数据库如达梦、人大金仓二次开发的成本是比较低的。只需要按照社区提供的文档对现有的 SQL 解析和执行器 SPI 进行对应数据库的实现和配置加载就能把整个流程跑起来。Seata 对市面上常见的 RPC 框架和关系数据库做了扩展实现。
Seata RPC 集成扩展 目前 Seata 已经支持了 11 种常见的 RPC 框架对 Dubbo 的适配社区支持了早期的 Alibaba Dubbo 版本和后续的 Apache Dubbo 版本。Seata 和 RPC 框架的集成比较轻量核心是要把 Seata 的事务上下文通过服务调用链路传递到服务的上游并对事务上下文的绑定和清除等操作。Seata 可以在 RPC 框架提供的 request/response 扩展点实现上述 Seata 的扩展逻辑常见的 RPC 框架基本支持自定义 filter 或 interceptor 的加载。
右边是当前实现 RPC 接口扩展的样例欢迎大家在 Dubbo 的生态去使用 Seata 去解决跨服务的数据一致性问题。
Seata 数据库集成扩展 目前 Seata AT 模式数据库支持 MySQL、Oracle、PostgreSQL、TiDB、OceanBase、SQLServer 等数据库。社区仍有一些数据库适配相关的 PR 当前还在 review 状态中未合并到主干中像达梦和 IBM DB2 等。就像刚才提到的只要基于当前的数据库的扩展点去做对应的实现就能实现尚未在社区支持的关系数据库适配。在近期的编程之夏活动中社区提了 PolarDB 课题的支持目前也已进入到测试状态后续社区将完整的支持 top20 的关系数据库同时也将增加对信创数据库的支持。
总结
Seata 起源于阿里内部电商业务体系解决服务化过程中的服务一致性问题经过了多年标准化建设和大促流量的洗礼Seata 已成为交易、支付和物流场景的标准化组件。Seata 开源后通过社区驱动的方式加速技术的探索和演进致力于打造一站式的分布式事务解决方案囊括了 AT、TCC、Saga 和 XA 多种事务模式满足不同场景的用户需求。Seata 在社区生态上做了大量的集成与被集成通过插件化的方案预留了丰富的扩展点满足不同场景的用户对服务调用框架、数据库和注册配置中心的扩展需求。展望未来Seata 社区立足于分布式事务解决方案来继续完善其生态同时将探索和延展更广阔的 DataOPS 生态。