首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

谷歌、AWS宕机事故频发,热闹看完该学会什么?

互联网时代对系统的可靠性提出了更高的要求。关键系统往往要求4个9的可用性,也就是每年的不可用时间不能超过53分钟。与此同时,各种开源框架、工具以及工程方法的使用,在提升效率的同时,却也带来了系统架构复杂化、系统失败容易迅速蔓延放大的副作用。有时一个错误的数据操作或者一行简单的代码缺陷就能使核心系统瘫痪且迟迟无法恢复。为了应对这个挑战,不同的公司结合本身的技术能力和业务特点,形成了多样的可靠性最佳实践。 在今天由极客邦科技举办的QCon全球软件开发大会2020(上海站)上,携程集团商旅事业部CTO宋涛博士发表了主题演讲《搭建可靠性系统工程实践》,探讨技术负责人在提升系统可靠性时可能面对的各种权衡和选择,并分享了携程在相关工作的探索中遇到的挑战和得到的教训。以下内容为演讲整理。

我叫宋涛,是携程集团商旅事业部的 CTO。我对系统的可靠性非常有兴趣,或者说有热情。我在读博士期间所做的一部分工作和系统的安全、系统的 integrity,还有系统的可用性紧密相关。在微软 Windows、亚马逊云计算以及携程三个不同的企业工作时,明显能感受到不同的系统对可靠性要求不一样。同时在各自团队当中所形成的规范标准、最佳实践以及流程也有很大的不同。甚至有时候会发现,同样的一种工程实践,在不同的公司、不同的团队也会有不同的效果。

我这次分享面向的听众是中小型互联网企业以及头部互联网公司的一些可以做技术决策的同学,希望能够帮助大家了解在不同的环境下应该做一个怎么样的权衡,然后达到一个什么样的可靠性标准。

可靠性:互联网时代的挑战

在过去的两个月里,我们可以看到全球三大云计算公司:谷歌、亚马逊 AWS、微软 Azure 相继发生大型事故,引发了世界范围的互联网故障。

简单回顾一下:一周之前谷歌全球范围内发生了 45 分钟的服务瘫痪;一个月前,亚马逊在最大的区域,它服务了美国大部分的客户,发生了 5 个小时的服务中断。

熟悉系统可靠性的同学应该很清楚的知道,对可靠性我们有一个比较好用的指标,叫系统可用性或 Availability。业界常用 3 个 9、4 个 9,来计算每年的服务故障时间。头部互联网公司对他们的关键服务,通常提出的承诺是 4 个 9,也就是每年最多故障 53 分钟。谷歌这一个事故就用掉了超过 80%的故障预算,而亚马逊则远远超标了。我在亚马逊工作的时候,其实也经历过一个类似的事件,稍后也会给大家分享一下当时发生事故的原因、整个事件处理的过程以及最后在复盘时得到的一些启发。

我们看一下网上能找到的事故相关公告会发现,谷歌和微软的公告是以状态通知为主,只是简单说明服务宕掉了、正在恢复、然后大概什么时候已经彻底恢复了。 而亚马逊是以自己常用的 6 页纸的复盘文档展现给大家,这种形式是技术人员非常喜欢看到的。简单地看一看,你就能知道是什么原因触发了什么系统故障,它的影响为什么会进一步放大,整个技术团队做了什么去控制影响,在文档中都会有详细记录。这是亚马逊公司文化的一部分,每次故障之后,他们都能够非常好地对事故做总结。

根据我对云计算和事故处理的一些经验,给大家简单分析一下亚马逊的事故报告。由于细节比较详尽,我们可以清楚的知道事故发生是在 Kinesis 跟 Kafka 比较类似的一个数据流的底层数据服务。

我们有时候把它用作 MQ,但它实际上更大的用处是数据复制和传输。在 Kinesis 服务当中前台大的集群,控制系统会记录其他所有工作节点的状态,它的设计当中每一个节点会用一个线程。这次是由于一次扩容,整个控制系统把 OS 的线程完全耗尽,依赖 Kinesis 服务的其他内外部服务也全部失效。整个系统重启也花了很多时间。整个过程跟我 2017 年在 AWS 经历过的事故有点相似,后续会再展开详细讲一下。

然后我们归纳一些共同的点。大家可以清楚的看到,由于这几家公司都是顶级的互联网公司、云计算公司,所以它处理的量是非常大的,量变引起质变,造成它的架构非常复杂或者比较微妙。

架构复杂就非常容易出问题,而且架构复杂了之后,不知不觉引入的关键点就会特别多,一旦关键点被冲垮,特别是超出了它的设计能够应付的范围,这种情况下要恢复其实已经超出了原来积累的所有操作规范,就需要临时改配置,甚至紧急发布。

CNCF 带来的改变

如今 CNCF 里边囊括了几乎是互联网时代你所能想到的所有业界流行的工具。所以了解 CNCF 并逐渐在架构中引用 CNCF 变成了业界比较通用的一种情况。

然后接下来就会造成我说的三个系统 5 种状态,三个系统包括自研系统、基于 Cloud Native 的私有云系统、公有云系统;5 种状态,除了这 3 种系统独有的状态之外,还有两个复合状态。比如说很多大中型互联网公司,如果有了 10 年以上的经历,往往都会有自建的数据中心和自己的一套生态系统。在这种情况下,如果要引入新的像这种 Cloud Native 的系统的话,就有可能会采用自建加开源集成的方式,尽量向国际的开源服务或者开源标准靠拢。在这种情况下,为了保持对前期投入的兼容性,就会对开源组件做大量的定制,给整个系统和研发团队带来一些挑战。

首先架构工作似乎变得好做了,因为有点像搭积木,你只要选择合适大小的积木块,然后不同的颜色把它组装起来。很多积木块本身是有这种高可用设计的,这种情况下你只要告诉大家我又上了一个什么系统什么功能,然后解决了一个什么难题,架构似乎变得既有方向感,也有可操作性。其次,软件开发和设计其实也受益了,会让整个的设计开发变得容易一些,效率高一些。

但是这会给其他工作带来一些挑战,比如说测试。测试往往是基于一些已有系统,然后尽量提升测试的覆盖面和测试的效率。引入新的架构本身就会对这种测试的框架带来很大的挑战。

举个简单例子,如果我们引入一个新的技术,比如容器化。容器化它自然就是说把所有的作为一个容器实例,原来的测试有可能很大一部分就会失败,而且更大的挑战是很难模拟容器调度失败之类的场景,所以一旦这种系统级故障出现,现在的测试是很难发挥作用的。

另外架构升级也会给运维带来很大的挑战。运维变的太难了。首先,我们引入的各种框架,它本身的可用性挑战就非常大。 另外在这上面构建的各种应用发布之后快速部署在大量的机器上,如果这时候出了问题,可能对我们的业务就会有一个非常大的压力,这种情况下对运维的挑战也会非常大。运维的挑战一个是引入了新的系统框架,要保证它的稳定,需要有一个快速检测和反应的实践。

影响可靠性的因素

刚刚讲了一些挑战,下面简单说一下,影响系统可靠性有哪些因素?

主要有三个方面,一个就是整个基础平台,不论是我们自己的数据中心,还是我们使用的云服务,这个基础平台它有可能会挂掉;第二个是我们的应用,它在发布过程中有可能出现问题; 第三个是我们的响应本身也会出现问题,不能很快地控制并恢复故障。

我从网上和技术分享,还有生产当中拿到了一些公开数据,给大家简单分析一下。

首先是数据中心的问题,这里的数据来自 IDC 做的一个公开调查。大家普遍认为造成数据中心问题的两个最大的因素,一个是人为失误引起的大规模故障,第二个是系统故障。所谓系统故障,它可能是某一个单体的系统或者设备出问题。如果大家有运维大集群的经验,就会知道系统故障不是偶发的,而是一个常态。 这两件事情的挑战非常大。规避个人操作的风险对公司的文化和操作规范挑战非常大,而系统故障又是无法避免的。

第二个是我们做应用的时候有可能引起各种问题。第一个是没有 Pre Product 的环境,所谓 Pre Product 就是在发布到生产之前的测试环境,可以很好地模拟生产环境。在这种情况下就是我们现在的技术或者资源不足以模拟出来一个相似度比较高的 Pre-Prod environment,所以造成很多算法发布的时候,在真实的生产数据下,是不是能够很好的发挥作用? 我们在通过一系列的测试之后,其实心里还是没有把握的。直到上了生产环境被打穿那一刻之前,我们一直还信心满满。排名第二的是日常 OPS 操作,我们做各种应用发布维护之类的工作时,也会涉及到比如说改数据改配置,还有集群数集群机器的拉拢拉出,本身也是风险性比较高的。

第三个是在真的出现了意外或 bug 的情况下,怎么能够减少对业务的影响?

第一个因素是减少影响半径或者爆炸半径,blast radius 在云计算和互联网公司经常提,指的就是我扔一个东西,bug 也好,事故也好,它的影响半径是多少,能让多少系统停止服务? 再往上面看是监控和报警,就是说出现故障时你不能及时发现,或者不能实时报警。还有发布过程当中灰度的粒度和推进速度,在进行灰度的过程当中,是不是总是能够有效的把已经灰度的这一部分机器跟其他的机器进行有效的比对,这些也会影响到这些事件是不是能够被快速发现。

那么怎么应对?我简单列了一些方法和工具,并把它们分为三个角色,开发、测试和运维。

这里我想强调两点,一个是不同的操作,在不同的公司,他们所起到的作用可能是不一样的。

第二个是我个人的观点。当你要解决的问题足够大、范围足够广的时候,可能在开发质量和测试环节做改进的效果很容易达到瓶颈,或者导致 ROI 变得越来越低。当质量提升陷入瓶颈或 ROI 变低时,通过增强监控和快速响应能持续提升系统可靠性。

不同公司的做法

在准备 Talk 的时候,我难免会把以前工作中的一些经验拿来对比,这里也想跟大家分享一下。

先说一下微软。因为微软本身是做商务软件和操作系统起家的,本身有非常好的技术积累,技术水平也非常高。因此它对自己的测试和代码质量要求非常高,也非常以此为傲。

微软的工程实践分两个维度来看,一个资源的投入,另一个是对可靠性提升的效果。微软对测试和开发的资源投入比较大,但日志监控和运营有一段时间它不是特别重视。意识文化和习惯确实很大程度上会影响一个公司采用的决策。

右边是它的团队架构,也是简单分三个角色,开发、测试和运维。开发测试基本上是一个大的组织里边会有明确的分工,然后运维处于单独的一个 Service 部门,三者之间分工明确,在一个大的发布周期里面能够配合的比较严肃。 但是如果真的要敏捷发布,或多或少会遇到一些问题。

然后是亚马逊,亚马逊比较直接简单粗暴,它是 DevOps,基本上研发团队里的每一个团队都可以把这三个角色合而为一。一个人既是系统的开发者,也是测试者,也是它的运维者,也是监控和报警的设立者,也是报警的响应者,整体来说责任和权力比较统一。在这种情况下,大家对可靠性提升的效率会更高一点。

然后看看他们的团队架构和实践,我们经常说组织架构决定你是怎么做事情的。大家可以看到,因为团队对 KPI,也就是服务上线之后要稳定运行,无论是功能还是可靠性的要求都非常高。在这种情况下,如果一个团队精力有限,不能无限制的投到测试里面,但它又必须面对各种故障带来的负面影响,那么关键就是要通过各种运维的手段,包括监控报警,包括级别非常高的每周的质量会议,把整体的可靠性性提升上去。

我们可以看看 Code Review 和 Design Review。Code Review 在亚马逊每个团队不太一样,但整体来说质量和投入不是特别高,Design Review 级别高的会非常注意。比如说我依赖这依赖那,Leader 肯定会问你,当你依赖的服务 A 或者是依赖的功能 B 失效的时候,你这边怎么办?然后你有怎么样去规避或者恢复的一些考虑。

另外一个就是运维的上线之前的 Ops Review,功能上线或者系统上线会影响到哪些指标?或者要新建哪些指标,会创建哪些新的报警,然后这些报警是不是已经准备好了 SOP(就是操作规范)。这样每一个报警被触发的时候,SOP 会发到响应人的手机上,就算是对系统了解不深的一个人,也能根据 SOP 做出一定程度上的响应。 如果真的处理不了,他会在很短时间内进行升级或者交给真正的专家来处理。

大家可以看到,他们的组织架构是有不一样的,他们对工程实践的看法、投入以及整个效果也是不一样的。

这里我要给大家分享一下,现在第一种模式正在向第二种模式转换,像大的互联网公司已经基本上都完成了,国外的互联网公司已经走完这个阶段,就是常说的去测试化。像谷歌是比较特殊的,它有一个 SRE 团队,把很多可靠性的提升以及报警的响应归到了一个单独的团队。也许这也是他们的各种事故报告总是语焉不详的一个原因。

在这儿我要加一个比较有意思的观察。我们看到很多国内的互联网公司,他们在一开始团队小的时候,可能使用 DevOps 这么一个方法快速上线。但是当它做大了之后,又开始引入整个测试和运维团队。先 DevOps,然后反向又回到传统团队架构,这也是非常有意思的一点。

我自己的一个想法是,第二种模式要求不同的文化和做事方。如果企业只是单纯地去掉测试,本身又不具备快速响应的实践或者能力不太够的情况下,你会发现自己虽然把测试去掉了,但是相应的能力没有提升,反过来倒逼你又得把测试团队拉回来,才能尽量减少事故发生的频率和影响,这也是一个非常有意思的现象。

说了这么多,其实我的观点已经非常明确了。在某些情况下质量提升非常有效,但是另外一些情况下质量提升存在各种条件不允许。举一个简单的例子,无论你是做系统架构还是做业务开发,你的资源是有限的,而你要对很多人负责,包括对业务负责,在这种情况下,你不可能把太多的资源投入到一些外界不太容易看到的可靠性等工作中,因此测试质量的资源是非常有限的。在这种情况下,可能性能快速响应,特别是基于已经发生的灾难不断提升的快速响应,是一种可以尝试的机制。

故障分享

下面我简单讲一下我在亚马逊 AWS 工作时经历过的一个可靠性事故。2017 年 2 月份,在 9:37 的时候一切还非常平静,这个时候 AWS 一个最大的存储服务,就是我工作的团队发生了一件事。两分钟之后团队的 Leader 就接到了报警,说系统出问题了。

这时立刻转为应急模式,需要做两件事,一是看一下 SOP,就好像飞机驾驶员会有各种事故的应对手册,另一个是去看 dashboard 的各种仪表盘,它会告诉你哪出了问题。然后我们突然发现团队所有的报警都被触发了,这个时候事件就升级了,大家进入了 War Room 的事件升级状态。War Room 是一些互联网公司在处理大型事故当中总结出来比较有效的方式,就是当大规模事件发生的时候,会把一些骨干技术负责人集中在一间房子里,然后这个房子里边大家指挥下边一批人去工作。这种情况下会有一个人负责对更高一层的沟通和决策,整体来说大家各司其职,比较有效率。

在 War Room 里面,我们在 9:48 的时候知道是有人删除了系统状态的全部内容,类似于 SOA 的集中服务的数据全删掉了。比较好的一点是关键数据的备份和恢复是经常做的,所以马上可以恢复。

过了 10 分钟之后,来了一个真正的噩耗。所有的数据都恢复了,所有的系统就要启动的时候,因为系统越来越大,几年没有冷启动,整个起不来了,在这种情况下就是不断的失败,重试再失败。

10:30 的时候,我们成功登上了 CNN 新闻版面,当时 1/3 的美国网站也宕掉了。在这个过程当中就会发现很多子系统上线就被雪崩打垮,有的系统能启动,但光状态加载就要 2~3 个小时,不得不现场改代码。反正出现了各种事件,最后在 13:54,也就是差不多花了 4 个多小时才把系统给恢复。

这件事之后团队进行了几周的大复盘,然后又做了大半年的技术提升。总结一下,在这件事情当中,整个响应是做的比较好的,做得不好的是大规模的重启,设计本身还是有问题。但总体来说对这种事件的响应,还有事件的复盘,会给整个的团队带来一些收获。

携程商旅实践

接下来讲一讲在携程商旅的实践。首先我要务虚一下,讲一下我们在这当中思考的两个角度,第一个是“Quality is not an act,it is a habit”,所谓质量都是日常习惯所产生的后果。如果要让可靠性或者质量变得更高,就是要养成非常好的习惯,相应的,如果现在可靠性不太高,也说明当前的习惯不是特别的优秀。 当你觉得质量不高时,你一定要有一个清醒的认识,习惯可能需要改变,而习惯的改变又特别难。这时候需要什么?需要有一个自动的机制,然后逐渐养成好的习惯。这也是我在商旅团队经常说的,我们要有自动的机制培养好的工程习惯。比如说代码首先要有规范,而有了规范但是如果不能实施也没有用处,所以我们就把它直接做成了自动检测加发布拦截。

另外,我们要 design for failure,需要对我们的 design 模板要求明确加哪些监控、怎么去报警,系统失败了怎么办?另外,我们对事故复盘有非常详细的 COE 记载,COE 就是复盘报告,包括整个故障的时间、花了多久解决、代码有哪些缺陷是可以共享的。

简单介绍一个例子,是我们的监控系统的演变过程。

它首先有的是一个生产维度的数据监控,数据监控就是在生产数据库里面直接拿出来,如果数据跌停了,那肯定是非常大的问题,所以从业务到产品都觉得数据非常关键,一开始认为这个维度非常重要,但是它有一些问题。比如它是监控结果的,而过程当中哪出了问题,其实是不知道的,这造成所有的团队都要反复去看报警,遇到误报又各种不耐烦,到最后有的团队就干脆不看了。

然后是系统数据监控,刚才说的架构提升上线之后,技术中心上了系统监控,系统监控加上业务监控很大程度上解决了问题,特别是我们 24 小时的应急团队。

后来在一次大的事故当中,我们总结出来 SRE 整体的系统方面还要加强,所以开始对关键系统增加流量、成功率以及延时这种 SRE 黄金三元素的监控。

现在我们要推的是在流程或者功能上基于现象的监控,只要出现了问题,没有及时监控,就要补充监控。在监控越来越丰富的情况下,我们就要看响应速度。所以会推出两个平台,一个是统一告警平台,把所有不同渠道的告警统一到一个平台,然后分级分不同的推送方式发出去;还有一个综合响应平台,去统计各种级别的响应,不同级别的告警响应了多少,响应的时间是多少,这些作为 KPI 就能保证响应速度得到提升。

最后还有一分钟时间简单说一下我们的流浪地球项目,这是一个集团级别的重要活动。我们有多数据中心,怎么保证只有一个数据中心工作的情况下,所有的关键服务还能够正常运转?我们大概花了一年多的时间,进行整体的梳理和隔离,从数据的导入和 load balance 开始进行分流。

数据层面,坦率地说我们用的 MySQL 和 Redis 为主的数据存储,对隔离还有整个 DC 隔离之后的存活,不是特别友善,所以我们就进行了 Disaster Recovery 的设计,把所有的关键的数据从一个组服务的数据中心导向另一个数据中心。最终的结果是,通过各种演练保证当出现事故的时候,无论是物理故障还是人员操作失误,都能保证在一个 DC 的情况下,还能够应对正常的业务要求。我们花了很长时间演练,包括服务级别的,包括业务线级别的,最终在今年 4 月份成功完成了集团整体的演练。

回顾一下,控制影响半径,包括设计的时候做一些隔离响应,在发布的时候也能够进行灰度等。另外就是在基础架构里保证一定区域能够独立的进行 operation。还有提高反应速度,通过对各种事件添加监控,同时对反应速度进行整体的一个 measurement。我认为这些是比较行之有效的方法。

技术展望

我认为未来系统架构会越来越复杂,整体的数据和流量的体量也会越来越大,这会导致可靠性的挑战越来越大。而常规的开发测试以及其他的手段对可靠性的提升会出现一些边界效应,投入很多,但还是有太多的场景和危险区域覆盖不了。

在这种情况下,快速响应和控制影响半径,是当前的互联网需要重视起来的两个工程实践方向。我的观察是很多公司缺少这方面的积累,这也是我今天特别想给大家分享的一点。

最后回到我刚才说的机制和习惯,如果一个公司在可靠性方面积累了比较好的自动机制和比较好的文化,未来将会有比较好的竞争优势。

  • 发表于:
  • 本文为 InfoQ 中文站特供稿件
  • 首发地址https://www.infoq.cn/article/ScP9570SIUl8G2Nr5gjb
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券