知识卡片
可靠事件队列靠最大努力交付实现无回滚的最终一致
内容
可靠事件队列是[[从强一致性到最终一致性的BASE理论重新定义一致性]]里最 朴素的一种柔性事务实现。核心思路:先按出错概率给各子操作排序(越容易 失败的越先做),最容易出错的那一步用本地事务完成,同时在同一个本地事务 里写入一条状态为”进行中”的消息;再用一个独立的消息服务定时轮询这条消息, 把它推给其余服务去完成各自的本地操作。一旦第一步的本地事务成功,后续 就没有”失败回滚”的概念,只有”持续重试直到成功”——网络问题导致消息没 送达就反复重发,下游服务暂时无法完成(如缺货)就一直重发直到条件满足或 人工介入,这种”不回滚只重试”的模式被称为”最大努力交付”(TCP重传ACK 丢失后自动重发也是同一原理),更笼统的说法是”最大努力一次提交”(Best- Effort 1PC)。这个方案的强依赖前提是所有被重发的操作必须具备幂等性(通常 靠给每个事务分配唯一ID来保证),否则重复重试会造成重复扣款/重复发货。它 的代价是完全没有隔离性——多个并发事务之间互不设防,这也是它容易出现 “超售”问题、不适合需要强隔离场景的原因(见[[TCC的Try-Confirm-Cancel 如何在分布式事务中保留隔离性]])。
参考来源
- 位置:《凤凰架构:构建可靠的大型分布式系统》第3章"事务处理"3.4.2节
"可靠事件队列"(源文件:_epub-src对应OEBPS/Text/chapter32.xhtml)
- 结论依据:原文详述先做出错概率评估排序、最先出错步骤用本地事务写入
消息、消息服务持续轮询重发直至成功的完整流程,并指出这种依靠重试的
方案被称为"最大努力交付",需要幂等性保障,直接支撑本卡片结论。
- 原始内容:以上这种依靠持续重试来保证可靠性的解决方案……有了专门的
名字——"最大努力交付"(Best-Effort Delivery)……由此可见,可靠事件
队列只要第一步业务完成了,后续就没有失败回滚的概念,只许成功,不许
失败。