在新冠肺炎期间,我们是如何攀登谷歌Meet的

2020-08-07 02:31:39

随着新冠肺炎将我们的世界变成一个更加遥远的世界,许多人开始寻求在线视频会议来保持社交、教育和工作场所的联系。如下图所示,这一转变带动了大量额外用户加入Google Meet。

在这篇文章中,我将分享我们如何确保Meet的可用服务能力领先于其30倍的新冠肺炎使用量增长,以及我们如何通过利用大量的站点可靠性工程最佳实践来使这种增长在技术和运营上都是可持续的。

随着世界对新冠肺炎的了解越来越多,人们开始调整他们的日常节奏。该病毒对人们的工作、学习以及与朋友和家人的社交方式产生了越来越大的影响,这意味着更多的人希望通过Google Meet等服务来保持联系。2月17日,Meet SRE团队开始收到有关地区容量问题的页面。

这些页面是有症状的,或者说是黑盒警报,比如“任务失败太多”和“正在卸载的负载太多”。因为谷歌面向用户的服务是建立在冗余的基础上的,所以这些警报并没有指出正在进行的用户可见的问题。但很快就变得清晰起来,该产品在亚洲的使用量呈急剧上升的趋势。

SRE团队开始与容量规划团队合作,寻找额外的资源来应对这种增加,但很明显,我们需要开始更早地规划,以防疫情蔓延到该地区以外的情况。

果然,此后不久,意大利开始了新冠肺炎的禁赛,Meet在意大利的使用率开始上升。

在这一点上,我们开始制定我们的回应。一如既往,SRE团队首先宣布一个事件,并启动我们对此全球容量风险的事件响应。

然而,值得注意的是,虽然我们使用久经考验的事件管理框架解决了这一挑战,但那时我们并没有处于或即将发生停机。没有持续的用户影响。新冠肺炎的社会影响大多是未知的或很难预测的。我们的任务是抽象的:我们需要防止已经成为大量新用户的关键产品的任何停机,同时在不知道增长将来自哪里以及何时稳定的情况下扩展系统。

最重要的是,由于新冠肺炎的原因,整个团队(以及谷歌的其他成员)正在过渡到无限期在家工作的过程中。尽管我们的大多数工作流程和工具已经可以从办公室以外的地方访问,但在虚拟环境中运行这样一个长期事件仍存在额外的挑战。

由于没有能力与其他所有人坐在同一个房间里,主动管理沟通渠道以确保我们都可以访问实现目标所需的信息变得很重要。我们中的许多人还面临着额外的、与工作无关的挑战,比如在我们都适应的过程中照顾朋友和家人。虽然这些因素给我们的应对带来了额外的挑战,但分配和增加备用设备以及主动管理所有权和沟通渠道等策略帮助我们克服了这些挑战。

尽管如此,我们仍继续采用我们的事故管理方法。我们在北美和欧洲设立了事件指挥官、通信主管和运营主管,开始了我们的全球响应,以便我们拥有全天候的报道。

作为整个事件的指挥官之一,我的职能就像一个有状态的信息路由器-尽管有意见、影响力和决策权。我收集了关于哪些战术问题挥之不去,谁在做什么,以及影响我们回应的背景(例如,政府的新冠肺炎回应)的状态信息,然后将工作分派给能够提供帮助的人。通过嗅探和挖掘不确定的领域(两者都在问题定义中:“我们在南美以50%的CPU利用率运行,这是一个问题吗?”和解决方案空间:“我们将如何加快我们的启动过程?”),我协调了我们的整体响应工作,并确保所有必要的任务都有明确的所有者。

响应时间不长,我们意识到我们的任务范围是巨大的,我们响应的性质将是长期的。为了保持每个贡献者的作用域是可管理的,我们将我们的响应塑造成许多半独立的工作流。在它们的作用域重叠的情况下,工作流之间的接口定义良好。

容量,它的任务是寻找资源,并确定我们可以在哪些地方提供多少服务。

与拥有Meet基础设施的团队(例如,Google的帐户身份验证和授权系统)合作,以确保这些系统也有足够的资源来随使用增长进行扩展。

控制旋钮,在即将发生或正在进行的容量中断的情况下,它在系统中构建了新的通用缓解措施。

生产更改,它安全地带来了所有发现的容量,使用新优化的调优重新部署了服务器,并使用可随时使用的附加控制旋钮推动了新版本。

作为事件响应人员,我们不断地重新评估我们目前的运营结构是否仍然有意义。我们的目标是拥有尽可能多的结构来有效运作,但不会再多了。结构太少,人们在没有正确信息的情况下做出决策,而结构太多,人们把所有时间都花在计划会议上。

这是一场马拉松,而不是短跑。在整个过程中,我们定期检查是否有人需要更多的帮助,或者需要休息一下。在如此漫长的事件中,这对于防止精疲力竭至关重要。

为了防止疲惫不堪,事件响应角色中的每个人都指定另一个人作为他们的“备用”。一名候补人员与该角色的主要响应者参加相同的会议;访问所有相关的文档、邮件列表和聊天室;并询问如果他们必须在没有事先通知的情况下接管初选时需要回答的问题。当我们的任何响应人员生病或需要休息时,这种方法就派上了用场,因为他们的待命人员已经掌握了立即生效所需的信息。

虽然事件响应团队正在研究如何最好地协调解决此事件所需的信息流和工作,但大多数相关人员实际上都在解决生产中的风险。

我们的主要技术要求只是保持区域可用的满足服务能力的数量领先于用户需求。谷歌在世界各地运营着20多个数据中心,我们有强大的基础设施可以利用。我们很快利用了现有的原始资源,这足以使Meet的可用服务能力大约翻一番。

以前,我们依赖历史趋势来确定需要调配多少容量。但由于我们不能再依赖历史数据的推断,我们需要开始基于预测性预测来调配容量。为了将这些模型转换为我们的生产更改团队可以在生产中采取行动的术语,需要将使用模型转换为我们需要的额外CPU和RAM所需的容量工作流。后来,通过教我们的工具和自动化来理解它,构建这个转换模型使我们能够加快获得生产中可用产能的过程。

很快,事情变得很明显,仅仅将我们的足迹规模增加一倍是不够的,所以我们开始反对以前不可想象的50倍增长预测。

除了扩展我们的能力之外,我们还致力于识别和消除我们服务堆栈中的低效。我们可以将这些工作中的大部分分成几类:调优二进制标志和资源分配,以及重写代码以降低执行成本。

使我们的服务器实例更具资源效率是一项多维的工作-目标可以用“以最便宜的资源成本处理最多的请求,而不牺牲用户体验或系统的可靠性”来表述。

我们是否预留了比所需更多的RAM,或者预留了比所需更多的CPU?我们能不能更好地把这些资源用在其他方面呢?

我们的网络边缘是否有足够的出口带宽来为所有地区的视频流提供服务?

我们是否可以通过细分正在使用的后端服务器数量来减少给定服务器实例所需的内存和CPU数量?

尽管我们总是对新的服务器形状和配置进行鉴定,但在这一点上,重新评估它们是非常值得的。随着会议使用率的增长,其使用特征-如会议持续时间、会议参与者数量、参与者如何共享音频时间-也发生了变化。

由于Meet服务需要越来越多的原始资源,我们开始注意到,相当大比例的CPU周期都花在了进程开销上,比如保持与监控系统和负载均衡器的连接处于活动状态,而不是用于请求处理。

为了增加吞吐量,即“每CPU每秒处理的请求数”,我们增加了进程在CPU和RAM预留方面的资源规格。这有时被称为运行“更胖”的任务。

在上面的示例数据中,您将注意到两件事:所有三个实例规范都有相同的计算开销(用红色表示),实例的总体CPU预留越大,它的请求吞吐量就越大(用黄色表示)。在分配的CPU总量相同的情况下,4x形状的一个实例可以处理的请求数量是基线形状的四个实例的1.8倍。这是因为计算开销(如持久化调试日志条目、检查网络连接通道是否仍处于活动状态以及初始化类)不会随着任务处理的传入请求数量线性增加。

我们一直试图将服务任务的预留数量增加一倍,同时将整个舰队的任务数量减少一半,直到我们达到规模限制。

当然,我们需要对这些更改中的每一个进行测试和鉴定。我们使用金丝雀环境来确保这些更改按照预期运行,并且不会引入或触及任何以前未发现的限制。与我们鉴定服务器新版本的方式类似,我们鉴定了没有任何功能或性能倒退,并且更改的预期效果确实在生产中实现了。

我们还对代码库进行了功能改进。例如,我们重写了内存中的分布式缓存,使其在跨任务实例切分条目的方式上更加灵活。反过来,当我们增加集群中的服务器实例数量时,这使我们可以在单个区域中存储更多条目。

尽管我们对使用量增长预测的信心正在提高,但这些预测仍然不是100%可靠的。如果我们在一个地区的服务能力用完了会发生什么?如果我们使特定的网络链路饱和,会发生什么情况?控制旋钮工作流的目标是为这类问题提供令人满意的(如果不是理想的)答案。我们需要一个可以接受的计划来对付任何出现在我们游戏机上的黑天鹅。

一个小组开始努力确定和建造更多的生产控制和消防通道--我们希望我们不需要这些东西。例如,当有人加入会议会议时,这些旋钮可以让我们快速将默认视频分辨率从高清晰度降级为标准清晰度。这一变化将为我们赢得一些时间,以便使用其他工作流(配置和效率改进)进行纠正,而不会大幅降低产品质量,但如果用户愿意,他们仍然可以将视频质量升级到高清晰度。

拥有各种像这样的仪表化控制装置,如果我们的最坏情况预测不准确,那么就可以为我们赢得一些额外的跑道,同时也可以让我们安心。

这种结构化的回应涉及到大量不同角色的谷歌员工。这意味着要在整个事件中不断取得进展,我们还需要一些认真的协调和有意的沟通。

我们每天在两个时区之间举行交接会议,以容纳苏黎世、斯德哥尔摩、华盛顿州柯克兰和加利福尼亚州桑尼维尔的谷歌员工。我们的沟通线索定期向我们的产品团队、高管、基础设施团队和客户支持运营部门的众多利益相关者提供最新信息,以便每个团队在做出自己的决策时都有最新的状态信息。工作流领导使用Google Docs更新共享的状态文档,以了解当前的风险集合、联系人、正在进行的缓解措施和会议记录。

这种方法工作得很好,足以让事情继续进行,但很快就开始感觉到了负担。我们需要将我们的计划周期从几天延长到几周,以便有意义地减少协调所花费的时间,并增加我们实际用于缓解危机的时间。

我们这里的第一个策略是建立更好、更可靠的预测模型。这种增加的可预测性意味着我们可以稳定整个星期的服务能力增长目标,而不仅仅是明天。

我们还努力减少提高任何额外服务能力所需的劳动量。我们的流程,就像我们运营的系统一样,需要自动化。

在这一点上,扩展Meet的服务堆栈是我们工作最密集的持续操作,这是因为需要更新最新预测和资源数字的人员数量,以及某些操作所涉及的工具数量(有时是不可靠的)。

如上面的生命周期图所示,自动化这些任务的诀窍是渐进式改进。首先我们记录任务,然后我们开始自动化其中的一部分,直到最后,在理想情况下,软件可以在没有人工干预的情况下从头到尾完成任务。

为了实现这一目标,我们委派了来自Meet组织内部和外部的许多自动化专家来专注于解决这一问题。这里的一些工作项目包括:

使我们的更多生产服务响应权威的签入配置文件中的更改

增强常用工具以支持一些更独特的系统要求(例如,更高的带宽和更低的延迟联网要求)。

自动化和编码化这些任务大大减少了在新集群中出现Meet或部署新的二进制版本以释放性能改进所需的手动操作。在此扩展事件结束时,我们能够完全自动化每个区域、每个服务的工作容量占用空间,从而避免了数百次手动构建的命令行工具调用。这解放了不少工程师的时间和精力来解决一些更困难(但同样重要)的问题。

在扩展运营的这一点上,我们可以通过电子邮件在站点之间进行“离线”移交,从而进一步减少要参加的会议数量。现在我们的战略已经稳固,我们的跑道变长了,我们进入了一种更纯粹的战术执行模式。

不久之后,我们结束了我们的突发事件结构,并开始运作剩余的工作,就像我们如何运作任何长期项目一样。

当我们离开我们的事件时,Meet已经有超过1亿的每日会议参与者。顺利实现这一目标并非易事,Meet团队在新冠肺炎之前的灾难和事件响应测试中探索的场景并不包括我们遇到的增加容量需求的长度或规模。因此,我们匆忙制定了很多回应。

在这一过程中,我们遇到了很多问题,因为我们必须以一种不同于标准操作期间通常所做的方式来平衡风险。例如,我们在生产中部署了新的服务器代码,比正常情况下的金丝雀烘焙时间更短,因为它包含了一些性能修复,在我们即将耗尽可用的区域容量之前,这些修复为我们赢得了额外的时间。

在这两个月的努力中,我们磨练的最关键的技能之一是以灵活的方式对风险和收益进行分类、量化和鉴定的能力。每天,我们都会了解有关新冠肺炎停工、新客户开始使用Meet的计划以及可用产能的新信息。有时这些新信息会使我们前一天开始的工作过时。

时间至关重要,所以我们不能以同样的优先级或紧迫性对待每个工作项目,但我们也不能不对我们自己的预测模型进行对冲。等待完美的信息在任何时候都不是一种选择,所以我们能做的最好的事情就是尽可能多地修建跑道,同时利用我们拥有的数据做出经过计算的、快速的决定。

所有这些工作之所以成为可能,是因为十几个团队和尽可能多的职能部门(SRE、开发人员、产品经理、项目经理、网络工程师和客户支持)的精明、协作和多才多艺的人员,他们共同努力实现了这一目标。

我们最终为接下来的事情做了很好的准备:让拥有谷歌账户的每个人都可以免费使用Meet。通常情况下,向消费者开放产品本身就是一个戏剧性的扩展事件,但在我们已经完成了紧张的扩展工作后,我们已经准备好迎接下一个挑战。