为了账号安全,请及时绑定邮箱和手机立即绑定

谈谈微服务架构中的原子性

标签:
微服务

分布式的数据管理难题可以通过基于事件驱动的微服务架构来解决。

那么在分布式数据管理的过程中,怎么保证原子性呢? 试想有这样一个场景,微服务1 中需要更新数据,同时发布一个数据更新的事件到服务2,那么在执行这个事务的过程中,微服务1刚更新完数据,系统出现了故障,数据更新的事件没有发布出去,怎么保证事务的一致性呢。

本文详细分析下这个问题。

方法一: 在发布事件的过程中使用本地事务。

来自Ebay的Dan Pritchett 提出了这样一种方法,那就是应用程序使用只涉及本地事务的多步处理流程。

具体的实现办法就是: 在存储相关数据实体状态的数据库中创建一个记录事件状态的表,这个表可以起到消息队列的作用。

那么应用程序在开始本地事务的时候,首先更新业务实体的状态,在事件表中插入一条事件数据,并提交事务,通过一个单独的进程来查询这个事件表,如果事件的状态是正确的, 将这个事件发布到消息队列中,然后在本地数据库中将事件标记为已发布。

图片描述

这个方法的优缺点分析如下:
优点:

能够保证每次更新的时候发布一个事件,不依赖于两阶段提交,同时保证了原子性。

缺点:

  1. 容易出错,在更新完数据实体后,不能忘记还要去发布事件。
  2. 对于一些对事务和查询能力支持不够的NOSQL来说,这个方法比较难实现。

方法二: 直接抓取数据库的事务更新日志。

数据库在更新事务之后,会有相应的日志,开启一个进程,定时的扫描日志文件,来找到需要发布的事件,同时讲这个事件发布出去。

图片描述

LinkedIn有一个开源数据库项目叫DataBus,挖掘Oracle事务日志并发布与更改对应的事件。LinkedIn使用DataBus来保持各种派生出来的数据存储与系统记录一致。

另一个例子是aws的dynaminodb中的streams机制,它是一个受管理的nosql数据库。dynamodb流包含在过去24小时内对dynamodb表中的项所做的更改(创建、更新和删除操作)的时间顺序。应用程序可以从流中读取这些更改,并将其发布为事件。

事务日志挖掘有很多优点和缺点。一个好处是:
它保证在不使用2PC的情况下为每个更新发布一个事件。
事务日志挖掘还可以通过将事件发布与应用程序的业务逻辑分离来简化应用程序。

一个主要的缺点是,事务日志的格式是每个数据库的专有格式,甚至可以在数据库版本之间进行更改。此外,很难从事务日志中记录的低级更新对高级业务事件进行逆向工程。

方法三: 使用事件源

事件源通过使用完全不同的、以事件为中心的方法来持久化业务实体,从而在没有2PC的情况下实现原子性。应用程序存储一系列状态更改事件,而不是存储实体的当前状态。应用程序通过重放事件来重建实体的当前状态。每当业务实体的状态发生更改时,都会在事件列表中追加一个新事件。由于保存事件是一个单独的操作,因此它本质上是原子的。

事件保存在事件数据库中,而且提供添加和查询的API,这个事件源实际就类似于微服务架构中的消息队列。

图片描述

事件源结构的好处是:

  1. 解决了原子性的问题,事件源提供可靠的日志。
  2. 对于从传统遗产系统迁移到微服务架构时,使用事件源是一个很好办法,因为它实现了微服务内部的松散耦合。

事件源的缺点是: 开发难度比较大,需要学习。

以上就是三种保证原子性的方法。

点击查看更多内容
1人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消