文章作者:姜南(Slyar) 文章来源:Slyar Home (www.slyar.com) 转载请注明,谢谢合作。
Amazon AWS 事故报告:https://aws.amazon.com/message/101925/
美国时间2025年10月19日星期一和10月20日星期二,亚马逊云 Amazon AWS 发生了严重的宕机事故,虽然问题的源头只在US-EAST-1区域(Northern Virginia Region),但其影响确是全球性的,事故导致多个大型互联网服务(Slack, Ring, Robinhood, Reddit, Roblox等)瘫痪或中断,整个事故持续了大约15个小时,堪称史诗级事故了。公开的事故报告很长,这里我简单提炼一下核心内容方便以后查阅。
DynamoDB DNS
造成本次事故的核心服务是Amazon DynamoDB,它是 AWS 托管的一个高性能 NoSQL 数据库服务,它不仅是AWS客户用来构建应用的基础服务,同时也是 AWS 内部众多其他核心服务 (比如EC2云服务器,S3存储,IAM身份认证) 用来实时存储和查询状态和元数据(metadata)的核心依赖服务。此次故障由 DynamoDB 的自动化 DNS 管理系统中的一个竞态条件 race condition 引起的 bug 触发,这个 bug 导致了整个 US-EAST-1 区域关于DynamoDB 服务的 DNS 记录 (dynamodb.us-east-1.amazonaws.com) 被错误地清空了,等于是把这个服务从网络里给抹除了,所有依赖 DynamoDB 的客户应用和其他 AWS 服务都无法与该服务建立新的连接,进而导致了大范围的宕机事故。
这个 race condition 挺有意思的,涉及 DynamoDB DNS 管理架构,其中两个重要的概念是 DNS 规划器(DNS Planner)和 DNS 执行器(DNS Enactor),我这里用通俗易懂的方式解释一下。
想象一下 DynamoDB DNS 是一块巨大的白板,上面必须时刻写着 DynamoDB 服务的正确 "地址列表"(一组 IP 地址)以及上一次更新的时间。互联网上所有服务(包括 AWS 自己的 EC2, S3, IAM)都靠看这块白板来找到 DynamoDB。如果白板是空的,灾难就会发生。
我们的主人公是一些各司其职的自动化程序:
- 计划员 (Planner):只有一个保证权威性,他会根据网络和负载情况不断生成最新的和最优的“地址列表”。他会把新列表写在"更新计划"上(比如 更新计划100,更新计划101,更新计划102 …)。
- 执行者 (Enactor): 多个跑腿的程序 (高可用防止单点故障),他们负责从"计划员"那里拿最新的"更新计划",跑到白板前,执行以下流程:
- 用手里的更新计划版本跟白板比较,如果手里的版本比较旧,就什么都不做。
- 如果手里的版本比较新,就用手里的更新计划替换白板内容,然后执行清理程序 (clean-up process) 把所有比手里版本更陈旧的更新计划删除。
好,现在故事开始,白板上的内容现在为"更新计划100":
- 00:00 - 计划员生成了一个"更新计划101",内容是 DynamoDB 正确的地址列表。
- 00:01 - 一个执行者"E1"拿到了"更新计划101"并走到了白板前发现101>100于是决定替换白板内容,但因为一些原因他迟迟没有进行更新操作 (unusually delayed),此时白板上的内容还是"更新计划100"。
- 00:02 - 计划员生成了一个"更新计划102"。
- 00:03 - 一个行动迅速的执行者"E2"拿到了"更新计划102"并跑到白板前,比较发现102>100,于是他把白板内容替换为"更新计划102",然后准备执行清理程序。
- 00:04 - 延误的执行者"E1"终于回过神来,继续之前工作,因为他之前已经决定替换白板上的内容了,而且也不知道E2来过,所以他直接把白板上的内容替换为了"更新计划101"。
- 00:05 - 执行者"E2"开始执行清理程序,他发现白板上是比自己手里更老的版本"更新计划101",于是删除了这个计划,此时白板上所有关于 DynamoDB 的地址都被删除了。
- 00:06 - 计划员生成了一个"更新计划103",内容是 DynamoDB 正确的地址列表。
- 00:07 - 一个执行者"E3"拿到了"更新计划103"并跑到白板前,看着空白的白板陷入了沉思,没有版本号就不知道手里的更新还是更旧,为了安全最好的办法就是啥也不干。很快,执行者 E4, E5, E6 ... 陆续到来,望板兴叹。
最终,SRE 被 page 之后人工介入更新了 DNS 记录并恢复了 DynamoDB 的服务,历时大约3小时 (23:48 - 02:40)。关键系统对DNS的依赖性风险还是非常大的,过去几年已经有过很多次大型的事故的根源都是DNS。
Amazon 的 Route 53 居然没有机制来保证数据的完整性和一致性这点我挺意外的。负责 DNS 更新的“执行者” (Enactor) 在多个版本的检查、更新与清理操作中不是原子操作(atomic operation),而且是多线程并发执行,这就不可避免地会出现上下文切换与中断,从而导致 race condition。AWS 出这种问题,属实是草台班子了哈哈。

其他AWS服务
DynamoDB恢复之后,其他一些核心AWS服务的恢复仍然耗时十几个小时。
EC2就是AWS的虚拟机服务。
DropletWorkflow Manager (DWFM) 负责管理 EC2 使用的底层物理服务器 (droplets),包括跟踪服务器状态和维护租约,这个组件依赖 DynamoDB 进行状态检查。
Network Manager 负责在 EC2 实例启动后,传播网络配置。
Network Load Balancer (NLB) 就是他们的负载均衡器吧,一般这种都带一个健康检查,发现不健康的就移除。EC2 实例就是在这个 NLB 后面的。
DynamoDB 恢复后,DWFM 在一瞬间尝试与大量的 droplets 重建租约导致了拥塞崩溃 (congestive collapse),解决方案是对 DWFM 进行限流和选择性重启。DWFM 恢复之后,EC2 实例开始大量启动,Network Manager 又因为处理积压的网络状态请求延迟,这一延迟就可能导致 NLB 判断刚启动的 EC2 实例不健康然后直接按死在摇篮里,然后 EC2 实例反复启动进一步增加网络延迟恶性循环。解决方案也很粗暴,限流 + 禁用了 NLB 健康检查,让更可能多的 EC2 实例启动。当然缺点就是慢,直到下午 13:50 EC2 才完全恢复。
非常经典的大规模恢复时遭遇瓶颈产生Cascading Failure连锁反应的案例。
转载请注明:Slyar Home » 2025 Amazon AWS 宕机事故 TLDR




























