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)这个问题。然而,它们具有复杂性,可能不适用于所有技术,因此在实施它们之前,请确保您了解权衡。

相关推荐
猫猫不是喵喵.13 小时前
从0到1创建一个微服务项目
java·数据库·微服务·1024程序员节
htzyl20615 小时前
别急着上微前端:从 6 个场景倒推 Module Federation 2.0 与 qiankun 2.x 的选型
前端·微服务
知守观17 小时前
一个方法两个触发口:反编译 XXL-Job 后,我看清了 inner/job 子包的裸奔现状
java·spring boot·微服务
草莓熊Lotso2 天前
【C++ 基于微服务的即时通讯系统】文件存储子服务实战:UUID生成、文件IO封装与全接口单元测试
开发语言·网络·数据库·c++·微服务·架构·单元测试
wdyan2977 天前
带着小白学习-微服务-5 实战:配置中心-数据库连接
数据库·学习·微服务
胡写代码8 天前
把数据库连接搬进配置中心,服务起不来:spring.config.import 的 4 个必填项
spring cloud·微服务
利威尔xu10 天前
Go IM 源码实战(14):本地缓存快 3000 倍,失效却难 10 倍
后端·缓存·微服务·面试·golang
利威尔xu10 天前
Go IM 源码实战(13):30 个会话只有 2 个红点,未读数错在三条路径
redis·后端·微服务·面试·golang
骑着蜗牛撵大象32711 天前
Spring Boot 4.1 + Spring AI 2.0:RAG 供文、图谱供关系、MCP 供工具的 Java Agent 平台
java·spring boot·spring·微服务·知识图谱·rag·mcp
code_slave(码畜)11 天前
微服务架构落地:慢 SQL 治理与连接池调优 —— 守住数据库的最后一道防线
数据库·spring boot·sql·spring cloud·微服务·架构