复盘AWS宕机15小时关键过程,其问题的根因竟然是...
DynamoDB 自身承载着数据面服务IP的注册工作,而 AWS 自己的内部控制面也构建在 DynamoDB 之上。这是一种隐藏的依赖关系。当 AWS 的内部服务找不到 DynamoDB 的 IP 时,整个控制面崩溃了。即便内部服务正常运行,也无法使用。
具体可以分为以下几个步骤:
第 1 阶段:DNS 失败。dynamodb.us-east-1.amazonaws.com 的内部 DNS 服务器停止工作。
第 2 阶段:控制平面失败。依赖 DynamoDB 的 AWS 自己的服务立即崩溃。这包括:
IAM(用于身份验证和会话状态)
EC2 实例启动子系统(使用 DynamoDB 作为元数据)
Network Load Balancer (NLB) 异常(事实情况是:运行健康状况检查不正常,将其运行状况状态写入 DynamoDB 表)
第 3 阶段:循环依赖。这是出错的主要原因。当 NLB 运行状况检查失败时(因为它们无法写入 DynamoDB),它会导致更多的网络无法连接问题,这反过来又影响了(已经陷入困境的)DynamoDB 服务本身。它创造了一个恶性的反馈循环。其实这里才是出错的根本原因:一个负责监控网络负载均衡器的子系统挂了;这导致负载均衡器(NLB)异常,因为DNS记录存储在DynamoDB中,所以这又反过来污染了 DynamoDB 中的DNS 记录(表面看起来是 DNS 挂了,其根因是监控子系统挂了导致 DNS 不能正常使用);所以也就酿成了最终的悲剧。
所以修复问题只用了几个小时。恢复花了这么长时间的原因猜测有两个:
全局控制平面:AWS 的许多核心控制平面服务(如 IAM)都集中在 us-east-1 中。即使您的应用在 eu-west-1 中运行,如果它需要进行身份验证或启动实例,该控制平面作也会通过 us-east-1 路由并失败,进而无法使用。
重试风暴:DNS 查询使用 UDP,这是一种无状态的“触发后忘记”协议。当 DNS 查询失败时,数百万客户端(开发工具包、Lambda 函数、其他 AWS 服务)没有立即收到“连接被拒绝”(如 TCP)。他们只是在 5+ 秒后超时,然后重试。这造成了数百万个请求的“重试风暴”(或雷鸣般的群体),这些请求二次伤害了 DNS 服务器和缓存,即使在初始修复程序完成后也无法快速恢复它们。
其实这种循环依赖问题在云厂商内部绝对不止一次发生,我们都知道这是系统架构设计不佳问题,把所有的鸡蛋都放到一个篮子里,没有冗余,没有故障转移,但某种层面上,也可能是一种权衡,因为对于绝大多系统来说,宕机可能比冗余更便宜......
原创不易,随手关注或者”在看“,诚挚感谢!
更多推荐
所有评论(0)