1913年,苏格兰生理学家约翰·斯科特·霍尔丹提出了将笼中的金丝雀带入矿井以检测危险气体的想法。100多年后,霍尔丹的矿井金丝雀方法也应用于软件测试中。
在本文中,“金丝雀测试”一词指的是对服务更改进行部分和限时部署,然后评估服务更改是否安全。然后,生产变更流程可能会向前滚动、回滚、向人员发出警报或执行其他操作。有效的金丝雀测试涉及许多决策——例如,如何部署部分服务更改或选择有意义的指标——值得单独讨论。
谷歌部署了一个名为 CAS(金丝雀分析服务)的共享集中式服务,该服务在生产变更期间提供关键指标的自动(通常是自动配置的)分析。CAS 用于分析二进制文件的新版本、配置更改、数据集更改和其他生产更改。CAS 每天在谷歌评估数十万次生产变更。
CAS 要求对生产的修改和分析进行非常严格的分离。它是一个纯粹的被动观察者:它从不更改生产系统的任何部分。金丝雀设置等相关任务在 CAS 之外执行。
在典型的 CAS 工作流程(如图 1 所示)中,负责生产变更的部署工具将变更部署到服务的某个子集。它可能会执行一些自己的基本健康检查。例如,如果推送新版本的 HTTP 服务器导致进程重启,则部署工具可能会等待服务器标记自己能够提供服务后再继续。(这也可能告知生产变更的部署速度。此部署工具行为并非金丝雀测试所特有。)
生产的这个子集现在构成了金丝雀群体。通过与对照群体进行 A/B 测试,CAS 回答了“金丝雀是否明显更差?”这个问题。对照群体是服务剩余部分(可能是严格的)子集。重要的是,CAS 并非试图建立绝对健康状况。
群体应尽可能细粒度。例如,应用程序更新可以使用该特定进程的全局标识符,在谷歌,这将是 BNS(Borg 命名服务)路径。BNS 路径的结构为 /bns/<cluster>/<user>/<job name>/<task number>。作业名称是应用程序的逻辑名称,任务编号是特定实例的标识符。2 对于内核更新,标识符可能是机器主机名:显然,多进程可以在同一台机器上运行,但(模虚拟化)您仅限于单个运行内核,因此粒度在机器级别定义。粒度允许调用者在运行时无限制地对整个服务进行切片和切块,并且使得静态预先存在的金丝雀设置变得不必要。
一旦设置了金丝雀群体,部署工具就会向 CAS 请求裁决。此请求指定金丝雀群体和对照群体,以及该群体中每个成员的时间范围。实体的金丝雀状态可能是短暂的:金丝雀仅在某个特定时间点才成为金丝雀;在该时间之前,它没有经过测试的生产变更。
如果存在用户提供的配置,则请求还包含对用户提供的配置的引用。如下节所述,CAS 试图通过强制执行我们普遍认为正确的事情来提供价值,即使没有外部配置也是如此。
CAS 在评估后提供时间点裁决:简单的 PASS 或 FAIL,表示系统表现相同或以危险的异常方式运行。(如果底层基础设施不可用且 CAS 无法得出裁决,则也可能出现第三个选项 NONE。客户端通常将其视为与无法访问 CAS 相同。)信号必须清晰明确,以便部署工具采取诸如向前滚动、回滚或向人员发出警报等操作。CAS 有意不提供置信度分数、p 值等:这将意味着部署工具具有确定何时采取实际操作的逻辑。保持此决策集中化可以更好地重用,并消除从毫无意义的启发式方法创建人为置信度分数的风险。
通过与用于更改生产的所有主要工具(包括用于推出新二进制文件、配置和数据集的工具)集成,CAS 迅速在整个谷歌获得了广泛的覆盖。广泛的集成需要保守的集成方法:在某些情况下,必须在分析质量上做出让步,以避免给用户带来不便。
为了开始使用 CAS,无需进行金丝雀设置,这消除了又一个入门障碍。如果用户未指定配置,则会对可以在各个方面进行推理的指标执行默认分析。CAS 自动发现金丝雀系统的功能,例如二进制文件是 C++ 还是 Java,或者哪些 RPC(远程过程调用)方法接收大量流量,然后选择要运行的分析(例如,RPC 错误率)以用于这些功能。谷歌基础设施的同质性使得这在很大程度上是成功的。
CAS 相对简单的高级交互由底层相当复杂的系统实现。
CAS 的 API 有两个 RPC 调用:Evaluate()
和 GetResult()
。
Evaluate()
被赋予一个或多个试验,并返回一个唯一的字符串标识符,即 Evaluation ID
,它是 CAS 用户界面的完全限定 URL。这个简单的技巧使得将这些链接插入到各种部署工具中变得非常简单,因为它意味着它们不需要任何额外的客户端逻辑来弄清楚如何将标识符转换为 URL。试验是金丝雀群体和对照群体以及应在其中进行比较的时间范围对;如果时间范围的结束时间未设置,则 CAS 可以自由决定评估需要多长时间。这意味着在过度延迟评估和没有足够的数据来得出有意义的结论之间取得平衡。实际上,至少需要五分钟的数据。调用速度相当快(通常在一秒内),并且 API 无限期地保留结果数据(或者至少直到垃圾回收不再相关的评估)。客户端为逻辑评估发送一个 RPC。
CAS API 不保证评估会在发送 Evaluate()
调用时开始。相反,分析在 GetResult()
时开始,因为这表明有人对结果感兴趣。作为优化,分析实际上在 Evaluate()
时开始,但为了对客户端设置适当的期望,此优化不是 API 定义的一部分。
GetResult()
接受一个参数:Evaluation ID
。此 RPC 会阻塞,直到分析过程完成,这可能需要请求结束时间后几秒到几分钟的时间;GetResult()
是幂等的。
为了可靠性,CAS 开发人员设计了具有两个调用的系统。此设置允许系统在无需复杂的客户端协作的情况下恢复处理请求。当库中的一个错误导致所有 CAS 进程每五到十分钟崩溃时,这种可靠性策略在实践中得到了体现。由于健壮的 API,CAS 仍然能够服务所有用户请求。
此设计有一些明显的替代方案。CAS 开发人员决定不使用单个长时间运行的 RPC:由于这些调用本质上是两个 Unix 进程之间的点对点连接,因此中断(例如,因为一个进程重新启动)将导致客户端完全重试。原始设计文档包含大量选项,每个选项都与谷歌基础设施和需求的细微属性相关的权衡。
虽然 RPC 仅返回简单的 PASS/FAIL 裁决,但底层分析由几个组件组成。
最低级别的单元是检查,它是来自金丝雀群体的时间序列、来自对照群体的时间序列以及将两个时间序列转换为明确的 PASS/FAIL 裁决的统计函数的组合。一些示例检查可能是
• 金丝雀的崩溃率不明显高于对照。
• RPC 错误率不明显高于对照。
• 加载到内存中的数据集大小在金丝雀和对照之间相似。
如 API 描述中所述,每个评估请求可以定义多个试验(即,金丝雀群体和对照群体的对)。每个试验的评估都会产生一系列检查。如果任何试验中的任何检查失败,则整个评估将被声明为失败,并返回 FAIL。
目前,试验被实现为相当独立,尽管给定的评估请求可能具有多个试验,如果它们查看两个相关但不同的组件。例如,考虑具有前端和后端的应用程序。前端的更改可能会触发后端的错误行为,因此您需要比较两者
• 金丝雀前端与生产前端。
• 从金丝雀前端接收流量的后端与从生产前端接收流量的后端。
这些是不同的群体,可能具有不同的指标,但任何一方的失败都是潜在的问题。
用户定义的配置到底需要什么?虽然 CAS 的设计阶段涉及关于配置性质的漫长哲学讨论,但主要目标是简单性。CAS 开发人员不希望强迫用户学习实现细节,以便将他们的高级目标编码到配置中。目的是仅向用户提出几个问题,这些问题尽可能接近用户对世界的看法。
应该为每个匹配的试验执行的各个检查定义了需要哪些信息。对于每个检查,用户指定
• 应该称为什么。
• 如何获取特定指标的时间序列。
• 如何将这些时间序列转换为裁决。
用户还可以包含可选的信息片段,例如长篇描述。
Monarch 是时间序列的典型监控数据源。1 用户指定一个抽象查询,金丝雀群体和对照群体在请求评估的 RPC 中运行时确定。CAS 具有灵活的自动查询重写机制:在运行时,它会重写抽象查询以专门用于仅提取特定群体的数据。假设用户配置了一个查询,“获取 CPU 使用率。” 在运行时,CAS 将该查询重写为“获取作业 foo-server 副本 0、1、2 的 CPU 使用率。” 这种重写发生在金丝雀群体和对照群体中,从而产生两个查询。
尽管不常见,但可以为金丝雀和对照指定不同的查询。查询仍然受制于重写,这保证了它们将仅提取实际正在评估的对象的数据。
为了简化配置,还有常用查询。这些是由 CAS 团队策划的预制查询,例如崩溃率、RPC 服务器错误率和 CPU 利用率。这些提供了已知的语义,CAS 可以为其提供更高质量的分析。
最后,需要有一种方法可以将通过为金丝雀和对照群体运行 Monarch 查询获得的时间序列(可能是多个流)转换为明确的裁决。用户可以从一系列测试中进行选择。一些测试(例如 Student's t 检验)具有明确的统计学来源,而另一些测试包含自定义启发式方法,试图模仿人类如何评估两个图表。
稍后将讨论,如果用户选择默认配置,以及如果用户未指定统计测试,则自动分析适用。
图 2 说明了 CAS 系统的组件。本节介绍每个组件的角色和 CAS 请求流程。
Spanner 数据库是评估流程的共享同步点;几乎所有组件都写入它。它是评估进度和最终状态的规范存储。
部署工具将 Evaluate()
调用发送到 RPC 前端,RPC 前端有意非常简单。前端为评估生成唯一标识符,将整个评估请求存储在数据库中(以唯一标识符作为主键),并返回标识符。
GetResult()
调用也落在 RPC 前端,RPC 前端查询数据库以查看协调器是否已在处理评估。如果是,则 RPC 前端向协调器发送 AwaitEvaluation()
RPC,该 RPC 会阻塞,直到评估完成。如果协调器未跟踪评估(例如,如果重启导致状态丢失)或者未分配协调器,则 RPC 前端选择一个协调器,将该信息存储在数据库中,并调用 AwaitEvaluation()
。这些重试是有限的。
如果评估已完成,则 RPC 前端不会联系协调器,而是立即将数据库中的结果返回给调用者。
RPC 前端处理并行 GetResult()
非常便宜。除非客户端请求两个重复且独立的评估,否则选择一个协调器可以避免重复昂贵的工作。
协调器将当前正在处理的所有评估保存在内存中。在 AwaitEvaluation()
时,协调器检查评估是否正在处理中。如果是,则协调器只需将此 RPC 添加到等待结果的 RPC 集中。
如果评估未在处理中,则协调器以事务方式取得数据库中评估的所有权。如果另一个协调器(出于任何原因,例如竞争条件)独立取得所有权,则此事务可能会失败,在这种情况下,协调器会推回 RPC 前端,RPC 前端然后联系新的规范协调器。
收到新评估后,协调器执行以下操作
1. 从配置服务器检索完全限定且明确的扩展配置。协调器现在具有要运行的所有检查的完整集。
2. 将每个检查分发给评估器。
3. 调用模型服务器以获取检查的预测行为,同时报告当前评估中检查的结果。
4. 使用最终裁决响应所有等待的 AwaitEvaluation()
RPC。
协调器在整个过程中将进度检查点保存到数据库。检查点在协调器收到完全限定的配置后以及评估器返回检查评估请求时异步发生。如果协调器崩溃,则新的协调器接管,从数据库读取进度,并从上一个协调器的检查点继续。
配置服务器查找并完全展开与评估匹配的配置。
当配置在请求中显式引用时,查找很简单。如果未显式引用配置,则一组自动查找规则会搜索用户的默认 配置。这些查找规则基于诸如谁拥有金丝雀服务等功能。
CAS 提交的配置是通用的:它可能说“获取 HTTP 错误率”,而未指定从哪里获取错误率。在典型流程中,部署工具识别当前金丝雀并在请求评估时将此信息传递给 CAS。因此,配置作者不一定能够预测金丝雀群体。
为了支持这种灵活性,配置服务器扩展配置和金丝雀/对照群体定义,以准确指定请求的数据。例如,用户的“获取 HTTP 错误率”变为“从这三个进程获取金丝雀数据的 HTTP 错误率,以及从这十个进程获取对照数据的 HTTP 错误率。” 从用户的角度来看,在配置通用变体后,“正确的事情”会自动发生,从而无需在金丝雀测试之前定义专用的金丝雀设置(尽管用户如果出于其他原因想要这样做,也可以定义这样的设置)。
除了评估外,配置服务器还接收配置更新,验证更新的正确性和 ACL(访问控制列表),并将这些更新存储在数据库中。
评估器接收每个检查的完全定义的配置(在已提及的扩展之后),每个检查在单独的 RPC 中。然后评估器
1. 从适当的时间序列存储中提取金丝雀数据和对照数据的时间序列。
2. 运行统计测试,将生成的时间序列对集转换为每个统计测试的单个 PASS/FAIL 裁决(因为金丝雀/对照而成为对;因为可能存在每个运行进程的时间序列,并且金丝雀或对照组中有许多进程而成为集)。
如果用户配置了统计测试,则评估器仅运行该测试。但是,如果用户选择自动配置,则评估器可能会运行数十个具有各种参数的测试,这些测试生成的数据会馈送到模型服务器。
评估器将来自测试的数据和任何潜在的元数据(例如,与时间序列存储通信时发生的错误)返回给协调器。
模型服务器执行自动数据分析。评估后,协调器向模型服务器请求预测。该请求包含有关评估以及来自评估器的所有观察到的裁决的信息。
对于每个观察到的裁决,模型服务器返回其对该特定评估的预期裁决。它将此信息返回给协调器,协调器在决定总体裁决时忽略对预测失败的统计函数的结果。如果模型服务器预测失败是因为所述失败是典型行为,则此行为被视为被评估系统的属性,而不是此特定金丝雀评估的失败。
正确地进行金丝雀测试是一个复杂的过程,因为用户需要完成以下细致的任务
• 正确识别有意义的金丝雀部署,该部署创建关于评估指标的代表性金丝雀群体。
• 选择适当的评估指标。
• 确定如何评估金丝雀为通过或失败。
CAS 通过消除这些任务中最令人生畏的任务来减轻负担:评估时间序列对通过或失败的含义。CAS 基于这样的基本论点,即运行可靠的系统不应需要深入的统计学知识或不断调整统计函数的参数。
CAS 使用的行为学习与用于监控的异常检测的一般问题略有不同。在 CAS 场景中,您已经知道服务正在被更改,以及更改发生的准确位置和时间;还有一个正在运行的对照群体可以用作分析的基线。用于监控的异常检测会触发用户警报(可能在凌晨 4 点),而与 CAS 相关的错误推出侵入性要小得多——通常会导致暂停或回滚。
用户可以通过手动指定测试及其参数来选择退出自动配置。
用最简单的术语来说,我们希望确定在类似的生产变更期间,被评估系统的典型行为。高级假设是,不良行为很少见。
此过程在线进行,因为它必须能够快速适应:如果某个行为是异常的但又是可取的,则 CAS 会使推出失败;当重试推送时,CAS 需要适应。
如果用户在异常实际上很危险时不断重试推送,则自适应行为会带来风险:CAS 最终开始将这种危险行为视为新常态,并且不再将其标记为有问题。随着自动化变得越来越成熟和可靠,这种风险变得越来越小,因为用户不太倾向于盲目重试(假设评估不正确),而更倾向于在 CAS 报告失败时实际进行调试。
离线支持流程可以补充标准在线学习。
直观地,您知道比较不同二进制文件之间的相同指标可能会产生不同的结果。即使您查看相同的指标(例如,RPC 延迟),有状态服务(如 BigTable)的行为也可能与无状态 Web 搜索后端截然不同。根据正在评估的二进制文件,您可能希望从统计测试中选择不同的参数,甚至完全不同的统计测试。
CAS 没有尝试深入发现潜在的功能依赖关系,而是根据过去运行生产系统的经验,按维度分解观察结果。随着时间的推移,您可能会发现其他相关维度。
目前,系统按以下因素对观察结果进行分组
• 数据源。您是在观察进程崩溃率、RPC 延迟还是其他内容?每个数据源都通过对配置进行指纹识别和一些小的启发式方法来删除不重要的差异的常见来源来分配唯一的标识符。
• 统计函数和参数。 这可能意味着,例如,显著性水平为 0.05 的 t 检验。每个不同的统计函数和参数集都被分配一个唯一的标识符。
• 应用程序二进制文件。
• 地理位置。这指的是金丝雀和对照的位置。
• 进程年龄。进程最近是否重新启动?这有助于区分配置推送(可能不会重新启动进程)和二进制文件更新(很可能会重新启动进程)。
• 其他分解,例如不同的 RPC 方法。 例如,在 BigTable 中读取行与删除整个表可能表现非常不同。这种分解取决于提供的指标。
• 观察时间。为了系统效率,这保持在每日粒度。
这些因素与每个观察到的裁决的计数相结合,构成模型。模型仅知道标识符——它不了解数据源、统计函数或其参数。
所有与特定二进制文件相关的模型都跨所有存在观察结果的统计函数和跨所有数据源获取。
对于每个统计函数和每个数据源,计算过去观察到的行为的加权总和,以获得每个可能的结果。相似性通过特征(进程年龄和地理位置)的启发式相似性和模型的年龄来加权。由于 RPC 方法等其他分解没有可用的相似性指标,因此其他匹配的分解只是被过滤掉,而没有进一步的加权。
对于单个统计函数和单个数据源,我们为每个可能的裁决(PASS、FAIL 或 NONE)生成一个分数。我们从过去观察结果的加权总和中计算此分数。加权基于诸如观察结果的年龄和观察结果与当前情况的相似性等因素(例如,两个观察结果是否都与相同的地理位置相关?)。
每个统计函数都有一个最小通过率。比率sum[PASS] / (sum[PASS] + sum[FAIL] + sum[NONE]) 必须大于 PASS 预测的最小值。否则,预测为 FAIL。
此比率允许 CAS 对各种函数施加严格性的概念,同时容忍“正常”的波动行为。例如,考虑两个统计函数:一个仅容忍金丝雀和对照之间 1% 的偏差,另一个容忍 10% 的偏差。前者可以被赋予非常高的最小通过率,而后者可以被赋予较低的最小通过率。如果指标在正常运行中波动超过 1%,则 CAS 会快速学习该行为并停止标记它。如果该波动是一次性的,则 CAS 会标记它,系统会恢复,并且随着时间的推移,CAS 会重新学习正常行为仅包括低于 1% 的偏差。CAS 有意花费更长的时间来学习较大容忍波动下的正常行为,因此在本示例中,CAS 在 10% 的情况下将以较慢的速度学习。
当用户最初提交评估指标的配置时,不存在可用于预测的过去行为。为了引导这种情况,CAS 会查找可能已使用此配置的过去评估,并运行这些评估以收集模型服务器的观察结果。凭借足够的近期评估,CAS 在用户首次请求评估时就已经拥有有用的数据。
如果无法进行此类引导,则模型服务器会恢复为最宽松的行为。
行为预测机制也是任意输入分析的首次尝试,它允许在对测试一无所知的情况下对测试行为进行建模。
当用户配置 RPC 错误率的金丝雀测试时,CAS 预先知道值介于 0.0 和 1.0 之间,并且值越高越差。对于用户提供的针对监控数据的查询,CAS 没有这样的知识,只能应用一系列测试并观察差异。
尽管存在一些重大问题(稍后讨论),但 CAS 开发团队选择了这种方法,因为他们确信这种方法风险相对较小。它仍然大大改进了自动化金丝雀测试。开发人员正在积极致力于改进。
虽然硬编码统计函数结果的元分析在自动配置的初始启动中效果良好,但这种方法粗糙且不灵活。CAS 可以存储有关时间序列的数据,而不是存储统计测试的结果,而对导致这些结果的时间序列一无所知。
CAS 支持的每个统计函数都需要来自时间序列的不同数据。我们可以尝试提取此数据的固定大小聚合视图,每个统计测试一个。例如,时间序列上的 Student's t 检验视图可以是两个群体的平均值、群体大小和方差估计。
来自许多过去观察结果的这种聚合视图将允许为每个统计函数合成单个测试,并根据过去的数据和某些策略选择正确的参数。
这项工作基本上将取代当前自动配置系统的一半。
观察结果分解最终成为模型服务器对整个 CAS 的最大贡献,因此开发团队计划扩展此功能。添加更多分解需要额外的计算/存储成本,因此,鉴于 CAS 的大规模,需要谨慎进行。
虽然 CAS 当前具有基于评估对象的分解,但这可以扩展到按金丝雀测试类型进行分解。有传闻称,在使用前后测试与两个群体的同步测试观察时,金丝雀行为存在重大差异。金丝雀群体相对于对照群体的大小以及群体的绝对大小也可以提供有意义的分解。
未来的工作可以确定这些额外的分解是否值得,以及以什么粒度执行它们。自动生成的决策树也可能是一种选择。
CAS 仅看到生产变更。目前,即使在稳态下,它也不会学习到特定指标是不稳定的。
关于生产变更之外的指标行为的数据可用于定义数据中的典型噪声。仅当偏差高于此典型噪声水平时,CAS 才会使金丝雀测试失败。噪声数据可能来自分析每次评估的对照群体,因为对照群体预计没有生产变更。
CAS 自动配置最显著的问题是在已经有完全相同环境下的丰富历史观测数据时,过度拟合数据。在这种情况下,仅使用该环境的历史数据。
这种行为有一些注意事项。考虑一下新版本的系统发布,该版本处理每个 RPC 调用的时间是原来的两倍,但性能却显著提高。CAS 会将每个地理位置发布中较长的 RPC 处理时间标记为异常行为,从而给发布所有者带来不必要的麻烦。缓解措施是仔细调整启发式方法,以选择相关环境,从而纳入完美匹配之外的数据。
CAS 很有用,但远非完美。它曾发生过用户无视金丝雀测试失败并推送了有缺陷的版本的事件。用户对复杂自动化的不信任是许多此类问题的根源。
CAS 开发人员正在通过以人性化的术语(不需要统计学知识)明确解释 CAS 为何得出特定结论来解决这种不信任问题。这包括文本解释和图形提示。
由于模型服务器仅存储统计函数的结果,而不知道输入值,因此 CAS 不知道时间序列的典型值。
不了解数据的语义意味着正在运行的测试纯粹是相对比较,例如使用 t 检验,其零假设是指标的增长不超过 5%。虽然相对比较很容易理解,但如果提供的时间序列值通常为零,或者如果较大的相对变化发生在绝对值太小而对服务所有者不重要的情况下,它们的行为会非常糟糕。
这是该机制的一个重大限制。虽然它在实际操作中没有产生太多实际影响,尤其是在存在简单的解决方法的情况下,但它值得改进。可以对该机制进行许多改进,其中一些非常简单。除了前面提到的未来工作之外,候选方案还包括标准偏差分析和查看指标过去观察到的行为。
由于 CAS 仅使用硬编码的统计函数集及其参数,因此该系统在分析预期输入规模之外的输入方面有些不灵活。例如,如果涵盖了 1% 到 100% 差异的范围,那么对于差异为 200% 属于正常的系统和指标又该如何处理?如果即使 1% 的差异也是不可接受的,又该怎么办?
CAS 开发人员最初并未预料到这会在实践中成为一个重大限制,值得庆幸的是,事实证明确实如此。大多数值得进行金丝雀分析的指标都包含一些噪声;相反,我们大多数 A/B 测试都希望看到两个群体之间几乎没有差异,因此较大的差异是意外的,因此会被注意到。
使用 CAS 的最佳方法是采用少量高质量指标,这些指标是系统健康的明确指标:合适的指标在健康时是稳定的,而在不健康时会发生剧烈变化。
通常,最佳的金丝雀测试策略是选择与 SLO(服务级别目标)相关的指标。CAS 自动与 SLO 跟踪系统集成,以应用服务范围的 SLO 和一些启发式方法,以将其适当地缩放到金丝雀测试规模。
设置 SLO 是一个与业务需求相关的复杂过程,SLO 通常涵盖整个服务,而不是单个组件。即使单个组件的金丝雀测试行为异常,它对服务整体 SLO 的影响也可能很小。因此,需要为每个组件识别(或引入)关键指标。
将服务导出的所有指标都输入计算机是很诱人的。虽然 Google 系统提供了大量的遥测数据,但其中大部分仅对调试狭隘的问题有用。例如,许多 BigTable 客户端库指标并非直接表明系统是健康的。实际上,仅使用弱相关的指标会导致不良结果。Google 的一些团队已经进行了分析,证明使用大量指标是合理的,但除非您执行类似详细的数据分析,否则仅使用少量关键指标会产生更好的结果。
金丝雀测试是提高生产安全性的非常有效的方法,但它并非万能药。它不应取代单元测试、集成测试或监控。
尝试“完美准确”的金丝雀测试设置可能会导致配置僵化,从而阻止行为发生可接受变化的发布。当系统本身不适合进行复杂的金丝雀测试时,很容易完全放弃金丝雀测试。
对超精确金丝雀测试设置的尝试通常会失败,因为僵化的配置会在常规发布期间造成过多的麻烦。虽然有些系统不容易进行金丝雀测试,但它们很少不可能进行金丝雀测试,尽管对该系统进行金丝雀测试流程的影响可能较低。在这两种情况下,切换到逐步引入金丝雀测试的策略,从唾手可得的成果开始,将会有所帮助。
早期,CAS 团队问道:“提供集中的自动金丝雀测试系统是否值得?” 并努力寻找答案。如果 CAS 实际上阻止了中断,您如何知道中断的影响,从而知道 CAS 的影响?
该团队尝试对生产变更进行启发式分析,但各种不同的发布程序使得这项练习过于不准确,以至于不切实际。他们考虑了一种 A/B 方法,其中忽略了评估子集的失败,而是通过它们来衡量影响。然而,鉴于影响中断严重程度的因素很多,预计这种方法不会提供清晰的信号。(事后分析文档通常包含一个诸如“我们很幸运”之类的部分,突出了许多要素促成了中断的严重性。)
最终,该团队确定了他们所谓的准事故分析:查看 Google 的大型事后分析,并识别 CAS 可能可以预防但未预防的中断。如果 CAS 由于缺少功能而未能预防中断,则会识别出这些功能并通常会实施。例如,如果 CAS 可以通过增加一项功能来预防 1000 万美元的事后分析,那么实施该功能就证明了 CAS 的 1000 万美元价值。这个问题空间在不断发展,因为我们尝试其他类型的分析。最近,该团队对公司(更同质化)的一部分进行了分析,以识别中断和事后分析的趋势,并发现了一些粗略的信号。
CAS 关于系统行为的大量信息可能可以用于其他用途。此类扩展表面上可能很诱人,但由于 CAS 的运行方式(以及需要在产品级别运行的方式),它们也很危险。
例如,CAS 团队可以观察到金丝雀测试在哪个地理位置表现最佳,并建议用户仅选择该地理位置。虽然推荐的位置现在可能是最佳的,但如果用户遵循建议仅在该位置进行金丝雀测试,团队提供进一步建议的能力就会降低。CAS 数据仅限于其观察结果,因此局部最优行为可能与全局最优行为大相径庭。
自动金丝雀测试已反复证明可以提高开发速度和生产安全性。CAS 帮助预防由二进制更改、配置更改和数据推送引起的具有重大经济影响的中断。
期望从事产品开发或可靠性工作的工程师具备统计学知识是不合理的;消除这个障碍——即使以可能降低分析准确性为代价——也导致了 CAS 的广泛采用。CAS 已被证明即使对于不需要配置的基本情况也很有用,并且显著提高了 Google 的发布可靠性。影响分析表明,CAS 可能已经预防了数百起值得进行事后分析的中断,并且不使用 CAS 的团队的事后分析发生率明显更高。
随着 CAS 开发人员努力扩展其范围并提高分析质量,CAS 正在不断发展。
许多人为此项工作贡献了关键组件。感谢 Alexander Malmberg、Alex Rodriguez、Brian O'Leary、Chong Su、Cody Smith、Eduardo Blanco、Eric Waters、Jarrod Todd、Konstantin Stepanyuk、Mike Ulrich、Nina Gonova、Sabrina Farmer、Sergey Kondratyev 以及许多其他以自己的方式做出贡献的人。
此外,感谢 Betsy Beyer、Brian O'Leary 和 Chris Jones 的技术评审。
1. Banning, J. 2016. Monarch, Google 的行星级监控基础设施。Monitorama PDX 2016; https://vimeo.com/173607638。
2. Van Winkel, J. C. 2017. Google 的生产环境,从 SRE 的角度来看。 https://landing.google.com/sre/book/chapters/production-environment.html。
大规模失败
在快速变化面前保持可靠性
Ben Maurer,Facebook
https://queue.org.cn/detail.cfm?id=2839461
分布式系统的验证
提高系统正确性的实践指南
Caitie McCaffrey
https://queue.org.cn/detail.cfm?id=2889274
浏览器安全:来自 Google Chrome 的经验教训
Google Chrome 开发人员专注于三个关键问题,以保护浏览器免受攻击。
Charles Reis、Adam Barth、Carlos Pizano
https://queue.org.cn/detail.cfm?id=1556050
Štěpán Davidovič 是 Google 的站点可靠性工程师。他目前从事自动监控的内部基础设施工作。在之前的 Google SRE 职位中,他开发了金丝雀分析服务,并从事过各种共享基础设施项目和 AdSense 可靠性工作。他于 2010 年在布拉格捷克技术大学获得学士学位。
Betsy Beyer 是纽约市 Google 站点可靠性工程部的技术作家,也是站点可靠性工程:Google 如何运行生产系统的编辑。她之前曾为 Google 数据中心和硬件运营团队编写文档。在移居纽约之前,Betsy 曾在斯坦福大学担任技术写作讲师。她拥有斯坦福大学和杜兰大学的学位。
版权所有 © 2018,归所有者/作者所有。出版权已授权给 。
最初发表于 Queue 第 16 卷第 1 期—
在 数字图书馆 中评论本文
Niklas Blum, Serge Lachapelle, Harald Alvestrand - WebRTC - 开放 Web 平台的实时通信
在这个疫情时期,世界比以往任何时候都更加依赖基于互联网的 RTC(实时通信)。在过去十年中,RTC 产品的数量呈爆炸式增长,这在很大程度上是由于更便宜的高速网络接入和更强大的设备,同时也归功于一个名为 WebRTC 的开放、免版税平台。WebRTC 正在从支持有用的体验发展成为在疫情期间让数十亿人继续工作和教育,并保持重要的人际接触的关键。WebRTC 未来的机遇和影响确实令人着迷。
Benjamin Treynor Sloss, Shylaja Nukala, Vivek Rau - 重要的指标
衡量您的站点可靠性指标,设定正确的目标,并努力准确衡量指标。然后,您会发现您的服务运行得更好,中断更少,并且用户采用率更高。
Silvia Esparrachiari, Tanya Reilly, Ashleigh Rentz - 跟踪和控制微服务依赖项
如果您曾将钥匙锁在房子或汽车里,您就会熟悉依赖循环。没有钥匙您无法打开锁,但没有打开锁您就无法拿到钥匙。有些循环是显而易见的,但更复杂的依赖循环可能很难在它们导致中断之前找到。跟踪和控制依赖项的策略对于维护可靠的系统是必要的。
Diptanu Gon Choudhury, Timothy Perrett - 为互联网规模服务设计集群调度器
希望构建调度系统的工程师应考虑他们使用的底层基础设施的所有故障模式,并考虑调度系统的运营商如何配置补救策略,同时帮助租户系统在租户系统所有者进行故障排除期间尽可能保持稳定。