采用 SLO

本文档定义了几个服务等级目标 (SLO),它们适用于不同类型的常见服务工作负载。本文档为两部分文章中的第 2 部分。第 1 部分定义 SLO 中介绍了 SLO,展示了 SLO 是如何从服务等级指标 (SLI) 派生的,并描述了什么是良好的 SLO。

DevOps 现状报告确定了可提高软件交付方面表现的功能。这两个文档可以帮助您实现以下功能:

衡量的指标

无论您的网域如何,许多服务都具有相同的功能,可以使用通用 SLO。以下关于通用 SLO 的讨论按服务类型组织,并详细介绍了适用于每个 SLO 的 SLI。

请求驱动的服务

请求驱动的服务会接收来自客户端(其他服务或用户)的请求,执行一些计算,可能将网络请求发送到后端,然后向客户端返回一个响应。请求驱动的服务通常通过可用性和延迟时间 SLI 来衡量。

可用性作为 SLI

可用性 SLI 表示服务是否正常运行。可用性 SLI 的定义如下:

成功处理的有效请求所占的比例。

首先,您需要定义“有效”。一些基本定义可能是“长度非零”或“遵循客户端-服务器协议”,但服务所有者负责定义“有效”的含义。衡量有效性的一种常用方法是使用 HTTP(或 RPC)响应代码。例如,我们通常认为 HTTP 500 错误是要计入 SLO 的服务器错误,而 400 错误则是不用计入的客户端错误。

在确定要衡量的指标后,您需要检查系统返回的每个响应代码,以确保应用正确、一致地使用这些代码。为 SLO 使用错误代码时,务必询问代码是否是用户服务体验的准确指标。例如,如果用户尝试订购缺货的商品,网站是否会中断并返回错误消息,或者网站是否会建议类似产品?为了与 SLO 配合使用,错误代码需要与用户的期望相关联。

开发人员可能会误用错误。如果用户询问商品暂时缺货的产品,开发人员可能会错误地编写要返回的错误。不过,系统实际上正常运行,没有出现错误。即使用户无法购买所需商品,代码也需要作为成功返回。当然,此服务的所有者需要知道某个产品缺货,但从客户的角度来看,无法进行销售不是错误,不应计入 SLO。但是,如果服务无法连接到数据库以确定商品是否有库存,则这是一个错误,应计入错误预算。

您的服务可能会更复杂。例如,您的服务可能处理异步请求或为客户提供长时间运行的过程。在这些情况下,您可以通过其他方式公开可用性。但是,我们建议您仍将可用性表示为成功的有效请求的比例。您可以将可用性定义为客户的工作负载按请求运行的分钟数。(此方法有时称为衡量可用性的“良好时间”方法。)对于虚拟机,您可以根据初始请求后可通过 SSH 访问虚拟机的分钟比例来衡量可用性。

延迟时间作为 SLI

延迟时间 SLI(有时称为“速度”)指示服务是否足够快。“延迟时间”SLI 的定义与“可用性”类似:

处理速度超过阈值的有效请求所占的百分比。

如需测量延迟时间,可以计算计时器启动时间与给定请求类型的停止时间之间的差异。关键是用户对延迟的感知。常见的隐患是衡量延迟时间时过于精确。实际上,用户无法区分 100 毫秒 (ms) 和 300 毫秒的刷新时间,可能会接受 300 毫秒到 1000 毫秒之间的任意值。

相反,最好是开发以活动为中心的指标,可以让用户集中注意力,例如,在以下流程中:

  • 交互式:用户在点击元素后等待结果的时间,1000 毫秒。
  • 写入:1500 毫秒,用于更改底层分布式系统。虽然对于系统而言,此时间长度会被视为缓慢,但用户往往倾向于接受该时间。我们建议您在指标中明确区分写入和读取。
  • 后台:5000 毫秒,针对用户不可见的操作,例如定期刷新数据或其他异步请求。

延迟时间通常以分布的形式进行衡量(参见本系列第 1 部分中的选择 SLI)。在给定分布的情况下,您可以测量各种百分位数。例如,您可以测量比历史第 99 个百分位慢的请求数。在本例中,我们认为好的事件是比这个阈值快的事件,而这个阈值是通过检查历史分布设置的。您还可以根据产品要求设置此阈值。您甚至可以设置多个延迟时间 SLO,例如典型延迟时间与尾延迟时间。

我们建议您不要仅使用平均(或中位数)延迟时间作为 SLI。发现中位数延迟时间太慢意味着一半的用户已经感到不满意。换句话说,在发现对长期错误预算的真正威胁之前,可能会有好几天的延迟。因此,我们建议您为尾延迟时间(第 95 百分位)和延迟时间中位数(第 50 百分位)定义 SLO。

在 ACM 文章重要指标中,Benjamin Treynor Sloss 写下以下内容:

“一个很好的实际经验法则…第 99 百分位延迟不应超过延迟时间中位数的三到五倍。”

Treynor Sloss 继续写道:

“我们发现服务的第 50、95 和 99 百分位延迟时间度量值都是单独有价值的,理想情况下,我们将围绕这些值设置 SLO。”

可以遵循的一个好模型是根据历史百分位数确定延迟时间阈值,然后测量每个存储分区中有多少请求。如需了解更多详情,请参阅本文档后面有关延迟时间提醒的部分。

质量作为 SLI

对于复杂的服务而言,质量是很有帮助的 SLI,这些服务 (SLI) 设计为在依赖项变慢或不可用时通过降级来正常失败。质量 SLI 的定义如下:

已处理且服务没有降级的有效请求所占的比例。

例如,网页可以从一个数据存储区加载其主要内容,并从其他 100 个服务和数据存储区加载辅助性的可选资源。如果一项可选服务已停止服务或运行速度过慢,该网页仍可以在没有辅助元素的情况下呈现。通过测量已传递降级响应的请求数(即,缺少至少一个后端服务响应的响应),可以报告不良请求的比例。您甚至可以跟踪有多少对用户的响应缺少来自单个后端的响应,或者缺少来自多个后端的响应。

数据处理服务

有些服务不是为了响应用户请求而构建的,而是使用来自输入的数据、处理该数据并生成输出。这些服务在中间步骤中如何表现并没有最终结果那么重要。对于此类服务,最强大的 SLI 是“新鲜度”、“覆盖率”、“正确性”和“吞吐量”,而不是“延迟时间”和“可用性”

新鲜度作为 SLI

“新鲜度”SLI 的定义如下:

更新时间超过阈值的有效数据的比例。

例如,在批处理系统中,新鲜度可以是为给定输出成功运行一项处理后所经过的时间。在更复杂的或实时处理系统中,您可以跟踪在流水线中处理的最新记录的存在时间。

例如,假设一款实时生成地图块的在线游戏。用户可能不会注意到创建地图块的速度有多快,但他们可能会注意到地图数据丢失或不是最新。

或者,假设某个系统会读取库存跟踪系统的记录,从而为电子商务网站生成消息“X 件商品有货”。您可以按以下方式定义“新鲜度”SLI:

使用了在最后一分钟内刷新的库存信息的视图的百分比。

您还可以使用传递非刷新数据的指标来通知质量 SLI

覆盖率作为 SLI

“覆盖率”SLI 的定义如下:

已成功处理的有效数据的比例。

如需定义覆盖率,请先确定是将输入作为有效项接受还是跳过该输入。例如,如果输入记录损坏或长度为零,无法处理,您可以考虑将该记录视为无效,用于测量您的系统。

接下来,您计算有效记录的数量。您可以使用简单的 count() 方法或其他方法来执行此步骤。此数字是您的总记录数。

最后,要生成覆盖率 SLI,您需要计算已成功处理的记录数,并将该数量与有效记录记录总数进行比较。

正确性作为 SLI

“正确性”SLI 的定义如下:

生成正确输出的有效数据所占的比例。

在某些情况下,您可以通过多种方法确定输出的正确性,以验证输出的处理情况。例如,旋转图片或为之着色的系统绝不应产生零字节图片,或长度或宽度为零的图片。请务必将此验证逻辑与处理逻辑本身区分开来。

测量正确性 SLI 的一种方法是使用已知良好的测试输入数据,即具有已知正确输出的数据。输入数据需要代表用户数据。在其他情况下,可能会对输出进行数学或逻辑检查,如前面旋转图片的示例所示。另一个示例可能是结算系统,它通过检查交易前的余额与交易后的余额之间的差值是否与交易本身的值相符来确定交易是否有效。

吞吐量作为 SLI

“吞吐量”SLI 的定义如下:

数据处理速率快于阈值的时间比例。

在数据处理系统中,吞吐量通常比对给定工作的单一延迟度量等更能代表用户的满意度。例如,如果每个输入的大小变化很大,那么如果作业以可接受的速度进行,比较每个元素完成的时间可能就没有意义了。

“每秒字节数”是测量处理数据所需工作量(无论数据集的大小如何)的常用方法。但是,任何与处理成本大致成线性关系的指标都是可行的。

根据预期吞吐率对数据处理系统进行分区,或实现服务质量系统以确保处理高优先级输入和对低优先级输入进行排队,这可能是值得的。无论哪种方式,按照本节所定义的方式测量吞吐量都可以帮助您确定系统是否按预期工作。

计划执行服务

对于需要按固定间隔执行操作的服务(例如 Kubernetes cron 作业),您可以测量“偏差”和“执行时长”。以下是计划的 Kubernetes cron 作业示例:

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: hello
spec:
  schedule: "0 * * * *"

偏差作为 SLI

作为 SLI,“偏差”的定义如下:

在预计开始时间的可接受时段中开始的执行比例。

“偏差”衡量作业的计划开始时间与实际开始时间之间的差异。例如,如果前面的 Kubernetes cron 作业设置为每小时零分钟开始,而实际在每个小时的第三分钟开始,则偏差为三分钟。如果作业提前运行,则偏差为负。

您可以用一段时间的分布情况来衡量偏差,并使用相应的可接受范围来定义良好的偏差。要确定 SLI,您需要比较良好范围内的运行次数。

执行时长作为 SLI

作为 SLI,“执行时长”的定义如下:

在可接受的时段内完成的执行所占的比例。

“执行时长”是指完成作业所需的时间。对于给定执行,常见的故障模式是实际时长超过计划时长。

一个有趣的案例是,如何使用此 SLI 来衡量永无止境的作业。由于这些作业没有完成,因此您需要记录给定作业花费的时间,而不是等待作业完成。此方法提供了工作完成时间(即使在最坏情况下)的准确分布。

与偏差一样,您可以将执行时长作为分布情况来跟踪,并为良好事件定义可接受的上限和下限。

其他系统的指标类型

许多其他工作负载都有自己的指标,可用于生成 SLI 和 SLO。请参考以下示例:

  • 存储系统:耐用性、吞吐量、首字节时间、blob 可用性
  • 媒体/视频:客户端播放连续性、开始播放的时间、转码图执行完整性
  • 游戏:匹配活跃玩家的时间、生成地图的时间

如何衡量

在了解要衡量的内容之后,您可以决定如何进行测量。您可以通过多种方式收集您的 SLI。

服务器端日志记录

生成 SLI 的方法

处理请求或已处理数据的服务器端日志。

注意事项

优点:

  • 可以重新处理现有日志以回填历史 SLI 记录。
  • 跨服务会话标识符可以跨多个服务重建复杂的用户历程。

缺点:

  • 系统不会记录未到达服务器的请求。
  • 导致服务器崩溃的请求可能无法被记录。
  • 处理日志的时间长度可能会导致过时的 SLI,这可能是因为操作响应的数据不足。
  • 写入代码以处理日志可能是一项容易出错、耗时的任务。

实现方法和工具:

应用服务器指标

生成 SLI 的方法

从处理用户请求或处理其数据的代码导出 SLI 指标。

注意事项

优势:

  • 向代码中添加新指标通常既快捷又费用不高。

缺点:

  • 系统不会记录未到达应用服务器的请求。
  • 多服务请求可能难以跟踪。

实现方法和工具:

前端基础架构指标

生成 SLI 的方法

利用负载平衡基础架构中的指标(例如,Google Cloud 的全球第 7 层负载平衡器)。

注意事项

优点:

  • 指标和历史数据通常都已存在,因此减少了工程的入门工作量。
  • 测量是在最靠近客户的位置进行,但仍在服务基础架构内。

缺点:

  • 不适用于数据处理 SLI。
  • 只能大致估算多请求用户历程。

实现方法和工具:

合成客户端或数据

生成 SLI 的方法

构建定期发送虚构请求并验证响应的客户端。对于数据处理流水线,创建合成的、已知良好的输入数据并验证输出。

注意事项

优点:

  • 衡量多请求用户历程的所有步骤。
  • 从基础架构外部发送请求会捕获 SLI 中更多的整体请求路径。

缺点:

  • 借助合成请求大致估算用户体验,可能会有误导性(误报或漏报)。
  • 覆盖所有极端情况是困难的,可以转移到集成测试中。
  • 可靠性高的目标需要频繁探测才能进行准确测量。
  • 探测流量会消除真实流量。

实现方法和工具:

客户端插桩

生成 SLI 的方法

向用户与之交互的客户端添加可观察性功能,并将事件记录回跟踪 SLI 的服务基础结构。

注意事项

优点:

  • 提供最准确的用户体验衡量。
  • 可以量化第三方(例如 CDN 或付款服务机构)的可靠性。

缺点:

  • 客户端日志提取和处理延迟使这些 SLI 不适合触发操作响应。
  • SLI 衡量指标将包含许多可能不受直接控制的高度可变的因素。
  • 将插桩构建到客户端中可能涉及大量的工程工作。

实现方法和工具:

选择测量方法

理想情况下,您需要选择与客户的服务体验密切相关的测量方法,并且需要投入一定的精力。为了实现此理想情况,您可能需要组合使用上表中的方法。下面是一个建议的方法,按工作量增加的顺序列出,您可以慢慢实现:

  1. 使用应用服务器导出和基础架构指标。通常,您可以立即访问这些指标,并且它们会快速提供值。一些 APM 工具包含内置 SLO 工具。
  2. 使用客户端插桩。由于旧式系统通常缺少内置的最终用户客户端插桩,因此设置插桩可能需要大量投入。但是,如果您使用能提供客户端插桩的 APM 套件或前端框架,则可以快速了解客户的满意度。
  3. 使用日志处理。如果您无法实现服务器导出或客户端插桩,但存在日志,则可能会发现日志处理是最有价值的。另一种方法是合并导出和日志处理,将导出用作某些 SLI(例如即时可用性)的直接源,并将日志处理用于长期信号(例如提醒部分后面讨论的慢速消耗提醒)。
  4. 实现合成测试。在基本了解客户如何使用您的服务后,可以测试服务等级。例如,您可以用已知的良好数据为测试帐号播种,并对其进行查询。此测试可以帮助突出显示不容易观察到的故障模式,例如低流量服务。

设置目标

设置目标的最佳方式之一就是创建一个描述 SLO 以及如何开发它们的共享文档。当文档随着时间的推移在 SLO 上实现和迭代时,您的团队可以对其进行迭代。

我们建议企业所有者、产品所有者和高管查看本文档。这些利益相关方可以提供关于服务预期以及产品可靠性权衡的见解。

对于贵公司最重要的关键用户历程 (CUJ),以下是开发 SLO 的模板:

  1. 选择 SLI 规范(例如可用性或新鲜度)。
  2. 定义如何实现 SLI 规范。
  3. 仔细阅读您的计划,确保涵盖您的 CUJ。
  4. 根据过去的性能或业务需求设置 SLO。

CUJ 不应限制为单个服务,也不应限于单个开发团队或组织。如果您的用户依赖于数百种以 99.5% 的可用性运行的微服务,但没有人跟踪端到端的可用性,则您的客户可能不满意。

假设您有一个查询依赖于按顺序工作的五个服务:负载平衡器、前端、Mixer、后端和数据库。

如果每个组件的可用性均为 99.5%,则最坏情况下面向用户的可用性如下:

99.5% * 99.5% * 99.5% * 99.5% * 99.5% = 97.52%

这是最坏情况下面向用户的可用性,因为如果五个服务中的任何一个发生故障,整个系统将失败。只有在栈的所有层都必须立即可用来处理每个用户请求,而没有任何弹性因素(如中间重试、缓存或队列)的情况下,才会出现这种情况。在服务之间具有如此紧密耦合的系统是一种不合理的设计,并且与微服务模型不一致。

以零散的方式(逐个服务)根据分布式系统的 SLO 来衡量性能并不能准确地反映客户的体验,而且可能会导致过于敏感的解释。

相反,您应该根据前端的 SLO 来衡量性能,以了解用户的体验。如果用户的查询仍然成功,则用户不会关心组件服务是否失败,并导致系统自动成功重试查询。如果您共享了内部服务,则这些服务可以根据它们的 SLO 单独衡量性能,而面向用户的服务充当其客户。您应该单独处理这些 SLO。

使用智能重试、缓存和排队等弹性因素,可以在可用性较差的服务(例如 99.9%)之上构建高可用性服务(例如 99.99%)。

通常,任何具有统计工作知识的人都应能够阅读和理解您的 SLO,而无需了解您的基础服务或组织布局

SLO 工作表示例

开发 SLO 时,请记住执行以下操作:

  • 请确保您的 SLI 指定了一个事件、一个成功标准,以及您在哪里如何记录了成功或失败。
  • 根据良好事件的比例定义 SLI 规范。
  • 请确保您的 SLO 同时指定目标等级和测量时段。
  • 描述您方法的优点和缺点,以便相关方了解所涉及的权衡和微妙之处。

例如,请考虑以下 SLO 工作表。

CUJ:首页加载

SLI 类型:延迟时间

SLI 规范:在 100 毫秒内处理的首页请求的比例

SLI 实现

  • 从服务器日志的“延迟时间”列衡量的,100 毫秒内处理的首页请求所占的比例。(缺点:此衡量方法会遗漏无法到达后端的请求。)
  • 通过在运行在虚拟机上的浏览器中执行 JavaScript 的探测器测量,在不到 100 毫秒内处理的首页请求的比例。(优点和缺点:当请求无法到达网络时,这种测量方法会捕获错误,但可能错过只影响一部分用户的问题。)

SLO:过去 28 天内 99% 的首页请求在不到 100 毫秒内送达

SLO 和提醒

引入 SLO 等新可观察性系统的错误方法是使用该系统完全替换旧系统。相反,您应该将 SLO 视为一个补充系统。例如,我们建议您不要删除现有的提醒,而是将它们与这里介绍的 SLO 提醒并行运行。这种方法允许您发现哪些就有提醒是可预测的 SLO 提醒,哪些提醒与您的 SLO 提醒并行触发,以及哪些提醒永远不会触发。

SRE 的一个原则是根据症状而不是原因来提醒。SLO 本质上是对症状的测量。在用 SLO 提醒时,您可能会发现症状提醒与其他提醒一起触发。如果您发现旧有的基于原因的提醒触发时没有 SLO 或症状,则不妨完全关闭这些提醒、将它们转换为工单提醒或简单地登录以供以后参考。

如需详细了解此主题,请参阅 SRE 手册,第 5 章

SLO 消耗率

SLO 的消耗率衡量的是故障向用户暴露错误和消耗错误预算的速度。通过测量消耗率,您可以确定服务违反其 SLO 的时间。基于 SLO 消耗率的提醒是一种很有价值的方法。请记住,您的 SLO 基于时长,而后者可能会很长(数周甚至数月)。但是,目标是快速检测在违规实际发生之前,导致 SLO 违规的条件。

下表显示了在给定的时间间隔内,如果 100% 的请求都失败(假设每秒查询数 (QPS) 是恒定的),则超过目标所需的时间。例如,如果您在 30 天内测量了 99.9% 的SLO,那么您可以在这 30 天内承受 43.2 分钟的完全停机时间。例如,所有停机时间可能会一次性发生,也可以分散到多个事件。

目标 90 天 30 天 7 天 1 天
90% 9 天 3 天 16.8 小时 2.4 小时
99% 21.6 小时 7.2 小时 1.7 小时 14.4 分钟
99.9% 2.2 小时 43.2 分钟 10.1 分钟 1.4 分钟
99.99% 13 分钟 4.3 分钟 1 分钟 8.6 秒
99.999% 1.3 分钟 25.9 秒 6 秒 0.9 秒

在实践中,如果您想获得较高的成功率,就不能承受任何 100% 中断的突发事件。但是,许多分布式系统可以部分失败或平缓降级。即使在这种情况下,您仍想知道是否需要人工介入(即使发生的是部分故障也是如此),而 SLO 提醒为您提供了确定这一点的方法。

何时提醒

一个重要问题是,何时根据 SLO 消耗率采取行动。通常情况下,如果将在 24 小时内耗尽错误预算,那么“现在”就是找人解决问题的时候了

衡量故障率并不总是简单的。一系列小错误可能在当时看起来很可怕,但结果是短暂的,并且对 SLO 产生的影响无关紧要。同样,如果系统长时间轻微损坏,这些错误会累积为 SLO 违规。

理想情况下,您的团队会对这些信号做出反应,以便您在给定时间段内用完几乎所有的错误预算(而不是超出)。如果用得太多,则表示您违反了 SLO。如果用得太少,则承担的风险不够,或者让待命团队疲于应付。

您需要一种方法来确定系统何时崩溃到需要人工干预的程度。以下部分讨论了解决这个问题的一些方法。

快速消耗

SLO 消耗的一种类型是“快速 SLO 消耗”,因为它会快速消耗您的错误预算,并且需要您干预以避免 SLO 违规。

假设您的服务以每秒 1000 个查询 (QPS) 的速度正常运行,并且希望在一周七天的时间内保持 99% 的可用性。您的错误预算约为 600 万个允许错误(总请求数为 6 亿个)。例如,如果在错误预算耗尽之前还有 24 小时,则每秒的错误数限制为 70 个,或者是一小时内 252,000 个错误。这些参数基于一般规则:可呼叫事件至少占季度错误预算的 1%。

您可以选择在这一个小时过去之前检测这个错误率。例如,在观察 15 分钟每秒 70 个错误的速率后,您可能会决定呼叫待命工程师,如下图所示。

图片

理想情况下,这个问题在您用掉 24 小时预算中的一个小时之前就解决了。选择较短的时段(例如,一分钟)来检测此速率可能太容易出错。如果目标平均检测时间 (MTTD) 短于 15 分钟,则可以调整此数字。

慢速消耗

另一种消耗率是“慢速消耗”。假设您引入了一个错误,在第 5 天或第 6 天消耗掉了周错误预算,或者在第 2 周消耗掉了月预算?最佳应对方法是什么?

在这种情况下,您可能会引入一个“慢速 SLO 消耗”提醒,让您知道在提醒时段结束之前,您将消耗掉整个错误预算。当然,该提醒可能会返回很多误报。例如,可能经常存在这样一种情况,即错误发生的时间很短,但速度很快就会消耗掉您的错误预算。在这些情况下,该条件是误报,因为它只持续很短的时间,不会长期威胁您的错误预算。请记住,目标不是消除所有的错误来源;而是要“保持在可接受的范围内,不超出您的错误预算”。对于不会对错误预算构成合理威胁的事件,您希望避免提醒人工干预。

对于慢速消耗事件,我们建议您通知一个工单队列(而不是呼叫或发送电子邮件)。慢速消耗事件不是紧急事件,但是在预算到期之前需要人工干预。这些提醒不应以电子邮件的形式发送给团队列表,否则很快会被忽略。工单应该可跟踪、可分配和可转移。团队应该针对工单负载、完结率、可操作性和重复项创建报告。过多的、无法操作的工单是手动操作的好例子。

熟练地使用 SLO 提醒需要时间,并取决于团队的文化和期望值。记住,您可以随着时间的推移对 SLO 提醒进行微调。根据需要,您还可以有多种提醒方法和不同的提醒时段。

延迟提醒

除了可用性提醒之外,您还可以设置延迟提醒。借助延迟时间 SLO,您可以测量未达到延迟时间目标的请求的百分比。通过使用此模型,您可以使用与用于检测错误预算是快速还是慢速消耗的相同提醒模型。

正如前面提到的延迟时间中位数 SLO,有一半的请求可以不符合 SLO。换句话说,在您检测到对长期错误预算的影响之前,您的用户会面临数天的延迟。相反,服务应定义“尾延迟时间目标”和“典型延迟时间”目标。我们建议使用历史第 90 百分位数来定义典型延迟时间,并使用第 99 百分位数定义尾延迟时间。设置这些目标后,您可以根据希望计入每个延迟时间类别的请求数量,以及速度太慢的数量,来定义 SLO。此方法的概念与错误预算相同,应同等对待。因此,您可能会得到这样的结论:“90% 的请求将在典型延迟时间内处理,99.9% 的请求将在尾延迟时间目标范围内处理”。这些目标可确保大多数用户体验到您的典型延迟时间,并且仍允许您跟踪有多少请求比您的尾延迟时间目标慢。

一些服务可能有高度不同的预期运行时。例如,在数据存储区中读写数据可能会有显著不同的性能预期。您可以引入运行时性能存储分区,而不是枚举所有可能的期望,如下表所示。这种方法假定这些类型的请求是可识别的,并预先分类到各个存储分区中。不要期望动态地对请求进行分类。

面向用户的网站
存储分区 预期最大运行时
读取 1 秒
写入/更新 3 秒
数据处理系统
存储分区 预期最大运行时
10 秒
1 分钟
5 分钟
巨大 1 小时
特大 8 小时

通过测量当前的系统,您可以了解这些请求通常需要多长时间才能运行。以处理视频上传的系统为例。如果视频很长,处理时间应该会更长。我们可以使用视频长度(以秒为单位)来将这个工作分类到一个存储分区中,如下表所示。该表记录了一周内每个存储分区的请求数以及不同的运行时分布百分比。

视频时长 一周内测量的请求数 10% 90% 99.95%
0 - - -
190 万 864 毫秒 17 秒 86 秒
2500 万 1.8 秒 52 秒 9.6 分钟
巨大 430 万 2 秒 43 秒 23.8 分钟
特大 81000 36 秒 1.2 分钟 41 分钟

从这样的分析,您可以得出提醒的几个参数:

  • fast_typical:最多有 10% 的请求比这个时间快。如果有太多请求的速度超过了这个时间,那么您的目标可能是错误的,或者您的系统可能发生了变化。
  • slow_typical:至少 90% 的请求都比这个时间快。这个限制得出您的主延迟 SLO。这个参数指示大多数请求是否足够快。
  • slow_tail:最少 99.95% 的请求比这个时间快。此限制可确保不会有太多慢速请求。
  • deadline:用户 RPC 或后台处理超时并失败的点(通常已经硬编码到系统中的限制)。这些请求实际上不会很慢,但实际上会失败并报错,然后计入可用性 SLO。

定义存储分区的一项准则是将存储分区的 fast_typicalslow_typicalslow_tail 放在一个数量级内。这条准则可确保存储分区的宽度不会太大。我们建议您不要尝试防止存储分区之间的重叠或间隙。

存储分区 fast_typical slow_typical slow_tail deadline
100 毫秒 1 秒 10 秒 30 秒
600 毫秒 6 秒 60 秒(1 分钟) 300 秒
3 秒 30 秒 300 秒(5 分钟) 10 分钟
巨大 30 秒 6 分钟 60 分钟(1 小时) 3 小时
特大 5 分钟 50 分钟 500 分钟(8 小时) 12 小时

这会产生类似于 api.method: SMALL => [1s, 10s] 的规则。在这种情况下,SLO 跟踪系统将看到一个请求,确定其存储分区(可能通过分析其方法名称或 URI,并将名称与对照表进行比较),然后根据该请求的运行时更新统计信息。如果这个过程花了 700 毫秒,则在 slow_typical 目标范围内。如果花了 3 秒,则在 slow_tail 范围内。如果是 22 秒,则超出 slow_tail,但仍不是错误。

在用户满意度方面,您可以将缺少尾延迟时间视为等同于不可用。(即响应速度很慢,应被视为失败)。因此,我们建议您使用与可用性相同的百分比,例如:

所有请求的 99.95% 在 10 秒内得到满足。

典型延迟时间由您自己决定。Google 的一些团队认为 90% 是不错的目标。这与您的分析以及您为 slow_typical 选择时长的方式相关。例如:

所有请求的 90% 在 1 秒内得到处理。

建议的提醒

根据这些准则,下表包含一组 SLO 提醒基准。

SLO 测量时段 消耗率 操作

可用性,快速消耗

典型延迟时间

尾延迟时间

1 小时时段 不到 24 小时会违反 SLO 呼叫某人

可用性,慢速消耗

典型延迟时间,慢速消耗

尾延迟时间,慢速消耗

7 天时段 超过 24 小时才会违反 SLO 创建工单

SLO 提醒是需要时间来培养的技能。本部分中的时长是建议时长;您可以根据自身需求和精确程度来调整这些值。将提醒与测量时段或错误预算支出进行绑定可能会有所帮助,或者您可以在快速消耗和慢速消耗之间添加另一层提醒。

后续步骤