Dual-Write Problem 双写问题(微服务)

原文链接https://www.confluent.io/blog/dual-write-problem/

双写问题发生于当两个外部系统必须以原子的方式更新时。

问题

说有人到银行存了一笔钱,触发 DepositFunds 命令,DepositFunds 命令被发送到Account microservice。

Account microservice需要做两件事,修改过数据库 和 发送消息到kafka。

Figure 1: A microservice writes to two separate systems.

如果在修改数据成功之后, 系统崩溃,发送kafka 消息失败,这样就造成了相关kafka事件丢失。

Figure 2: A failure results in a missing event.

同样的问题也会发生于任何系统,包括 monolithic和microservice 系统, 只要是尝试写两入两个独立的系统,却只有其中一个操作成功。

解决办法

事务发件箱模式(transactional outbox pattern )

同时利用了数据库事务和重试机制。

这种模式其实就是在 Account microservice 写数据库表的同时,把要发到kafka的消息先写入一张outbox表。这里写入的两张表在同一个事务(transaction)里完成。

至于outbox 表中的数据,可以由专门的程序负责读取和发送到kafka,也可以利用CDC(change data capture)完成。对于发送失败可以加入retry。在确定发送成功之后,可以删除outbox表中的数据。

Figure 9: The transactional outbox pattern.

Event sourcing

事务发件箱模式不合适于不支持事务的数据库,而不依赖于数据库事务的就是 event sourcing。

这种模式不另外写一张表来保存要发送的数据,而是在原来表上(这里原来的表是存放的event,而不是事物发件箱模式中的数据)加一个flag,来过滤那些已经发送过了。

++(😂是不是觉得很。。。 反正我看到这里,哎!😂)++

The listen-to-yourself pattern

和 event sourcing很像,只不过event sourcing是先写表,在发送至kafka。

而 listen-to-yourself pattern 是直接写入kafka。在从kafka接收消息来修改数据库,同时写表需要retry跟上。

只不过就是这个先后顺序问题,写表虽会最终一致,但若在未写表之时,访问数据库则问题出现。

若系统可接纳,则无所谓。

其它解决办法

还有其他解决双写问题的方法,我们在这里没有介绍。其目的不是暗示这些是解决问题的唯一方法,而是强调在事件驱动系统中特别有用的具体解决方案。

在某些情况下,可以使用两阶段提交( two-phase commit aka 2PC)、扩展架构(extended architecture aka XA)事务和传奇模式(saga pattern)等技术来规避(circumvent)这个问题。然而,它们具有复杂性,可能不适用于所有技术,因此在实施它们之前,请确保您了解权衡。

相关推荐
工业互联网专业2 小时前
基于springcloud微服务架构的巡游出租管理平台
java·vue.js·spring cloud·微服务·毕业设计·源码·课程设计
陌言不会python3 小时前
谷粒微服务高级篇学习笔记整理---thymeleaf
笔记·学习·微服务
极客先躯17 小时前
高级java每日一道面试题-2025年3月21日-微服务篇[Nacos篇]-什么是Nacos?
java·开发语言·微服务
程序员ys1 天前
微前端是什么?
微服务·架构·前端框架
kill bert1 天前
第32周Java微服务入门 微服务基础
java·开发语言·微服务
Mia@2 天前
网络通信&微服务
微服务·云原生·架构
Julian.zhou2 天前
MCP服务:五分钟实现微服务治理革命,无缝整合Nacos/Zookeeper/OpenResty
人工智能·微服务·zookeeper·交互·openresty
冰 河2 天前
《Mycat核心技术》第21章:高可用负载均衡集群的实现(HAProxy + Keepalived + Mycat)
分布式·微服务·程序员·分布式数据库·mycat
A叶子叶2 天前
Kong网关部署研究
python·spring cloud·微服务·gateway·kong
小李同学_LHY3 天前
微服务架构中的精妙设计:环境和工程搭建
java·spring·微服务·springcloud