重试无法解决最终一致性
摘要
文章认为,在最终一致的分布式系统中重试消息会将正常状态误判为故障,并建议改为存储传入数据,待所有前置条件到达后再处理,从而无需重试和死信队列。
<p><a href="https://lobste.rs/s/t0cn1z/retries_don_t_fix_eventual_consistency">评论</a></p>
查看缓存全文
缓存时间: 2026/08/03 09:32
重试无法修复最终一致性 — var0.xyz
来源:https://var0.xyz/posts/retries-dont-fix-eventual-consistency.html
2026\-08\-02重试是一种让人觉得显然正确、以至于我们很少停下来质疑的模式。出了故障?再试一次。如果仍然失败,等久一点再试。如果还是不行……就继续试。
有时候这正是正确的做法。但有时候我们重试的地方实际上并没有发生故障。
## 当重试变成一种设计模式
我曾与人讨论一个分布式系统中处理消息的方案。想象一下,一个服务发出“用户已创建”事件,另一个服务发出“订阅已创建”事件,而第三个服务需要同时具备两者才能处理该订阅的付款。
提议的解决方案很简单。如果订阅事件在本地用户存在之前到达,就将其视为错误。把消息移入死信队列,必要时让人检查一下,稍后重试。
乍一看,这听起来完全合理。毕竟所需的数据不在那里,但这种说法隐藏了一个重要的假设:有东西出错了。
## 系统并没有坏
实际上,可能根本没有出任何问题。
分布式系统并不承诺信息会同时或按顺序到达所有地方。它们承诺的是,最终会到达。这正是最终一致性背后的全部理念。
如果一个事件比另一个事件先到达,系统并非不可用。它并非处于异常状态。它只是在按照设计之初所提供的保证行事。
这是一个微妙但至关重要的区别,它改变了一切。
## 这不是 bug,而是一种性质
一旦你把最终一致性视为一种性质而非错误条件,整个架构看起来就大不相同了。
与其把缺失信息视为需要干预的故障,你会意识到这只是系统另一种可能的状态罢了,别无其他。
存储每一条到达的数据。每当新数据到达时,检查所有必需的数据是否都已存在。如果是,就执行工作;如果不是,就什么都不做。
没有重试。没有死信队列。没有人工手动重放消息。
随着信息的可用,系统的内部状态自然推进。
## 复杂性随之消失
解决对的问题,最令人满足的事情之一,就是目睹那些无关的问题也随之消失。
想象一下,某个服务不可用了一分钟。消息堆积起来。一些消息进了死信队列,而服务恢复后,较新的消息继续在系统中流转。
现在你又多了一个要解决的问题:按正确顺序重放那些较旧的消息。它们应该插队到较新的事件前面吗?处理过程是否要暂停直到它们被重放?如果顺序确实重要呢?
这些问题并非无解,但却是你自己制造出来的问题。
如果每一条消息都只是存储起来,直到所有先决条件都满足,那么所有这些编排都不存在了。随着缺失信息的到达,事件自然就会变得可以被处理。
## 重试并非有害
这并不意味着重试不好。
一次短暂的网络超时?重试。一个数据包被丢弃?重试。分布式系统中充满了短暂的故障,重试一次通常就足以抚平真实基础设施中不可避免的小问题。
但是,当重试次数开始成倍增加时,就值得问一个简单的问题了。
如果重试一次不能解决问题,为什么重试五次就能?第二次尝试和第六次尝试之间发生了什么变化?是否有实际证据表明依赖会恢复,还是我们只是在祈祷它恢复?
## 解决你真正面对的问题
更大的教训其实根本不是关于重试的,而是关于在动手解决问题之前,先正确识别问题。可用性问题需要一套工具,最终一致性需要另一套工具。把一种问题当成另一种问题来对待,通常会导致额外的基础设施、额外的运维负担,以及更难推理的系统。
有时候最干净的解决方案不是找到更聪明的重试策略,而是意识到一开始就根本没有需要重试的东西。
---
如果你更愿意看视频,我制作了这次讨论的视频版本:重试无法修复最终一致性(https://youtu.be/Rk4R5obm8FA)。
感谢阅读。
相似文章
代理的重试逻辑会随代理一起消亡
作者分享了将一个具有写入权限的 AI 代理投入生产环境后的经验教训,指出当进程终止时,代理循环内部的重试逻辑会失效。他们主张将有副作用的工具调用视为带有幂等键的持久后台任务。
重试可能加剧AI失败
本文讨论了在AI系统中,特别是使用大语言模型和智能体时,重试如何可能在根本问题未解决时加剧故障,导致重复错误并增加成本和延迟。
Uber如何防护重试风暴
Uber介绍了一种上下文感知机制,用于在分布式系统中处理重试风暴,以防止级联故障并提高可靠性。
在故障处修复:局部故障恢复的论证
本文主张在分布式系统中采用局部故障恢复机制,强调在组件级别修复故障而非依赖全局恢复的好处。
忠实的,而非纠正的:多跳智能体中继中的消息格式效应依赖于层级
本文研究了消息格式(如自由文本、JSON、三元组)在多跳LLM智能体中继中如何影响信息丢失,发现格式效应取决于中继模型的能力,且结构能忠实地保留内容但不会纠正错误。