2022年12月18日, 阿里云香港区域的C可用区, 因为空机房故障, 导致了大面积的云服务不可用, 并且导致其他本来不应该受影响的对象存储OSS, 以及云控制台和云API不可用. 故障持续了十几个小时.
25日, 阿里云公布了关于阿里云香港Region可用区C服务中断事件的说明, 公开了故障的具体时间线, 并且给出了几项改正措施.
业内人士基本都能理解机房故障, 尤其是香港机房故障, 是难以避免的. 但是大家很惊讶是阿里云自己的API服务无法抵御单机房故障:
14:49开始,ECS管控服务触发限流,可用性最低跌至20%。客户在使用RunInstances/CreateInstance API购买新ECS实例时,如果指定了自定义镜像,部分实例在购买成功之后会出现启动失败的现象,由于自定义镜像数据服务依赖可用区C的单AZ冗余版本的OSS服务,无法通过重试解决。
新扩容的ECS管控系统启动时依赖的中间件服务部署在可用区C机房,导致较长时间内无法扩容。
从用户角度解读就是这样的: 当C区因为物理故障而不可用的时候, 客户也无法在其他几个区创建新的替代资源, 因为:
- 阿里云的API服务器已经过载, 而其扩容动作因为依赖于一个C区的未名中间件服务又失败了.
- 即使你重试多次到达API服务器, 你的API调用也可能依赖自定义镜像服务, 而镜像服务又依赖只部署在C区的OSS服务, 因此还是失败.
第一个问题, 毫无疑问, 是阿里云API团队的设计失误, 他们就不应该依赖于一个单区的中间件.
第二个问题稍微复杂一点, 这里的链条是:
API调用 -> 镜像服务 -> OSS服务
其中OSS服务有两种部署模式: 本地冗余LRS模式只部署在单一AZ中, 如果该AZ不可用, 则OSS不可用. 同城冗余ZRS模式则部署在3个AZ中, 任意一个AZ故障, 不影响OSS的可用性. 此次故障中, OSS服务正采用了本地冗余模式, 当C区空调故障的时候, 整条链条就断了.
显然苛求API服务团队去研究其二级供应商是否多AZ部署, 是不近人情的. 那么问题就化成了: 明明有同城冗余模式可选的时候, 为什么镜像服务选择了本地冗余模式?
相对于同城冗余, 本地冗余的可用性(Availability)和持久性(Durability)都更低, 其唯一优势是更便宜. 但是在香港区域, 本地冗余模式是0.136元/GB/月, 而同城冗余模式是0.156元/GB/月, 也就便宜12%, 考虑到镜像服务是关键服务, 而镜像所占空间不大, 省这个三五毛钱是没有意义的.
我的猜想是: 镜像服务选择了单AZ部署, 并不是一个主动的选择, 只是因为他们使用了OSS服务的默认配置.
上述OSS服务的冗余模式是由Bucket的DataRedundancyType所决定的.
Bucket的数据容灾类型取值范围如下:
- LRS(默认) :本地冗余LRS,将您的数据冗余存储在同一个可用区的不同存储设备上,可支持两个存储设备并发损坏时,仍维持数据不丢失,可正常访问。
- ZRS:同城冗余ZRS,采用多可用区(AZ)机制,将您的数据冗余存储在同一地域(Region)的3个可用区。可支持单个可用区(机房)整体故障时(例如断电、火灾等),仍然能够保障数据的正常访问。
可以看出, 除非客户特别指定多AZ部署的ZRS模式, OSS默认把OSS部署在一个AZ.
阿里云OSS在存储类型介绍中该有特别说明:
重要 本地冗余存储类型的数据冗余在某个特定的可用区内。当该可用区不可用时,会导致相关数据不可访问。如您的业务需要更高的可用性保障,建议您使用同城冗余的存储类型来存储和使用数据。
这反映了阿里云OSS的一个理念: 默认客户不需要多AZ可靠性. 如果一个AZ出故障, 客户的服务就不可用. 如果一个AZ损毁了, 客户的数据就丢失了.
我要说, 这是一个很吓人的假设. 阿里云自己的镜像服务很可能就是这样掉入陷阱的.
如果阿里OSS的理念并不满足企业对可靠性的要求, 那么其他云呢?
腾讯的COS服务同样把单AZ部署当作常态, 而视多AZ部署为需要显式设置的特例:
存储桶多 AZ 配置开启后,将同时开启版本控制。开启后,将无法进行修改,并且数据将以支持多 AZ 特性的存储类型(例如标准存储(多 AZ)、低频存储(多 AZ))存放在存储桶中,请谨慎配置。
华为云OBS服务也默认用户对象存储服务使用单AZ部署
x-obs-az-redundancy 创建桶时带上此消息头设置桶的存储类型为多AZ。不携带时默认为单AZ。用户携带该头域指定新创的桶的存储类型为多AZ,
甚至OBS还有一个更吓人的设计:
存在一种情况是当该区域如果不支持多AZ存储,则该桶的存储类型仍为单AZ。
也就是说, 即使我明确要求多AZ部署, OBS服务也可能因为区域设置给我自动降级成单AZ部署.
OBS团队可能认为这是一个很友好的设计, 但是这种静默失败(Silent failure)是企业用户最忌讳的.
打个比喻, 企业CEO要给100个优秀员工发一台Huawei Mate 50 Pro当年终奖, 下单的时候OBS团队说没问题, 但是因为没货, 悄悄的把40台换成了华为小灵通. CEO直到年终晚会的时候才发现自己要把小灵通当奖品发, 会是什么感受? 一个工程师给对象设置了多AZ模式, 然后在故障的时候才发现被替换成单AZ模式了, 会是什么感受?
这时候, 我又要请出云计算的开山鼻祖AWS了.
AWS的对象存储模型很直接: 他们默认的冗余模式是多AZ, 而视单AZ冗余模式为需要显式配置的省钱模式.
至于因为默认多AZ部署带来的额外成本, 他们通过一个正交的特性来解决: S3 智能分层.
这样, 你默认获得多AZ的可靠性和持久性, 但是你要想省钱的话, 也有办法. 作为企业客户, 我认为这是让人满意的理念.
当然, AWS这样做是有硬件支撑的: 他们的每个区域(region)都有三个以上可用区(AZ).
华为云在多个区域(深圳, 圣地亚哥, 贵阳一)只有一个AZ, 在这些区域的OBS只能部署为单AZ冗余模式.
阿里云在曼谷, 迪拜, 首尔和马尼拉的区域只有一个AZ, 可以理解为海外投资谨慎. 但是他们在福州, 南京也分别有个只含一个AZ的区域, 就让人费解了.
而腾讯云虽然在大多数区域有多个AZ, 但是只在有限的区域(北京、上海、广州、新加坡)支持COS的多AZ部署, 非常让人费解.
阿里云/腾讯云/华为云由于基础设施的欠缺和理念的不同, 默认把你的对象存储都放置在一个AZ. 所以你的对象存储能抵挡单机宕机, 但是无法抵挡机房故障. 如果机房因为火灾不能恢复的话, 你的对象还可能永久丢失!
鉴于阿里云自己的镜像服务都被这个设计坑了, 我建议你检查下你的OSS/OBS/COS桶的设置, 对那些不能丢失的数据, 尽量开启多AZ冗余模式.
如果您觉得我的文章对您有帮助, 欢迎给我发私信留言. 我考虑再写一篇文章, 从成功案例看几家主要本土云厂家运用对象存储的水平. 透露一下: 很不乐观.