事件的事后调查

2022-10-05 17:41:52 浏览数 (2)

事件的事后调查

目录

  • 事件的事后调查
    • 简介
      • 什么是事件
      • 不是所有事情都是事件
        • 监控
        • 告警
        • 可操作告警的重要性
      • 事件管理生命周期
    • 事件响应的准备练习(准备)
      • 灾难演习和事件响应练习
        • 定期测试
        • 微妙的测试和自动化
        • 准备响应者
        • 编写事件响应测试
    • 扩展时间管理(响应)
      • 组件响应者
      • 系统体系(SoS)响应者
      • 事件响应组织结构
        • 共同的协议
        • 信任
        • 尊重
        • 透明
      • 管理风险
      • 事件管理和风险管理的功能
    • 缓解和恢复
      • 紧急缓解措施
      • 降低事件影响
        • 计算事件的影响
        • 降低探测时间
        • 降低修复时间
        • 建立组织事件响应流程
        • 建立清晰的on-call策略和流程
        • 编写用的运行手册/playbooks
        • 降低响应疲劳
        • 研究数据采集和可观测性
      • 增加故障之间的时间
        • 避免反模式
        • 分散风险
        • 采用开发实践
        • 考虑可靠性设计
        • 优雅降级
        • 纵深防御
        • N 2资源
        • 从故障中获得的经验
    • 事后调查及其他
      • 心理安全感
        • 构建心理安全氛围的一些点子
        • 处理事件时的心理安全
        • 不推卸责任
        • 从错误中吸取经验
        • 实施事件管理实践时的心理安全
      • 编写事后调查
      • 系统分析和组织提升
      • 根因VS触发因素
        • 隔离系统VS整个堆栈
        • 时间点VS轨迹
    • Mayan Apocalypse:一个真实世界的例子

译自:Anatomy of an Incident。看完整篇文章,最多的感触是一个好的SRE(或者其他角色)需要一个好的企业文化,很多时候压力并不能成为解决问题的动力,反而会成为问题解决的绊脚石,甚至成为员工换工作的动力。

简介

毫无疑问,接下来将是个人和职业上充满压力的N周,有时我们会争先恐后地赶在事态发展之前。十多年来,我们一直在为危机做准备,我们已经做好了准备。在全世界人民比以往任何时候都更需要信息、通信和计算的时候,我们将确保谷歌能够帮助他们。--—Benjamin Treynor Sloss, Vice President, Engineering, Google’s Site Reliability Engineering Team, March 3, 2020

失败是不可避免的。作为科学家和工程师,你会着眼于长期问题,并将系统设计为最具可持续性、可扩展性、可靠性和安全性。但你设计的系统只是基于现有的知识。在实现方案时,并不会知道未来会发生什么。你不能总是参与下一个zero-day事件、病毒式媒体、气候灾难、配置管理错误或技术转换等。因此你需要准备好迎合应对这些事情,以及这些事情对系统造成的影响。

近十年来,谷歌最大的技术挑战之一就是由COVID-19引发的。该病毒引发了一系列的紧急事件,我们需要通过处理这些事件来继续服务客户。为此,我们不得不大力提高服务能力,提高在家办公的生产力,并通过新的方式来快速恢复服务(尽管受供应链的约束)。正如Ben Treynor Sloss所述,在这种颠覆式的事件之下,谷歌能够继续服务全球的原因是我们已经为此做好了准备。十多年前,谷歌已经前瞻性地调研了事件管理。这种准备提高了祖师对事件的弹性。准备可以增强应变能力。弹性和处理故障的能力成为从长期(如十年)角度衡量技术成功与否的关键因素。除了成为最好的工程师,你还需要做好处理故障的准备。

弹性是公司运营的主要支柱之一。在这方面事件管理是一个强制性的公司流程。事件很高昂,不仅仅是对客户的影响,也给运维工作者带来了沉重的负担。事件会产生压力,通常需要人工介入。有效的事件管理会将预防性和主动性工作优先于反应性工作。

事件管理伴随着压力,而且很难找到和培训响应者。有些意外是不可避免的,故障总会发生。预期问"如果发生事件,你该如何处理?"我们更倾向于问"发生事件时你是如何处理的?",这种方式减少了歧义,不仅可以减少人力和响应者的压力,还可以缩短解决时间,减少对用户的影响。

该报告作为技术事件响应事件指导。一开始,我们会使用通用的语言来讨论事件,然后讨论如何激励工程师、工程师领导以及管理人员如何考虑组织内的事件管理。我们的目的是涵盖从事件准备、事件响应以及事件恢复到保持组织健康(使其保持战斗力)的方方面面。

什么是事件

事件是一个加载项。其具体含义取决于使用它的组织。例如在ITIL,一个事件就是一个非计划内的中断,如问题单、bug、或告警。无论如何使用该名词,最重要的是要根据具体的定义进行调整,以降低筒仓,确保每个人都能够理解到相同的含义。

在谷歌,事件为:

  • 可升级的(表示无法独立处理)
  • 需要立即响应
  • 需要有组织地响应

有时事件可能是由于中断引起的,导致一段时间内服务不可用。中断可以是计划内的,如为了系统升级,在一段服务维护窗口内,该系统不可用。如果中断是计划内的,且通知了用户,那么它就不是一个事件--即不需要立即且有组织地作出响应。但更多是由于非期望的故障导致的非预期的中断。大部分非预期的中断都是或都会成为事件。

事件会困扰客户,可能会导致收益损失、数据损坏、违反安全规定等等,这些事情会给你的客户带来影响。当用户感受到事件的影响后,可能会影响到客户对你(提供商)的信任。因此需要避免产生"过多"的事件或"过于严重"的事件,来让客户满意,否则他们就会离开。

过多的事件也会影响到事件响应者(处理事件也是有压力的)。仅仅为了应对事件而去寻找具备多项合适技能的SRES,这种方式既困难且成本也很高。相反,你应该给他们提供机会,通过主动缓解事件来提升他们的技能。后续我们将讨论这一点,通过某些方式来降低压力并提升on-call轮换的健康度。

不是所有事情都是事件

区分事件和中断很重要。此外还需要区分指标、告警和事件。你如何对指标和告警以及告警和事件进行分类?并不是每个指标都会成为告警,且并不是每个告警都会成为事件。为了帮助你了解这些术语的含义,我们会讨论维护系统健康的监控和告警的角色。

监控

持续观察系统监控的最常见的方式是通过监控,Google SRE Book中将监控定义为:采集、处理、聚合和展示系统的实时量化数据,如请求量和类型、错误量和类型、处理事件以及服务生命周期等。监测是一种测量。

在测量方面,我们建议采用一种以客户为中心的方式来设定SLOs(,见下文"降低事件的影响")以及客户体验。这意味着采集的指标是那些能够反映用户体验的指标和各种度量值,如black box、基础设施、客户端以及应用指标等。由于不同的度量方法具有不同的优势,因此可以采样不同的方式来度量相同的值,以此保证冗余和准确性。以客户为中心的仪表盘也可以作为客户体验的指标,且对于故障排除和调试事件来说至关重要。

还需要注意的是,应该去关注如何衡量可靠性以及对用户的影响,而不是已经宣布的事件数。如果关注了后者,人们可能会因为畏惧惩罚而不愿宣布事件。这可能会导致延迟事件宣布,不仅仅会造成时间和数据采集上的浪费,还会影响事件管理协议的可追溯性。因此,最好的方式是宣布并关闭某个事件,而不是进行事件追溯。

在这一点上,人们经常会混用"可靠性"和"可用性",但可靠性的要求要远大于可用性,特别是在复杂的分布式系统中。可靠性是指大规模提供一致服务水平的能力,包括不同的方面,如可用性、延迟和准确性等。不同的服务中可能代表不同的含义。如YouTube和Google Search中的可靠性是否一样?可靠性的具体含义取决于服务和用户对服务的期望。

一般来说,具有更少、更短和更小中断的系统的可靠性更高。因此,归根结底,就是用户愿意忍受的停机时间。由于采用了以客户为中心的方式,因此用户就定义了你的可靠性,所以需要尽可能仔细地衡量用户体验(后续在"降低事件的影响"中细谈)。

告警

我们已经讨论了使用监控来观测系统健康。现在讨论监控的关键组件:告警。当监控到非预期的行为时,它会发送一个信号来表示发生了某个不正确的事情,该信号就是告警。一个告警意味着两件事情之一:有东西坏了,需要有人修理;或有东西快坏了,需要有人看看。紧迫感--意味着当需要采取某个动作时,需要直接选择如何应对。如果需要立即(人工)操作,则应该发送一个页面。如果在接下来的几个小时内需要人工操作,则应该发送一个告警。如果不需要任何动作,即需要通过拉取模式获取需要的信息,例如用于分析或故障排除,则以度量或日志的形式保留信息即可。

注意,根据不同的组织偏好可能会有不同的告警模式,例如,可以通过仪表盘或问题单的形式呈现。在谷歌,通常选择后者,监控系统会在 Google Issue Tracker中打开不同优先级的"bug"。

现在我们已经了解了基本概念,下面深入讨论一下可操作的告警(actionable alerts)。

可操作告警的重要性

正如前面提到的,当发生特定条件时会触发一个告警,并仅针对那些关心且可操作的内容进行告警。考虑如下场景:作为活跃的on-caller,你在凌晨2点被呼叫起来处理某个告警,原因是过去5分钟内的QPS增加了300%。有可能这是一个突发服务,即一段时间内流量稳定,但随后一个大客户来了,并在很长一段时间内发出数千条查询。

此时半夜爬起来的价值在哪里?没有价值。该告警并不可操作。由于此时并不会导致服务故障,因此并不需要将任何人从床上拉起来。查看服务的历史数据可以看到,服务能够处理这种峰值流量,但这种流量并不会产生问题,因此也不需要生成任何告警。

现在看一个更微妙(且更常见)的可操作告警的版本。你的公司每晚需要对生成数据库进行备份,因此你配置了一个cronJob,每4个小时进行一次备份。有可能会因为支持备份的副本出现事务错误(出现硬件故障)而导致运行失败,负载平衡器会自动将该副本移出服务模式,并完成后续的备份。

没有必要由于某个备份的错误而创建问题单,这样会导致噪音(系统会在无人为介入的情况下自动恢复)。

这类情况经常发生,且仅仅通过"在我处理时一切正常"就简单地关闭问题单,这种方式本身是有问题的,原因如下:

  • 辛苦 需要有人花时间查看问题单,查看图标,并确定是否需要处理该问题。
  • 警惕性疲劳 如果95%的"数据库备份失败"都被简单地关闭,那么有很大概率会忽视真正的问题。

正如前面讨论的,事件是一个具有特殊特征的问题。一个告警用于指示某个正在发生的事件。你可能接收到很多告警,但没有产生任何事件。这种情况下并不意味着你需要执行正常的事件管理技术,这可能只是一个计划中的维护事件(event),且在维护过程中本来就会接收到这些告警。

有时候会产生事件,但没有产生告警。例如可能是安全团队向你通报,他们怀疑你的生产系统遭到破坏。这种情况下,你的团队不会接收到触发的告警。

更实际地说,人类对告警和事件的感知存在差异:

  • 与简单地修复警报相比,正式的事件管理的压力要大得多。
  • 相比经验丰富的响应者,经验少的响应者更不愿意调用事件
  • 事件更可能需要额外的团队资源,因此没有响应者可以更容易地判断他们是否需要尽早关注活动的问题。

这不仅适用于你的团队。事实上,它适用于整个组织。

通常你接收到的告警要远多于事件。获取告警的基本指标很有用(如每15分钟接收到多少告警),但事件值得一探究竟(如过去15分你接收到了5个主要事件,所有事件都是因为推出了一个生产前未经过充分测试的特性造成的)。你不想用收到的所有警报污染这些报告。考虑一下相关的观众--指标主要用于团队,而事件报告则可能会给提供给上级且需要确定合理的范围。

希望这些能让你更自信地说,"这不是一个事件"。但这句话可能会被一分为二:如果某些事不是事件,这意味着某些事情是事件。你应该如何处理这些事件?请看下节介绍。

事件管理生命周期

理想的事件管理并不仅仅意味着快速管理事件。好的时间管理需要关注事件的整个生命周期。在本章中,我们会讨论一种程序化的方法来管理事件。将事件认为是系统中存在的持续风险。处理这类风险的过程称为事件管理生命周期。事件管理生命周期包括准备、响应、恢复和缓解事件的所有必要活动。这是服务运维的持续成本。

生命周期是指事件存在的每个阶段,图1-1展示了这些阶段:

  • 准备 围绕一个公司或团队为一个事件的发生所作的准备动作。可能包括工程安全措施(代码监视或回滚过程),事件管理培训和为识别错误而进行的实验或测试,也包括配置的监控和告警。
  • 响应 当触发的告警变成问题时,就会发生这种情况。涉及响应告警、决定该问题是否是一个事件、以及联系该事件影响到的人。
  • 缓解和恢复 这是系统将其恢复到正常状态需要采取的一系列动作。包括紧急缓解措施,避免影响或影响扩大化。恢复包括问题事后调查涉及的系统分析和反思。一次分析对应一个事件报告,包含采取的动作、影响、根因和后续防止重新发生以及/或降低影响的措施。

一旦完成恢复阶段,你又回到了准备阶段。根据技术栈的大小,所有这些阶段都可能同时发生,但可以肯定的是,至少有一个阶段总是会发生。

事件响应的准备练习(准备)

上面我们讨论了事件管理的阶段以及事件管理生命周期。下面了解如何进行事件管理演练,以便为真实事件做好准备。

灾难演习和事件响应练习

可以通过测试和事件响应练习准备来提升弹性。推荐在团队中进行灾难角色扮演来训练事件响应。在谷歌我们将此称之为 Wheel of Misfortune,通过重建过去在生产环境中遇到的事件来进行演练。

定期进行事件响应练习有着明显的好处。在早期的谷歌灾难恢复能力测试(DiRT)项目中,有些测试被认为因风险太大而无法执行。这些年来,通过重点关注那些因风险太大而无法运行测试的领域,使得很多风险都得到了彻底的解决,以至于现在的测试被认为是自动且是无趣的。

做到这一点并不容易,它需要很多团队花费很多精力才能达成,但我们已经实现了通过"只需定期自动化运行测试"的方式大大降低了全局系统中存在的风险。

定期测试

定期进行测试可以带来明显的好处。多年来,谷歌通过运行DiRT测试来找出并修复生产系统中存在的问题。由于团队一直在测试他们的服务,因此高风险测试的数目会有所减少。这是个好的迹象,即由于系统更具有弹性,因此更难发现系统的缺陷。

测试可能会由于某些原因而失败,但这种情况也变得越来越少。即使发生了,这些系统也会按照预期的方式失败,并很快得到修复。这样响应者也可以更放心地激活应急程序,并在压力下保持镇定。通过测试结果,可以减少事后调查的过程。经过多年的付出,思维方式已经从"灾难测试是我该做的事"演变为"灾难测试是我们一起做的事"。

微妙的测试和自动化

测试正在慢慢从解决纯粹的技术问题(如"我们如何恢复完全崩溃的数据库")转变为一系列更加微妙的"让我们修复流程"的挑战。

技术测试更容易讨论和自动化:归根结底就是编写一些代码来实现一系列命令并检查结果是否符合预期。与之相比,找出流程问题则更加困难,例如可能出现"只有一个人可以授权这件事,但他没有回复电话/邮件"的情况,尤其是那些不经常执行的流程。

准备响应者

执行事件响应测试(即便只是理论上的),也可以帮助识别这些流程,给这些流程分配概率和风险因子,并给响应者注入信心。即使是非计划内的特定测试,也可以了解到你的事件响应流程中的缺陷。响应者最好也做好任何时候处理真实事件的(技术、心理和情绪上的)准备。

不能忽视情绪上的准备。正如前面提到的,事件管理可能会给开发者带来极大的压力。压力可能会导致不良响应,如失察、响应慢和判断模糊。还会引起焦虑、疲惫、高血压和睡眠不良等健康问题。

通过事件响应测试不仅仅可以为个人降低不良影响,更重要的是,可以通过识别这些影响,并作出正确的动作,如请求外部帮助,休息一下,甚至完全交接一件事件。管理者和其他领导岗位上的人应该持续关注响应者的压力/疲劳/倦怠上的迹象,并尽可能给予帮助。

编写事件响应测试

编写一个好的事件响应测试的开端是查看最近的事件。在谷歌,我们在事后调查时会问到以下标准问题:

  • 哪里出了问题?
  • 什么是正确的?
  • 哪里做的比较好?

从观察哪里出了问题开始,因为这是比较清晰的且需要提升的地方,通常是需要修复的具体问题,如你的监控发现了一个问题,但没有通知任何人。在确定并修复该问题之后需要对此次修复进行验证。有一点无需过分强调:仅仅修复一个问题是不够的,有可能问题并没有被完全修复,且修复该问题会导致其他地方出现问题。在通过一些小的、相对简单的测试验证了正确性之后,随着对流程信心的增加,你可以开始关注那些更复杂的问题,包括那些不完全在技术范畴内的过程(如人力处理过程)。

在小范围内的验证执行一段时间之后,开始考虑"哪里做的比较好"。通常这些问题都比较微妙,且解决它们并不那么容易。可以将这些问题分为更小、更易解决的项。

这些测试应该保持缓慢但稳定的节奏--你不会想让团队都投身到这些测试当中,当然也不想放弃这些测试。比较简单的方式是每4个星期执行一小时的测试,而不是花费10%的运维精力去执行这些测试。随着流程的完善以及测试价值变得更清晰,你会找到一个合理的模式来决定多久执行一次测试,以及执行的力度。

扩展时间管理(响应)

我们已经通过事件响应练习、角色扮演和常规测试讨论了如何练习事件响应准备。这些策略可以帮助你在遇到真实事件时做好准备,并对事件进行管理(参见"建立一个事件响应流程")。但如何在组织增长的同时管理事件?本章我们将讨论如何扩展事件管理。

在谷歌,我们为所有系统提供了最优的事件管理范围。谷歌的规模很大,为了支持每年2万亿的请求,我们使用了很多数据中心,至少1百万台计算机,以及8万多员工。所有这些活动都会经过一个庞大且高度互联的系统体系(SoS),严重依赖该技术栈进行生产活动。对该技术栈的支持意味着需要有合适且可靠的人员,以便在问题出现时能够及时定位和修复。这些人员来自我们的SRE组织,他们为特定范围的系统提供了事件管理,并在发生事件时进行响应。

组件响应者

在SRE组织中,有一类响应者,称为组件响应者,用于on-call谷歌整体基础设施中的某一个组件或系统。

组件响应者是精通问题空间的单系统专家,是专业的问题解决者,擅长在出现危机时实施缓解策略。他们会持续访问工具/系统来执行应急响应、妥善处理压力并在危机期间保持清醒的认知。

单个件响应者的职责范围比较有限,这使他们能够深入了解自己所在的领域以及可能影响该领域的系统。这些响应者是防止故障从一个组件串联到整个栈的第一道防线。单个组件要远小于整个SoS栈,通常有清晰的系统边界。因此可以设置合适的监控和告警,这样组件响应者可以持续了解到系统的故障类型。

当技术栈发展到一个人无法理解和维护的状态时,我们会切割技术栈,这样就可以引入多个响应者,每个响应者负责整体栈的某个组件。随着时间的推移,这些组件也会变得越来越复杂,然后再作进一步切分。通过维护一个有限的范围,主响应者可以在给定时间内解决更小范围内的问题。但这种响应方式存在不了解跨多组件、多系统的风险,或由于问题超出了他们的专长,因此特定组件响应者无法提供足够的支持。

例如出现了一个串联多个技术栈组件的底层问题,且这种串联速度要快于人员自组织的速度。在事件影响扩大的过程中,我们可以快速达这样一种状态:每个组件团队都接受到通知,并分派响应者来维护其组件状态。这些组件团队是并行工作的,但有可能这些响应者并不知道其他响应者的存在。可能某个响应者的事件是问题根因,其他只是该问题的后果,但如何确定是哪一个?

由于技术栈足够大且复杂,单个响应者极有可能无法缓解并维护其所有依赖关系及其依赖项的状态。为了缓解这种风险,我们在组件响应者之外构建了一个二级响应者结构。在谷歌,我们将这些二级响应者称为SoS响应者,见下一节。

系统体系(SoS)响应者

系统体系(SoS)响应者是出现跨组件系统的事件、跨系统边界的事件或事态变糟糕时的事件响应者。SoS响应者经过适当的培训,级别比较高,并有权领导有组织、有配合的响应。这些响应者是第二道防线,关注点也更加全面,可以在响应分布式计算故障时体现其关键优势。

我们将SoS响应者认为是多系统事件管理者和多面手,其关注范围也更全面。他们擅长在更广的视角下处理一系列事件。通常这些事件会涉及多个团队,例如某个主要的SoS故障会导致很多服务下线,这些事件会导致会已经导致了下游故障,并有可能扩散到服务边界之外,此外,还可能是持续30分钟或更久都没有解决的影响到客户体验的事件。

SoS响应者可以很好地处理这类影响广泛的事件,因为他们知道如何组织其他人并在复杂情况下下达命令。他们还知道如何诊断系统行为并确定问题根因,专注于扩大响应范围,并就事件进行广泛的沟通。

在谷歌,我们有两种类型的SoS响应者,每种类型都有不同的功能,通常是互通的:

  • 注重产品的事件响应团队(IRTs): 用于保证特定领域的产品稳定性的事件响应团队。例如,Ads IRT 和 YouTube IRT。不是每个产品领域都有事件响应团队,但如果产品不断迭代更新,且越来复杂,并且产品之间有相似的技术债,则有必要引入IRTs。这些团队不会知道每个产品栈的技术细节,但他们了解产品的整体运作和依赖情况。
  • 技术事件响应团队: 这是关注面最广的事件响应团队。该团队主要关注那些跨多个产品,职责不明确,或有不清楚和普遍问题根因的事件。Tech IRT的成员是谷歌的终身员工,他们至少在两个不同的团队中担任过组件响应者。他们知道系统是如何运作的,更重要的是他们拥有出色的事件管理能力。

Tech IRT的成员会持续负责他们自己的组件,但也会提供全球范围内24*7的轮岗支持。由于练就了这种特殊技能,使得他们可以在出现重大紧急的情况下保持正常工作。

Tech IRT的成员每年会进行两次两周的产品培训,涵盖了产品的运作(故障)细节。每季度还需要展示如何使用应急工具来保证高效工作的能力。

下图描述了谷歌的事件响应组织架构。该架构的每一层都对应一个产品(日常功能的复杂细节)的抽象层。这里面的每个角色都同等重要--该金字塔的每个后续级别角色接收到的事件通知也会随之减少。如果一个组件响应者无法解决该问题,且会影响到产品的稳定性,则可以升级到其他角色:关注产品的IRT。

如果一个问题威胁到了多个产品,或可以通过共享基础设施来快速缓解该问题,此时将激活Tech IRT,并在最广的范围内处理该问题。Tech IRT作为其他所有层级的升级点。 那么如何让这种组织架构无缝运作?答案是共同的协议、信任、尊重和透明度。接下来了解一下这些内容。

事件响应组织结构

成功的事件响应组织有四个特点:共同的协议、信任、尊重和透明。

共同的协议

在谷歌,我们内部广泛使用了一个联邦应急管理局事件指挥系统(ICS)的变体,它定义了事件响应者的角色,如事件指令、记录和通信。通过一个共享且清晰的流程,我们形成了一个正向的应急响应习惯,包括维护活动状态,清晰的指令链以及降低整体的压力。每个人都需要了解交接过程,包括谁交接给谁,保证高效的知识传承。一个棋手不能把主教丢在麻将桌上并保证每个人都知道如何使用它--在紧急情况下,重要的是让所有玩家都参与进同一个游戏。

信任

在一个事件过程中,事件施令者需要掌握一定的权力。他们需要引导他人,组织混乱的力量,并对适当的行动方案做出判断。对于大部分组织,让权力与运营职责相一致是一件具有挑战性的事情,但我们标准的操作流程避免了这种只有上级业务领导才能够授权改变服务的情况:我们将此权限授予具有相关背景的问题专家。

尊重

当响应者觉得有必要升级时,他应该放心地去执行升级流程。如果响应者在不断升级的事件中受到审查、批评或不称职的感觉,那么他可能会在需要升级的时候不去升级。除了一般的礼貌,我们必须相信,考虑到摆在他们面前的信息,他们能够做出最好的决定。如果事情出现错误,关键的问题不是让某人感到难过,更重要的是如何创建更精确更可执行的信息来避免未来出现类似的事情。谷歌SRE成功的部分原因是在事后调查过程中,谷歌坚持严格的无过错政策(稍后将对此进行详细介绍)。

透明

我们没有筒仓心态。当一个事件发生时,任何人都可以看到其细节。如果我们不让其他人访问事件信息,就无法进行升级和协作(在事件解决之后,我们会在自己的每周简讯中对事件进行事后调查)。我们鼓励通过阅读其他团队或产品领域产生的事件来交互学习。

管理风险

除了事件响应组织结构的特征,还需要考虑如何管理风险。确定并解决事件的时间不应该超过3天。正如前面提到的,事件管理在时间和人员上都比较昂贵。如果你长时间处理活动时间的管理中,就会导致疲惫和倦怠,还有可能会考虑换工作。需要升级的事件需要进行及时且有组织的响应。这种及时并不是一种自然状态--人们不应该让延髓受到那么长时间的刺激,也不应该让皮质醇在体内持续那么长时间。如果史前人类一直在打猎或被剑齿虎猎杀,却从未感到安全或有时间休息,那么我们的进化就会大不相同。如果你希望在战斗或逃跑模式下花费大量时间,那么很自然地,这种情况最终会导致你的团队不断流失。

事件管理和风险管理的功能

为了最小化花费在事件管理模式中的时间,需要识别事件管理和风险的功能。事件管理是一个短期经历,目的是为了快速修正一个存在的风险。一个事件的级别可以分为几种简单的类型。在谷歌,我们针对我们组织的产品对这些进行了适当的量化(见下表)。

风险

定义

litmus test

Huge

重要的面向用户的故障,可能会给谷歌的收益或谷歌的客户带来不良新闻或重大影响。当出现一个内部产品故障时,只有当它导致可见的外部后果时才会被认为是Huge的,如负面新闻。

它是否损害了Alphabet/Google b的品牌或业务。

Major

对用户可见,但最终没有损害到谷歌的服务或客户,或没有对谷歌或其客户造成重大损失,或没有影响到50%或更多的谷歌内部人员。

如果未来反复发生可能会损害Alphabet/Google的品牌和业务

Medium

差点导致huge/major故障的事件。影响到内部大量用户。但存在解决办法,且用户知道如何降低影响度。

这种反复发生的、未缓解的事件可能随着时间的推移导致不稳定性增加,并增加生产维护成本。

Minor

内部用户可能不会注意到该故障。可能会给内部用户造成不便。结果会导致实体(网络、数据中心、实例)之间的流量波动

这种反复发生的、未缓解的事件不太可能会随着时间的推移导致不稳定性增加,但代表正常运行条件。

Negligible, Trivial

这种事件对用户不可见,且对产品的影响度很小。但可以吸取宝贵的经验教训,后续动作需要以低优先级进行跟踪。

这种反复发生的、未缓解的事件不应该认为是进程崩溃

Test, Ignored

可能并不是一个事件

不产生告警

事件的规模大致对应评估的"风险"(根因/触发/影响)。事件管理可以短期缓解其造成的影响,并为组织中的当权者争取一定时间来决定下一步应该做什么。由于事件被定义为"X是一个问题",且"应该由某人去处理",事件响应倾向于通过缓解短期影响来做出长期决定。 但这并不意味着在消除短期和长期影响之前应该继续进行事故管理。根据技术栈的规模或技术债的量,可能会花费数月甚至数年来完全矫正产生问题的根因。只有在事件处于"开启"状态时才会激活事件管理,直持续到短期影响被缓解。在医院中,类似的方法是评估出血患者当下存在的风险,然后及时止血。

那么下一步是什么?在医院中,下一步是找出什么原因导致了出血,以及如何防止再次出血,这可能涉及帮助病人构建一个长期计划来避免再次收到伤害,或仅仅涉及治疗导致伤口的皮肤病。无论哪种方式,一旦避免了当下的危险,就需要做长期计划,包括短期的全天候支持,如果需要,还需要落实到位,确保病人安全,并防止再次出血。类似地,在你的技术栈中,一旦避免了当前的风险,则需要转向长期动作。

在事件管理中,你可以经常为事件创建以分钟计数的时间线。如果你正在处理一个活动且紧急的问题时,每分钟都会反映到受影响的用户或遭受的经济损失。由于每分钟都很关键,因此事件管理会给事件管理者带来很多压力,因此,正如本章开头讲的,它并不是一个长期的正向体验。当你在处理事件的长期后遗症时(解决问题根因或诱发原因),理想况下,不会立即对用户造成伤害或造成重大经济损失。这就给你留下了一些高优先级的工作,这些工作仍需立即执行,但不需要使用与事件管理相同的方式执行。此时的时间线最好以天或周为单位,且不需要在推荐的事件时间内完成(3天)。不要让自己保持在"战斗或逃跑"模式中,关闭你的事件,然后继续恢复这些事件。

缓解和恢复

我们已经讨论了如何扩展事件管理,以及如何使用组件响应者和SoS响应者来帮助在公司规模扩展时管理事件。此外还涵盖了一个成功的事件管理组织的特性,并讨论了管理防线以及如何避免on-call疲惫。这里,我们将讨论如何在事件发生后进行恢复。首先关注紧急缓解措施。

紧急缓解措施

前面我们已经鼓励如何在一个服务事件中"止血",我们建立了恢复措施,包括紧急缓解措施来避免影响或避免影响升级。下面让我们来谈谈这意味着什么以及紧急情况下的一些提前缓解措施。想象一下你的服务很糟糕,故障已经产生,并探测到该故障正在影响用户,而你正是事件的负责人。此时第一优先的总是降低或减少用户影响,而不是弄清楚什么导致了问题。假设你在一个屋子里,而屋顶开始漏水。你做的第一件事可能就是在滴水出放一个桶,防止水患。(我们后面会看到,如果屋顶问题是根因,雨就是触发因素)。在屋顶修复以及天气变晴朗之前,桶可以降低漏水带来的影响。为了在服务故障下停止或降低对用户的影响,你需要准备一些桶。我们将这些比喻的桶称为通用缓解策略。

一个通用缓解策略是一个在你弄清楚需要修复什么之前,为降低故障影响级别所采取的动作。

适用于服务的缓解策略各不相同,具体取决于对用户的影响途径。一些基本的策略如回滚二进制文件、清除或重定向流量或增加容量。这些"创可贴"的目的旨在为你和你的服务时间买单,以便能够找到一个有意义的修复方案,从而完全解决潜在问题。换句话说,你修复了故障的症状,而非产生症状的原因。在使用通用缓解策略之前,你不需要完全理解故障本身。

可以考虑做一些研究并调研部署一些快速修复按钮(比喻的桶)。记住,桶这是个简单的工具,可能会被误用。因此,为了正确使用通用缓解策略,需要在定期的弹性测试中练习使用这些策略。

降低事件影响

除了一般的缓解策略(即第一优先缓解一个紧急情况或事件),从长远来看,还需要考虑如何降低事故的影响。事件是一个内部术语。事实上,你的客户并不关心事件或事件的数目,他们真正关心的是可靠性。为了满足用户的期望并达到期望的稳定性级别,你需要设计并运行可靠的系统。为了达成这个目标,你需要将你的动作对齐到前面提到的事件管理生命周期:准备、响应和恢复。考虑在事件前、中、后应该做哪些事来提高系统的稳定性。

虽然很难衡量用户的信任度,但有一些策略可以用来衡量你提供的用户体验的可靠程度。我们SLI来衡量用户体验。SLI会告诉你任何时间下的服务质量。那么如何衡量服务的表现好坏呢?

在一些场景下,用户可以是一个终端用户、一个人或系统(如API),或其他内部服务(如服务其他内部服务的核心服务)。在这种情况下,你需要像你的关键依赖项(即硬依赖或无法执行缓解策略的依赖--如果它出现故障,你也会出现故障)一样可靠。这意味着,如果面向客户的服务依赖内部服务,那么这些内部服务需要提供一个更高的可靠性来为客户提供其需要的可靠性等级。

SLI的可靠性目标称为SLO。一个SLO会随时间聚合目标:在特定时间段内,这是你的服务目标,用于衡量服务的表现(通常使用百分比)。

SLA定义了你对你的客户做出的承诺,即,如果你无法满足目标,则需要付出什么代价(如退钱)。为了达成SLA,你需要保证SLO比SLA更严格。

我们用来校验和衡量用户满意度的工具称为"用户旅程"(user journey)。用户旅程是一个用户视角下的文本表述。用户旅程用于考察你的用户是如何通过与你的服务进行交互来达成一系列目标的。最重要的用户旅程称为关键用户旅程(CUJ)。

一旦给你和你的用户或客户制定了目标,接下来就需要考虑当无法满足这些目标时会发生什么。

计算事件的影响

事件会影响稳定性目标。稳定性目标受故障数、波及长度和范围以及故障的级别的影响。因此,为了降低事件影响,首先需要了解如何降低影响。下面看下如何对事件的影响定质定量。

下图展示了为了测量影响,如何计算服务不可靠的时间,即发现影响的时间加上恢复(缓解)的时间,然后乘以事件数目(受事件频率的影响)。

主要的指标是探测时间、修复时间和故障间隔时间:

  • 探测时间(TTD): 从故障发生到有人观测到或收到产生问题的告警之间的时间
  • 修复时间(TTR):从当有人收到问题警报时开始,到问题得到缓解之间的时间。这里的关键是缓解,并不意味着你需要提交代码来修复问题,它只是响应者缓解对用户的影响所花费的时间,如将流量切换到其他域。
  • 故障间隔时间(TBF)是一个事件到下一个相同类型的事件之间的时间。

降低用户影响意味着降低下面等式中的四个方面:探测时间、恢复时间、故障间隔时间和影响。

为了降低事件影响,并让系统恢复到一个已知状态,你需要结合技术和"人"这两个方面,如流程和支持。在谷歌,我们发现一旦人力介入,故障至少会持续20到30分钟。通常,使用自动化和自恢复系统是个不错的策略,这些方式可以帮助降低探测时间和恢复时间。

Unreliability sumfrac{TTD TTR}{TBF}times Impact

你需要注意你使用的方法。简单地降低告警阈值可能会导致反效果并增加噪音,而过多地使用自动化进行快速恢复可能会降低恢复时间,但可能会导致忽略底层问题。在下一章中,我们会分享一些策略来帮助降低探测时间、恢复时间和事件发生的频率。

降低探测时间

一种降低事件影响的方式是降低探测事件的时间(见下图)。作为起草SLO的一部分,你需要进行风险分析,制定优先级,并确定哪些事情会导致无法达成SLO。这些准备也可以帮助你降低事件探测的时间,此外还可以通过如下方式最小化探测时间:

  • 对齐SLIs,使你的客户满意度指标尽可能贴近用户的期望,用户可以是真人或其他服务。再进一步,将你的告警对齐到SLOs,通过周期性地回顾这些告警来确保它们能够代表用户的期望。
  • 使用最新的信号数据。这意味着你需要使用不同的测量策略来衡量告警质量。选择最适合的获取数据的方式很重要:流、日志或批处理。此外还需要平衡告警的频率,过于频繁的告警可能会造成噪音,而过慢的告警则可能会影响到用户(噪音告警也是Ops团队经常抱怨的问题之一,他们通常是传统的运维开发或SRE)。
  • 使用有效告警来避免告警倦怠。当需要立即采取行动时才需要进行通知,且只会通知特定的响应者(特定的团队或所有者)。注意另一种经常抱怨的情况是,告警不可操作。 但新的问题来了:"如果只通知那些需要立即行动的内容,那么剩余的问题该怎么处理?"。一种解决方式是对不同原因的告警采用不同的工具和平台。可能"最佳的平台"是一个问题单系统或仪表盘,或只是在"拉取"模式下通过指标进行故障排除和调试。
降低修复时间

我们已经讨论了降低事件影响的一种方式是降低探测事件。另一种降低影响的方式是降低恢复时间。降低恢复时间更多是降低"人工侧"的时间。使用事件管理协议并组织一个事件管理响应来降低事件管理中的歧义以及缓解对用户造成的影响所需的时间。除此之外,你还需要培训响应者,制定清晰的程序和内容,并降低on-call的压力。下面看下这些策略的细节。

培训响应者

未准备的on-caller会造成更长的恢复时间。可以考虑执行如灾难恢复测试或我们先前提到的"厄运之轮"测试等训练主题。另一种技术是提高对on-call的指导。让on-caller结对工作(“结对待命”),或让学员在轮班期间引入经验丰富的on-caller进行学徒训练(“跟踪”),进而增加新团队成员的信心。记住on-call是有压力的。清晰的事件管理流程可以通过消除歧义并明确必要的动作来降低压力。

建立组织事件响应流程

事件管理中存在一些常见的问题。例如,缺少责任性、缺少沟通、缺少层级关系,而自由职业者/"英雄"可能会导致更长的解决时间,这些问题会给no-caller和响应者增加额外的压力,并影响到你的客户。为了解决这些问题,我们建议通过清晰的角色建立一个层级响应组织架构。这可以帮助维护清晰的指令线并分配清晰的角色。

在谷歌,我们使用IMAG (Incident Management at Google),这是一个灵活的基于消防员和医务人员使用的事故指挥系统(ICS)框架。IMAG可以教你如何通过清晰的角色、任务和通信渠道建立一个层级结构。它建立了一个标准的、一致的方式来解决紧急情况并组织有效的响应。

IMAG协议为那些致力于解决事件的人提供了一个框架,保证能够自组织应急响应团队并通过与响应者和相关人进行有效沟通,控制整个事件响应,并帮助协调响应工作。它声称,事件指挥者(IC)负责协调响应和委派责任,而其他人则向IC报告。每个人都有一个特定的角色,如运维领导负责修复问题,而沟通领导则负责处理沟通。

通过这种协议,你可以降低歧义,理清楚团队的工作,并降低修复的时间。

建立清晰的on-call策略和流程

我们建议对事件响应on-call策略以及应急响应流程(包括故障中和故障后)进行归档。它包括一个清晰的故障升级路线以及责任划分。它可以降低歧义处理故障的相应压力。

编写用的运行手册/playbooks

归档非常重要,它可以将经验转化为所有队友都能获得的知识。通过对文件进行优先级排序并预留出一定的时间来为事件过程创建playbooks和策略,这样你的团队成员就可以知道事件是如何呈现的。一开始的playbooks不需要非常具体,可以从一个简单的点开始,然后逐步迭代。一个好的例子是谷歌的"看见问题,修复问题"(即在发现问题的时候修复问题),并让新团队成员更新这些playbooks,作为新员工培训的一部分。

将ploybooks开发作为一个主要的事后项目,并将该团队贡献作为绩效管理的一部分。这通常需要领导层确定优先级并分配必要的资源,将其作为开发冲刺的一部分。

降低响应疲劳

第二章讨论了响应者的疲劳成本,进一步讲,如果你的响应者已经筋疲力尽,这将会影响他们解决问题的能力。你需要确保班次平衡,否则就需要使用数据帮助你了解不平衡的原因并减少工作量。

研究数据采集和可观测性

你希望基于数据来做决定,如果你看不到这些数据,就无法了解事态的发展。因此我们鼓励在组织中使用度量文化,采集那些与用户体验有关的指标,并度量你目标的完成度以及错误预算消耗速度,并以此做出反馈,调整优先级等。此外,还可以度量团队的辛苦程度并周期性地审视SLIs和SLOs。

你会希望尽可能多地收集高质量数据,特别是那些与用户体验有关的数据,这可以帮你进行故障排查和问题调试。采集应用和业务指标,并将其绘制成关注用户体验和关键用户旅程的仪表盘和可视化界面。

可以看到,可以通过一些方式来降低恢复时间,并最小化事件影响。现在让我们看下通过增加故障事件的间隔时间来降低事件影响。

增加故障之间的时间

为了增加故障之间的时间,并降低故障的个数,你可以重构架构,并解决在风险分析和流程改进过程中发现的故障点。还可以通过其他事情来增加TBF。

避免反模式

本文中我们提出了一些反模式,包括缺少可观测性和正反馈,这些模式可能会导致系统过载并引发级联事故,如崩溃。你需要避免这些反模式。

分散风险

可以通过冗余和职责解耦、避免单点故障和全局变更,以及采纳高级的部署策略来分散风险。考虑在数小时、数天或数周内进行渐进式和金丝雀式的发布,这样可以在所有用户受到影响之前降低风险并识别问题。类似地,可以通过自动化测试,逐步发布和自动化回滚来及早发现问题。通过参与混沌工程并引入故障注入和自动化灾难恢复测试(如DiRT)来达到及早发现故障的目的。

采用开发实践

你可以采纳开发实践来培养质量文化,创建代码监视流程以及可以集成到CICD流水线中的健壮性测试。CICD可以节省工程时间并降低用户影响,提高服务部署的信心。

考虑可靠性设计

在SRE中,我们有一句话:"希望并不是一个策略"。在讨论故障时,问题不在于是否是故障,而在于何时发送故障。因此,一开始就需要考虑到可靠性设计,以及可以适应故障的健壮性架构。通过如下问题来了解你是如何处理故障的:

  • 我的系统能够抵御哪种类型的故障?
  • 它是否能够容忍非预期的单点故障或重启?
  • 它是否能够处理分区或区域故障?

在你了解到存在的风险以及风险的影响范围,就可以进行风险缓解措施。例如,为了缓解单点问题,你应该使用持久化磁盘,并提高自动化数据备份功能。为了缓解区域和分区故障,你可以使用多种跨分区和区域的资源来实现负载均衡。另一种方式是水平缩放。例如,如果将一体式架构分解为微服务,就可以独立地缩放这些服务。水平缩放也可以意味着地理上的缩放,如通过多个数据中心来提高弹性。我们建议尽可能避免使用人工配置和特殊硬件。

优雅降级

架构中另一个重要的方面是实现优雅降级方案。降级是一种策略,类似限流和减载。可以考虑一下这个问题,如果我不能给所有用户提供所有功能,那么是否可以给所有用户提供最小集合的功能?是否可以限制用户流量并丢弃占比过高的请求?当然,可接受的降级程度取决于服务和用户旅程。如,返回x产品和返回未更新的支票账户余额之间存在差异,但根据经验,降级服务总比没有服务好。

纵深防御

纵深防御是另一种处理故障的方式,更精确地说是容忍故障。如果你依赖一个系统进行配置或其他运行时信息,则需要确保有一个可回退或缓存的版本来在依赖不可用时保证系统的正常运作。

N 2资源

N 2资源是实现分布式系统可用性的最小原则。N 2意味着你需要有N的容量来处理峰值请求, 2实例来容忍一个实例因为故障不可用,另一个实例因为(计划中的)升级不可用。我们前面提到过,你的服务要像关键依赖项一样可靠,因此需要合理地设计架构。当在云端进行构建时,需要确保使用服务的可靠性等级,将其与应用目标关联起来,并注意它们的适用范围(例如,在谷歌云平台的构建块[区域、区域、全球])。通过在架构设计中解决可靠性问题来降低后续的纠正成本。没有一劳永逸的方式,需要根据需求来作出相应的策略。

NALSD:非抽象大型系统设计 在讨论可靠性和SRE时不能不涉及非抽象的大小系统设计。在谷歌,我们发现可以通过在设计阶段解决可靠性问题来降低未来的成本,如果你使用了一个可迭代的系统设计风格,就可以通过一种低成本的方式开发出健壮且可扩展的系统。我们将这种方式称之为非抽象大小系统设计,或NALSD,它描述了谷歌产品系统的系统设计迭代过程。可以参考谷歌的 SRE Classroom。

从故障中获得的经验

最后,通过从失败中吸取教训来让明天更好。当中使用的工具就是事后调查。确保问题修复、缓解和文档升级都使用一致的事后调查流程。与跟踪其他问题一样跟踪事后调查项,并将事后调查优先于"一般"工作。下一章节我将详细讨论事后调查。

事后调查及其他

在上一章中我们涵盖了降低用户影响的一些方式,包括技术和人两方面的,因为二者都会影响到探测时间、缓解/恢复时间以及故障间隔时间。在本章,我们将讨论事件结束之后的事:编写事后调查并使用它作为一种工具来帮助分析问题根因以及吸取经验。

在事件完成之后,你如何知道做什么事情来降低未来的事件?为了了解需要关注那些内容,我们推荐使用一种事件驱动方式。数据可以是风险分析过程的结果,或前面提到的度量。重要的是要依赖事后调查中采集到 的数据并从影响到用户的事件中吸取经验。

一旦有了大量事后调查,就可以确定出事件的产生模式。让事后调查指引你解决问题。为此,我们推荐创建一个共享仓库并在团队内部共享事件调查。

心理安全感

在讨论事后调查的时候不得不提到心理安全。因此,在开始编写事后调查前,首先讨论事件管理文化中固有的心理安全,并讨论及早升级的价值。

如果你的客户受到影响,你应该及早解决问题。但如果组织中的成员对事件升级或事件扩大感到不安,则可能会影响事件的及时解决。如果一个公司不鼓励问问题,或者事件升级会带来影响,那么响应者可能会不确定是否应该问问题。如果发生了这种情况,会让事件在好转之前变得更糟。

故障总会发生,你需要接受这个事实,这就是为什么实施SRE原则需要一种支持和授权的文化。随着不断使用新功能和新系统来增强服务,一个关键点是需要理解事件和故障是不可避免的。因此,如果不从事件中吸取经验,那就错失了一个提升的机会。Aikidoe的创始人Morihei Ueshiba曾说过"失败是成功的关键,每个错误都会教会我们一些东西"。

如果你将操作看作是一个软件工程问题,那么当出现问题时,需要查看系统中存在的导致这些问题发生的缺陷,然后采取一些措施来避免人为导致的错误。

人永远不会导致故障,但系统和流程会允许这些故障发生

如果发生了故障,那么就应该是系统的缺陷,而不应该是人的问题。因为人为错误是一个既定的事实。事件管理的最终目的不是消除人为错误。

构建心理安全氛围的一些点子

实施事件管理实践是一项组织变革,需要文化方面的支持,能够让你进行创新并从错误中吸取经验。关键是要有心理安全和无指责的流程。

心理安全是一种信念,即一个人不会因为说出想法、问题、担忧或错误而受到惩罚或羞辱。 ---Dr. Amy Edmondson, Novartis Professor,哈佛商学院领导与管理

心理安全促进了绩效导向组织的一些主要特点;特别是将故障作为一个学习机会,并采纳一些新的点子。例如Westrum的组织文件模型基于心理安全来预测软件交付能力:与其他两种类型相比,生成型组织更有可能成为表现最佳的组织。

心理安全性较高的团队更有可能采纳来自队友的不同想法,比销售目标高出17%(不安全团队则低于销售目标19%),并且被高管评为有效团队的概率是后者的两倍。

处理事件时的心理安全

在风险管理中,重要的是要让人们知道他们可以发出自己的观点并确定问题产生的原因,而不用担心被惩罚或被嘲笑。当发生一个事件时,必须报告并产生一个事件。在处理事件的过程中,你可能需要共享之前发生的事件的信息,即使这么做会暴露之前的错误(但这与指责无关)。你可能还需要将事件交接给下一个on-call工程师,并建议改进内部流程、工具和功能。

如果没有心理安全和无指责文化,人们可能会避免提出一些可能可以确定事件问题根因的正确问题。结果是团队无法得到成长并进行创新,原因是他们看重印象管理且害怕承担后果。

为了在团队中培养心理安全和无指责文化,需要关注学习机会:将每个事件都视为每个人都可以从中学习的机会,通过邀请每个人(特别是有不同意见的人)发出他们各自的观点来鼓励不同的想法。作为一个领导,你也应该承认自己的错误,通过提问来激发好奇心。

不推卸责任

无指责和心理安全是一起的,其中一个可能是另一个的天然结果。假设出现了一个故障,如果经理的第一个问题是"谁导致的?",那么这可能会创造一种指责文化,导致无法创新和提升。相反,你应该提倡无指责:

无指责是一种观念,即将人的责任转移到系统和流程。

指责文化会 阻碍人们快速解决问题并从中学习的能力,因为为了避免遭受惩罚,他们可能会倾向于隐藏信息并避免声张事件。另一方面,无指责文化可以让你更关注提升。你应该假设个体是出于善意而执行的动作,并根据可用的最佳信息做决定的。相比指责,对组织来说,调查失实信息的根源更有用。因此,当出现问题时。需要支持团队的设计并鼓励创新和学习。

从错误中吸取经验

只有在正确识别错误的程序性和系统性原因时,错误才是学习和提升的最佳机会。在谷歌,Ben Treynor Sloss每个季度都会发送一封工程报告--"谷歌最大的成功与失败",以此来鼓励从错误中进行学习。

实施事件管理实践时的心理安全

事件响应者需要有一定的信息才能成为一个高效的响应者,即使是在压力环境中。响应者在处理事件时必须感到心理安全。

心理安全可以延申到多个层面:

来自团队成员

  • 响应者不应感受到自己的行为受到同行的评判,尤其是在他们犯错时
  • 说“我需要帮助”应该得到奖励,而不是质疑或谴责

来自伙伴团队

  • 一些团队可能会觉得团队X的成员因居高临下而名声不佳,所以我们不要跟他们进行交流。更甚者,有些团队会采取这种文化,或使用这种方式来避免与其他团队进行交互。这种态度是不能容忍的,它会造成额外的紧张并降低事件响应的速度。

来自管理者

  • 管理者需要负责团队的心理安全,在一个事件中,管理者通常不会做技术性的工作,相反,他们会专注于确保团队的健康,寻找压力/倦怠的迹象,如可能在团队处理事件的时候订披萨,也可能只是告诉事件响应者"休息5分钟"。
  • 管理者还可以帮助从组织其他部门获得更多帮助
  • 管理者为团队争取他们需要的来自组织其他部分的缓冲,并在冲突发生时介入来解决冲突。

来自组织

  • 只有组织将心理安全融入其文化,心理安全才能蓬勃发展。组织中应该有一个无责任的文化,其关注点是修复导致事件的流程。
  • 行业中充斥着诸如"三次罢工政策"等政策,该政策要求终止或严厉谴责涉及影响生产的三个错误的个人。尽管这种政策的目的是鼓励响应者在事件发生时格外小心,但它会导致响应降级("我不想成为打坏电话的人")、推卸责任("我们没有打破它,另一个团队打破了它"),或隐藏有价值的信息("不要泄露我们已经知道这个问题的事实")。
  • 如果领导希望他的团队和组织能够蓬勃发展,就必须培养一种尊重、信任和合作的文化。这种文化需要源自上层组织。

早先提到过,心理安全环境的一个好处是可以降低升级时间。如果一个组织拥抱合作文化,响应者会更倾向于征求外部帮助---无论是来自本团队还是公司的其他团队。

在回顾事件时,一个反复出现的主题始终是"如果我们早点升级,我们本可以节省XXX美元的收入损失",即使在拥有健康、心理安全环境的团队/组织中也是如此。让一个响应者提问题其实是一件很困难的事情--以免被认为是能力不足或缺乏准备的表现。我们被训练成隐藏不安全感(甚至是感知到的不安全感),并被教导成为英雄,为团队做出110%的贡献。这些行为实际上是累赘,特别是在事件响应期间--反应过度或疲惫的人更容易出错。升级应该是简单快速的,并且不附带任何条件。应该认为假设升级的意图是好的。如果发现无需升级,找出升级的原因(可能是因为缺乏/丢失文档)并纠正流程即可。

事件响应者不应该对试图自己做的每件事保持高度警惕,相反,应该尽早升级。在谷歌,事件响应团队有一个俗语:我们会告诉其他团队我们不介意经常收到通知,且我们也没有收到过多的通知。

编写事后调查

现在我们已经深入讨论了心理安全,下面看下如何编写事后调查。当出现问题时,这是一个可以从中学习并提升自我的机会。而一个"糟糕的工程师"则会认为"期望不会看到那样",一个好的工程师则会注意到发生了某些事情,并认为"有意思,让我们告诉其他人",这也是事后调查介入的地方。

编写事后调查是一种系统分析形式:它是深究导致事件的缺陷并确定提升工程和工程流程领域的过程。事后调查并不是多余的,而是在服务上实践系统工程的核心方法,用于推动改进。

在编写事后调查时,需要持有一种无指责的文化,并假设事件终究会发生。正如前面提到的,预防失败很重要,但是要认识到日常故障是不可避免的,尤其是在涉及到规模时。事件给你和你的团队带来了从中学习的机会。事后调查是确保你能够从错误中吸取经验的一种系统解决方案,还能帮助共享从错误中获得的知识(如给其他人阅读事后调查)。

事后调查提供了一种从事件中学习的正式流程,以及防止和降低事件、影响和复杂度的机制。例如,你可能会从中学习到避免将补丁作为一个一劳永逸的方案。事后调查可以展示趋势,并为你的工作排出优先级。事后调查应该是无指责的,这可以避免私底下对问题进行反复讨论,即谁导致的问题,是谁的过错等等。事后调查应该关注从事件中学习到了什么以及对未来的改进。

有些信息是每个事后调查都应该涉及的。如,好的事后调查会包含清晰的行动项(AIs),以及这些行动项的责任人和截止时间。注意,这里没有指责谁,而是为了提升责任意识,消除歧义,并确保能够跟踪所有的动作。此外,还应该包含一个清晰的事件时间线,即事故的发生时间、检查时间、升级时间(如果有的话)和缓解时间(如果有的话)、故障影响和故障的截止时间。如果发生了升级,则需要说明为何以及如何产生的。为了避免困惑,需要明确术语事件故障,以及事件开始事件检测。我们推荐在事件过程中使用在线文档来记录调试和缓解过程,后续在事后调查时可以参考这些文档。文档可以帮助正确捕获时间线,并确保没有错过关键的AIs。

在事后调查中应该避免责备性语言,并践行心理安全。可以举例并询问问题,但不能指责。事后调查是关于了解事件的本质,采取的动作以及如何防止未来发生相同的问题。

谷歌的一个最佳做法是与尽可能多的受众分享事后调查的经验教训。通过分享可以帮助其他人获得事后调查并从中获得知识。

我们已经发现,建立一个无指责的事后调查文化可以获得更可靠的系统,成就一个成功的SRE组织。

系统分析和组织提升

我们已经讨论了无指责的事后调查,并将事后调查作为一种系统分析的形式。但你是否深入你的系统来完全了解到到底发生了什么以及如何发生的?为了得出最终结论,需要对事件进行分析,而不是简单的描述。事件发生之后或在事后调查中需要对其进行深入分析,为了暴露并解释最终结论,是否对事件和系统方面进行了分析。这一点很重要,因为它增加了你的团队在事件发生后正确修复事件的可能性。

在编写事后调查时,你应该以最完整和最准确的系统运作细节为目标,这样才能确保修复是正确的。在图5-2中,带有"你认为的问题是什么"的圆圈反映了你对事件中的系统的理解,这是你可以控制的部分。带有"实际的问题是什么"的圆圈反映了事件中的系统的真实状态,涉及复杂的、由很多活动部件组成的复杂技术生态系统,以及与管理事件有关的所有的(人)交互过程,要真正理解所有这些细微差别是极其困难的。但对事件的理解越深入,圆圈的重叠部分也就越大,越接近潜在的问题。

如果事件已经被缓解,系统再次稳定,那么还有必要理解真正的问题?当然,原因是它涉及可行动性,或一个事件之后修复或改进的能力。这些事后的增量系统改进有助于逐步建立系统的恢复能力。第三个重要的圆圈表示你实现的系统修复的部分(图5-4)。

这个圆圈也不能移动,因为总会有一些超出你控制的东西影响系统的健康(天气、地球大小、光速)。

中间最小的交集(1 ∩ 2 ∩ 3)就是事件之后你的团队可以实施的最佳部分。而"你认为的问题"和"你可以修复的地方"的重叠部分((1 ∩ 3) – 2)一个危险区域:你认为有些方式可以长期起作用,但实际并不会解决真正的问题。你可能会解决一些主要问题周边的问题,或解决了另一个隐藏问题暴露出来的症状。假设你已经解决了一个尚未真正解决的问题,可能会导致无法了解到日益上升的风险。如果再次发生了一个特定的事件,你的客户信任度会降低,并错失本可以更有效利用的时间。

如果对系统进行了深入研究,就可以在其他两个圆圈不动的情况下,最大化中心部分(1 ∩ 2 ∩ 3)。即提高了有效修复的可能性。如果你希望确保目标是正确的,则需要花时间来研究如何移动圆圈,其关键是需要对系统进行足够的调查分析,然后选择可以更大概率提升系统弹性的工程项目。但这里面存在一个回报递减的问题,例如,花费一个月时间来调查每个故障,这并不是一种谨慎使用资源的方式。在下面章节中,我们会推荐一些方式来帮助(思考以)移动圆圈。

根因VS触发因素

让我们从两个关键术语开始,根因和触发因素:

根因:

系统的危险,或系统如何容易到受攻击。系统中的一个危险可能会存在一段不确定的时间--需要通过某种系统环境变更来将其转化为故障。需要明确一点:在复杂系统中,很少只有一个事件根因。熟练的从业者会认为事件的底层根因是一个导致危险状态的各种相互作用的因素网络。

触发因素:

即让根因换变为事件的环境。它是一个相关、但独立的东西。为了防止重复产生故障,有时候需要定位根因。有时,则围绕这些触发因素建立预防措施更为合理。

根因和触发因素一起会导致事件。当然,这样描述有一些过于简化。根因/触发因素和事件类型并没有一对一的映射关系,系统的复杂性可能会导致各种后果。下面看几个例子:

房屋着火:

  • 根因:燃气泄漏
  • 触发因素:泄漏的炉子附近的一个火花塞点燃了泄漏的气体。
  • 事件:房租着火(但这里的根因可能会导致其他事件)

蚂蚁侵扰:

  • 根因:温暖的季节适合自然环境中的昆虫和害虫繁衍生息
  • 触发因素:邋遢的饮食习惯会留下很多面包屑
  • 事件:蚂蚁侵扰

内存不足(OOM):

  • 根因:配置文件导致内存泄漏
  • 触发因素:突然发生大量请求
  • 事件:OOM

第三个场景中,在触发现有的条件之前,根因可能已经存在了多年(这是技术债务最终比预期更昂贵的方式之一)。该根因可能并不是一个缺陷,它可能是限制系统行为的任何因素。在系统将限制转化为危险的环境条件之前,限制本身并不危险。此外还要澄清一点,触发因素可能并不是简单的二元状态(即是或否),触发条件可能存在于一个动态范围内,只有在系统的环境和根因相互作用时才会成为事件。这两个因子可以被视为创建事件生命周期的关键组件。

事后剖析的根因部分应详细说明一些根本原因和当前事件的触发因素。为了防止再次发生停机,有时解决根本原因很重要。有时,围绕触发因素建立预防措施则更为合理。

然而,仅仅将根因和触发因素分开讨论并不能从本质上提高团队事后分析的质量。本文的所有章节中都包含一定数量的最低要求,但同样重要的是,事后分析应该包括可以被团队以外的工程师理解并采取行动的分析内容。这是一个反复出现的问题吗?是否注意到缓解步骤,或者是否需要确定缺陷?事后剖析是否适当地解释或量化了系统的正常功能,并展示出故障的规模比较和影响?如果说89%的产品用户群受到了影响…这意味着什么?

隔离系统VS整个堆栈

不幸的是,存在一种反模式,即在不考虑系统上下文(系统环境中与系统功能相关的部分)的情况下,将系统分析的范围限制在可能被破坏的部分。以下是一些可以拓宽系统分析深度的问题:

  • (如适用)该事件是否作为单个事件进行审查,或是否讨论了关联/相关/子事件?
  • 你或任何主要内部客户是否了解到以前未知的依赖关系?
  • 端到端的沟通情况如何?

虽然事件可能只发生在整个堆栈的一个子部分中,但这并不意味着事件是孤立发生的。查看事件是否以及如何影响整个堆栈和公司成员,可能会发现事情是如何产生的。这可能包括你的事件是否会导致其他事件或级联故障,或者你的公司作为一个整体是否能够在事件期间进行有效沟通。

时间点VS轨迹

在研究中,元分析是一种将多个研究串联成更大的结论的技术。如果你认为每一次事后剖析都是一项传达系统时间点视图的研究,那么将这些工作视为一个整体可以帮助识别新出现的模式和见解。我们建议将每次事后剖析作为一次检查系统随时间变化的行为的机会。考虑以下问题:

  • 是否根据系统随时间的轨迹对该事件进行了审查?
  • 是否发生了相同的故障类型?
  • 是否存在长期的强化或调节回路?

整体系统思维的一部分是随着时间的推移来考虑你的系统。总的来说,不要让同一个事件发生两次。

我们已经研究了系统分析组织上的改进,以及它如何使你和你的团队受益。现在让我们来看一个真实的例子。

Mayan Apocalypse:一个真实世界的例子

为了实际理解我们讨论过的原则,下面我们将深入了解一下谷歌发生过的一个重大故障。我们会复盘整个过程,了解可缩放的组织是如何解决该故障的,以及我们可以从中学习到哪些内容。

对谷歌而言,Mayan Apocalypse并不是导致2012年故障的新玩意。相反,Mayan Apocalypse发生在2019年6月2日,使用了名为Maya的网络自动化工具,它用来管理标签并在我们的一个骨干网上进行流量定向,但一个很小的代码移位导致整个实体被错误标记。

中午左右,我们正在进行计划内的维护工作,并最终确定了要在一组服务器上运行的操作和配置变更列表(包括在Maya上)。但当该错误标记与我们的作业调度逻辑冲突时,我们“发现”了一种新的故障模式,在这种模式下,与流量方向相关的作业被整体取消调度。然后,进出这些区域的网络流量试图将取消调度的作业与流量方向仍然有效的剩余网络容量相匹配,但没有成功。网络开始变得拥塞,我们的系统正确地对流量过载进行了分类,并自动排出更大且延迟敏感度更低的流量,保留较小且延迟敏感的流量。

流量开始变得拥塞。因此,监控启动了事件管理流程的第一步:告警。组件响应者会接收到来自监控系统的告警,表示他们负责的系统可能出现了故障。我们的监控系统会自动给响应者发送网络组件超过错误阈值的通知,然后由响应者介入调查。

同时,受到网络容量降低影响的区域产生了外溢,该网络拥塞导致在我们的网络和计算基础设施出现了级联故障。通常,我们的网络会优先处理用户(包括员工)流量(而非内部流量)。这种做法是好的,我们对99.9%的员工流量进行了重定向,因为这部分人并不参与问题解决,以此来最大保障用户的正常工作。而剩余的参与事件的0.1%的员工通常知道如何处理并避开这一限制。但此次级联故障影响到了我们的内部工具,导致大量告警中断,并导致大量呼机关闭。当每个on-caller转换为事件响应模式时,他们发现服务因为网络问题而不可用。网络组件响应者快速确定了网络拥塞的根因,但由于相同的网络拥塞仍然在导致服务降级,因为减缓了恢复配置的能力。

由于每个人都希望更好地支持用户并了解期望的服务恢复轨迹,因此原始网络组件响应者突然就有了很多同伴。

在谷歌,我们有如下三种级别的组件:

  • 基础设施组件,如网络流水线或存储服务
  • 产品服务组件,如网络YouTube流或Google Search的前端
  • 内部服务组件,如监控,零信任远程访问,MaYa等。此时这一部分功能出现了故障。

广泛依赖意味着,在网络组件解决问题之前,任何人都无法进行下一步动作。但如此多且职责不同的响应者的介入并没有加速问题的解决。根因和二阶效应开始模糊;一个团队的原因是另一个团队产生的影响,每个人都在努力贡献自己的知识。虽然每个人都是其系统栈的专家,但都没有完整的系统视角来说明哪些工具路径变得不可用。

为什么?从未接触过拥挤网络的路径都很好。而有些路径即使接触到了拥塞网络的路径,其也是正常的,因为我们为其分配了优先级。因此针对外部用户的服务是可用的,如视频通话或文档编辑。但如果路径本质上是内部的,例如作业或标志控制或Maya配置,则它将被取消优先级并被卡住。

我们看到一座火山喷发,20分钟后,我们得出结论,我们的问题“可能与熔岩有关”。

在介入故障一小时之后,一个组件响应者指出,影响我们基础设施的系统间问题过于严重,围绕事件的协调沟通正在变得混乱且不和谐。此时已经有超过40个团队加入了事件响应沟通频道,都想提供帮助。在对事件进行衡量之后,我们发现Google Cloud, Gmail, Google Calendar, Google Play和其他服务都受到了影响,导致业务服务无法运作,员工无法进行工作以及人员之间无法进行沟通。一些员工尝试使用不需要用到受影响网络的服务,但最后他们放弃了。

在40个人参与的情况下,我们的网络问题解决人员缺乏足够的心理空间来实施合适的缓解措施、协调实施这些缓解措施,与所有利益相关者进行沟通,以及管理预期效果等。

因此,他们进行了升级,我们的网络组件on-caller通知了一些在合理时区内的Tech IRT成员,这些Tech IRT成员能够在事件影响到可用性时介入工作。由于事件影响深远,很多Tech IRT成员其实已经介入了该事件。我们的一些Tech IRT响应者并不作为事件施令者,因为他们是网络团队的成员或管理者,可以帮助确定主要根因,因此他们选择协助运维。

成为事件施令者的Tech IRT的成员之前并没有在受故障影响的网络组件团队中工作过,但他们能够评估我们的"求救信号"以及响应故障的人员状态。通过他们接受过的训练,事件施令者能够使用某种机制来访问我们的生产系统,该机制会立即将他们的行为识别为“事件响应”,并能够破坏“降级内部流量”标记。一旦内部流量有了一点余量,他们就会引导网络on-caller加入进来解决问题。

在这一过程中,他们很快组织正在沟通以及试图“参与”的每个人。一旦这种混乱的工程能量被组织起来,每个人就可以发挥作用。他们可以更清楚地跟踪不同系统的持续状态,并了解缓解措施的实施进度。随着管理不再给我们的网络组件响应者带来负担,他们和他们的团队(已经出现在帮助中)就有了实施适当缓解计划的空间。包括通过大量减少负载来为重启和一些紧急强制配置更改腾出系统余量.

一旦启动了缓解事件,技术IRT成员就会专注于推动事件走向结束。他们设定了一些退出标准,用来确定我们何时可以结束事件,确保其他系统能够在执行恢复操作中得到支持,最后确保相关的响应团队的交接和分离。

在事件结束并恢复正常服务后,需要深入进行事后分析,分析事件并了解其根因以及通过这些故障模式暴露出来的紧急特性。此后,相关的网络团队一直致力于一些非常酷的举措,重构了Maya并防止再次这种故障模式,以及防止之前没有考虑过的故障模式再次困扰我们的系统。

最后,我们用内部简介徽章、荣誉模因和奖金奖励参与的人员。对大多数人来说,真正严重的事件是他们职业生涯中最糟糕的一天。提供一些小的东西给每个人提供了一种微妙的激励,让他们为事后分析做出贡献,帮助我们学习,并不断地变得更有适应力。

0 人点赞