作者 | Adrienne Walcer, Kavita Guliani, Mikel Ward, Sunny Hsiao, and VrAI Stacey
译者 | 刘雅梦
策划 | Tina
让我们回到 2016 年,当时 YouTube 提供了大家最喜欢的视频,例如“Carpool Karaoke with Adele”和一直很吸引人的“Pen-PineApple-Apple-Pen”。由于 YouTube 的分布式内存缓存系统的一个 bug,YouTube 经历了长达 15 分钟的全球宕机故障,中断了 YouTube 的视频提供能力。以下是我们从这次故障中学到的三个经验教训。
1. 故障削减措施的风险应与故障的严重程度成比例
有一个表情包,其中一个人发布了一张在他们家里看到蜘蛛的照片,家长说:“是时候搬新家了!”。可笑的是,这一事件(看到一只可怕的蜘蛛)会得到严厉的削减措施(放弃你现在的家,搬到新家中)。我们 SRE 在选择比宕机风险更大的削减措施方面有一些有趣的经验。在上述 YouTube 宕机期间,一个有风险的减载过程并没有解决宕机问题……反而造成了级联故障。
我们得到了惨痛的教训,在故障发生期间,我们应该监控和评估情况的严重性,并选择一条风险适合该严重程度的故障削减路径。在最好的情况下,风险削减措施可以解决宕机问题。在最坏的情况下,风险削减措施会失灵,并且本应修复问题的措施会导致宕机时间的延长。此外,如果一切都坏了,我们可以做出明智的决定来绕过标准程序。
2. 在发生紧急情况之前,应对恢复机制进行全面测试
在高层城市建筑中进行紧急消防疏散是首次使用梯子的可怕时机。同样,在故障中首次尝试风险减载过程也是一个糟糕的时机。为了在高风险和高压力的情况下保持冷静,事先演练恢复机制和故障削减措施很重要,并需要验证:
演练恢复机制有一个有趣的副作用,即可以降低执行其中一些操作的风险。自从这次混乱的宕机以来,我们加倍努力地进行演练。
3. 金丝雀所有变更
有一次,我们想要推送缓存配置变更。我们很肯定那不会导致任何坏事。但相当肯定并不是百分之百确定。事实证明,缓存对于 YouTube 来说是一个非常关键的功能,而配置变更产生了一些意想不到的后果,导致该服务完全瘫痪了 13 分钟。如果我们采用渐进式的发布策略来应对这些全球变更,那么这次故障本可以在产生全球影响之前得到遏制。可以阅读这篇论文中了解有关金丝雀策略的更多信息,也可以通过本视频以了解更多信息。
大约在同一时间段,比 YouTube 稍微年轻的兄弟公司谷歌日历(google Calendar)也经历了宕机故障,这也是接下来两个经验教训的背景。
4. 有一个“大红色按钮”
“大红色按钮”(Big Red Button)是一种独特但高度实用的安全功能:它应该启动一个简单、易于触发的动作,该动作将触发不良状态恢复到(理想情况下)关闭正在发生的任何情况。“大红色按钮”有多种形状和大小,在提交一个有潜在风险的操作之前,识别这些大红色按钮可能是什么非常重要的。我们曾经差点就能避免一次重大的宕机故障,因为提交可能触发变更的工程师在更改传播之前拔掉了台式电脑的电源插头。因此,在计划重大部署时,请考虑大红色按钮是什么?确保每个服务依赖项都有一个“大红色按钮”,以便在紧急情况下使用。请参阅“通用削减措施”以了解更多信息!
5. 仅仅进行单元测试是不够的,还需要进行集成测试
啊……单元测试。它们验证单个组件是否可以按照我们需要的方式执行。单元测试的范围是有意限制的,而且非常有用,但它们也不能完全复制可能存在的运行时环境和生产需求。因此,我们大力提倡集成测试!我们可以使用集成测试来验证作业和任务是否可以执行冷启动。事情会按照我们希望的方式进行吗?组件也会按照我们想要的方式协同工作吗?这些组件会成功创建我们想要的系统吗?这一教训是在谷歌日历(Calendar)的故障处理中学到的,在这次故障中,我们的测试没有遵循与实际使用相同的路径,导致了大量的测试...... 但这并不能帮助我们评估变更在现实中的执行情况。
转到 2017 年 2 月发生的一个故障,我们学到了接下来的两个经验教训。
首先,不可用的 OAuth 令牌导致数百万用户退出设备和服务,并导致 32000 个 OnHub 和 Google wifi 设备执行出厂重置。由于登录失败,手动帐户恢复索赔增加了 10 倍。谷歌花了大约 12 个小时才从这次故障中完全恢复过来。
6. 沟通渠道!还有备份通道!!以及这些备份通道的备份!!!
是的,那是一段糟糕的时光。你想知道是什么让情况变得更糟的吗?团队希望能够使用 Google Hangouts 和 Google Meet 来管理事件。但当 3.5 亿用户退出他们的设备和服务时……回想起来,依赖这些谷歌服务是一个糟糕的决定。确保你拥有独立的备份通信通道,并且已对其进行了测试。
然后,2017 年的同一故障让我们更好地理解了优雅降级:
7. 故意降级性能模式
人们很容易将可用性视为“完全启动”或“完全关闭”……但是能够通过降级性能模式提供连续的最小功能有助于提供更一致的用户体验。因此,我们谨慎而有意地构建了性能降级模式——因此,在粗略的补丁程序中,它甚至可能不会被用户看到(它可能现在正在发生!)。服务应该适度降级,并在特殊情况下继续运行。
下一个经验教训建议我们确保最后一道防线系统在极端情况下能如预期的那样工作,例如自然灾害或网络攻击,这些情况会导致生产力或服务可用性的损失。
8. 故障弹性测试
除了单元测试和集成测试之外,还有一些非常重要的其他类型的测试:故障弹性和恢复测试。弹性测试验证我们的服务或系统在发生故障、延迟或中断时是否正常运行,而恢复测试则验证服务在完全关闭后是否能够恢复到稳态。两者都应该是业务连续性战略的关键部分——如“抵御意外”中所描述的那样。一个有用的活动还可以是让你的团队坐下来,研究其中一些场景在理论上是如何发挥作用的——桌面游戏风格。这也是一个探索那些可怕的“假设”的有趣机会,例如,“如果部分网络连接意外关闭怎么办?”。
9. 自动化故障削减措施
2023 年 3 月,几个数据中心的多个网络设备几乎同时发生故障,导致大范围的数据包丢失。在这 6 天的宕机故障中,估计 70% 的服务受到了不同程度的影响,具体取决于网络故障时的位置、服务负载和配置。
在这种情况下,我们可以通过手动自动化故障削减措施来减少平均解决时间(MTTR)。如果有一个明确的信号表明某个特定的故障正在发生,那么为什么不能以自动化的方式启动故障削减措施呢?有时,最好先使用自动故障削减措施,并在避免了用户影响之后再解决根本原因。
10. 缩短部署之间的时间间隔,以降低部署出错的可能性
2022 年 3 月,支付系统大范围故障,客户无法完成交易,导致 Pokémon GO 社区日被推迟了。原因是删除了一个数据库字段,这应该是安全的,因为该字段的所有使用都事先从代码中删除的。不幸的是,系统某一部分的缓慢部署节奏意味着该字段仍在被线上系统所使用。
部署之间有很长的间隔,尤其是在复杂的多组件系统中,会使得我们很难推断出特定变更的安全性。间隔很近部署(并进行适当的测试)可以减少此类故障的意外发生。
11. 单一全球硬件版本会是单点故障
只使用一种特定型号的设备来执行关键功能可以简化操作并能使运维更简单。然而,这也意味着,如果该模型出现问题,则该关键功能将不再执行。
这一故障发生在 2020 年 3 月,当时一台网络设备遇到了一个未被发现的零日漏洞,该漏洞触发了流量模式的变更。由于整个网络都在使用相同型号和版本的设备,因此出现了严重的区域性故障。防止这种情况全面故障的原因是存在多个网络主干网,这些主干网允许高优先级流量通过仍在工作的替代路由。
关键基础设施中的潜在漏洞可能潜伏在未被发现的地方,直到一个看似无害的事件触发了它们。维护多样化的基础设施虽然本身会产生成本,但可能意味着麻烦的区域故障和全面故障之间的差异。
所以你学到了嘛!从谷歌 20 年的站点可靠性工程中汲取的 11 个经验教训。为什么是 11 个呢?好吧,你看,谷歌站点可靠性有着丰富的历史并仍然处于鼎盛时期。
原文链接:
https://sre.google/resources/practices-and-processes/twenty-years-of-sre-lessons-learned/