2013 年 2 月 2 日,@陈怀临 在新浪微博上发了一张图片,描述几天前 Amazon 云计算平台 AWS 崩溃的原因。他在微博里说,“试图手工沙盘推演Amazon EBS的崩溃。。。不一定对。同学们见笑。”
于是我在他的原帖下面回复,虽然竭力想简洁明快,两三条微博说完。但是写着写着,竟然写了十余条。网友回复,说这样读起来累,不如集合起来,搞个长微博。
好吧,长微博来了。。
如果 @陈怀临 的分析是正确的,那么此次事故的原因,和 2011 年 4 月 20 日那次的事故原因,基本上是一致的。但是 2011 年事故以后,Amazon 号称彻底修复了系统,杜绝了类似事故的发生。如果 @陈怀临 的分析是正确的,Amazon 其实并没有彻底把上次的故障解决,所以旧病复发。
对此,俺持保留态度,静观后续的事故分析。
2011 年 4 月 20 日事故,大致原因是这样的。Amazon AWS 云平台把数据传输分为两类通道,Data Channel 和 Signal Channel。Data Channel 传输内容数据,所以 AWS 给它分配了更多的网络带宽。而 Signal Channel 用来传输控制信号,控制信号来往频繁,但是每则控制信号的字节很少。
另外,每次写数据的时候,AWS 都要存备份,备份地址是由 AWS 调度系统自动指派的。用户向主力节点写入内容数据后,AWS 通过内部发 Signal,寻找最合适的备份节点。所谓 “最合适” 是由 AWS 调度系统,根据管理员预先制定的规则,自动计算出来的。
如果第一次备份没有成功,那么主力节点就认为初选的备份节点挂了,于是它要求 AWS 调度系统,再找第二个备份节点。于是,AWS 调度系统再次群发 Signal,选择次优的备份节点。
问题出在主力节点凭什么,就认定备份节点挂了?AWS 的设计是,备份节点每隔几秒要向 AWS 调度发个心跳,汇报它的工作状态。
按理说,AWS 这两条设计,Data vs Signal Channels 分开,以及备份的替补方案,听起来都很合理。但是,问题出在,假如突发网络拥堵怎么办?
假如网络拥堵了,主力节点向初选的备份节点传输的内容数据,可能不能按时到达。不能按时到达,主力节点就要求调度,立刻寻找次优备份节点。
如果大量主力节点都要求调度寻找次优备份节点,调度就会大量群发控制信号,这就造成了 Signal Channel 的拥堵。这样,就造成了备份节点的心跳,也传不出去。
调度系统收不到备份节点的心跳,根据原先的 AWS 设定,调度系统就要在替补设备中,挑选设备,充当新的备份节点。
刚才说的情况很可怕,但是发生内部网络拥堵的概率,“应该” 微不足道。都是 Amazon 自家人,谁会没事找自家同事的麻烦呢?但是 2011 年 4 月 20 日,这样的小概率事件,还是发生了。当时,AWS 美东地区数据中心要搞维护,据说需要更换一批设备。
更换设备时,必然导致要把内容数据,从原来的节点中,备份到其它节点中去。同时要备份海量内容数据,但是系统操作员,并不了解 AWS 的设计细节。所以,操作员们,没有更改 Data Channel 和 Signal Channel 的设置,就开始做维护了。于是,雪崩开始了。
当主力节点向新选的备份节点,传输内容数据时,大量的主力节点同时做这个操作,于是造成了网络拥堵,确切地说,是 Data Channel 拥堵了。这样一来,大量主力节点就没有在规定时间内,收到来自备份节点传来的控制信号,说内容数据已经按时到达。这是第一轮冲击波。
于是,主力节点向调度系统发送请求,要求另选备份节点。大量的主力节点,同时发出这样的请求,而调度系统随即群发了这些请求。由于 Signal Channel 的带宽较窄,心跳信号被群发的信号堵塞了,这是第二轮冲击波。
AWS 调度系统收不到各个节点的心跳了,它们都挂了吗?调度系统主动发出查询信号,仍然没有回音。不得已,调度系统决定启用替补节点。很快,所有替补节点全部告罄。AWS 急了眼,恨不得用直升机把工程师们,从家里拽到数据中心现场。但是谁也回天无力,终于,AWS 全线崩溃了。
事后,Amazon 的工程师们,写了详实的事故分析报告,没有闪烁其词,没有回避责任。根据协议,对客户该赔的钱,Amazon 也没含糊。所以,业界也没大肆炒作。对于 Amazon 来说,这是一次灾难,但是对于云计算技术人员来说,这是难得的学习机会。这就像地震,对于老百姓来说,这是灾难。但是地质人员来说,地震,是分析地质结构的绝佳机会。
首席画的这四张图,描述的情况,与 2011 年 4 月 20 日的事故很相似。想深入了解的同学,不妨读读 AWS 的历次事故的分析报告,
1. 2011 年 4 月 21 日事故报告: http://aws.amazon.com/cn/message/65648/
2. 2012 年 6 月 29 日事故报告: https://aws.amazon.com/cn/message/67457/
3. 2012 年 10 月 22 日事故报告: https://aws.amazon.com/cn/message/680342/
4. 2012 年 12 月 24 日事故报告: http://aws.amazon.com/cn/message/680587/