从 AWS 故障中学习分布式系统原则 - 过去大规模故障改变的架构

以 S3 故障(2017)、Kinesis 故障(2020)、us-east-1 的特殊性等 AWS 公开的故障报告为题材,解析 Shuffle Sharding、Static Stability、Cell-based Architecture 等设计原则。

故障报告这本教科书

AWS 在发生大规模故障时会公开称为 Post-Event Summary 的详细故障报告。这些报告不是简单的道歉文,而是技术性地描述故障根本原因、影响连锁、恢复过程和防止再发措施的宝贵资料。分布式系统的设计原则往往被抽象地讨论,但与实际故障案例关联后,就能具体理解为什么该原则重要。这里以 AWS 公开的代表性故障报告为题材,解析从中诞生的设计原则。

S3 故障(2017 年 2 月)- 级联故障与恢复的困难

2017 年 2 月 28 日,us-east-1 区域的 S3 停止了约 4 小时。根据 AWS 官方报告,在调试计费系统问题的过程中,从 S3 的索引子系统和放置子系统中删除了超出预期的服务器。问题从这里开始。这些子系统对 S3 的读写操作不可或缺,仅剩的服务器处理能力不足。更严重的是,这些子系统自 S3 创建以来从未完全重启过,重启所需时间远超预期。这次故障教给我们的设计原则是:第一,大规模系统的完全重启成本可能超出想象;第二,级联故障会使影响范围远超最初的触发点。

Kinesis 故障(2020 年 11 月)- 容量扩充引发的故障

2020 年 11 月 25 日,us-east-1 的 Kinesis 发生了约 21 小时的故障。AWS 官方报告揭示的原因是容量扩充本身。Kinesis 的前端服务器群使用网状结构,每台服务器使用一个 OS 线程与其他服务器通信。向后端添加服务器后,前端各服务器的线程数超过了 OS 限制。这次故障的教训是:系统的扩展操作本身可能成为故障原因。添加容量这一看似安全的操作,在特定条件下会触发意想不到的副作用。设计原则是将扩展操作也纳入故障模式分析,并设置扩展速度的限制。

us-east-1 的特殊性 - 为什么只有这个区域故障多

追踪 AWS 的故障报告会发现 us-east-1(弗吉尼亚北部)反复出现。这不是偶然。us-east-1 是 AWS 最古老的区域,IAMRoute 53CloudFront 等全球服务的控制平面集中于此。全球服务是指不绑定特定区域、在全球拥有共同端点的服务。这些服务的控制平面集中在 us-east-1 意味着,该区域的故障会影响全球用户。AWS 正在逐步将全球服务的控制平面分散到多个区域,但历史遗留的集中仍然存在。对用户来说的教训是,即使主要工作负载部署在其他区域,也要理解对 us-east-1 的隐性依赖。

从故障中诞生的设计原则

AWS 从这些故障经验中,通过 Builders' Library 和白皮书体系化了设计原则。Shuffle Sharding 是将客户随机分配到服务器组合(分片)的方法。传统固定分片中一个分片的故障影响该分片所有客户,而 Shuffle Sharding 中每个客户的分片组合不同,一个服务器故障只影响极少数客户。Static Stability 是即使依赖服务停止,系统也能以当前状态继续运行的设计。不是在故障时获取新信息来应对,而是用已缓存的信息继续运行。Cell-based Architecture 是将系统分割为独立的单元(Cell),将故障影响限制在单元内的设计。每个 Cell 独立运行,一个 Cell 的故障不会波及其他 Cell。

应用到自己的系统

这些原则不仅适用于 AWS 规模的系统,也可以应用于一般应用设计。首先,明确把握依赖关系。事先整理自己的系统依赖哪些服务,该服务停止时会发生什么。其次,意识到控制平面和数据平面的分离。即使无法进行配置变更和管理操作,也要设计为现有数据处理可以继续。Circuit Breaker 模式在依赖服务故障时快速失败,防止级联故障。重试时的指数退避和抖动防止恢复时的请求风暴。要深入了解分布式系统设计原则,相关书籍 (Amazon) 也可作为参考。

总结

AWS 的大规模故障是学习分布式系统设计原则的最佳教材。S3 故障教会了级联故障和重启成本的危险性,Kinesis 故障教会了容量变更时意想不到的副作用,us-east-1 反复的故障教会了全球服务集中的风险。从这些经验中诞生的 Shuffle Sharding、Static Stability、Cell-based Architecture 不是理论,而是从实际故障中提炼的实践智慧。将这些原则应用到自己的系统设计中,是提高可靠性的最有效途径。