MTTR:衡量可用性的方法及其缺点

459 阅读9分钟

这种情况在所有复杂的网络应用中都会发生--你所操作的服务发生故障,用户受到影响。为了解决这些故障,并防止它们发生,软件团队需要有一些方法来衡量故障的 "严重程度"。

关于 "可用性 "的指标--即衡量一个网站有多少时间是 "正常 "的--已经存在了一段时间,但在谷歌的Tamás Hauer、Philipp Hoffmann、John Lunney、Dan Ardelean和Amer Diwan的论文《有意义的可用性》中,作者提出了一个新的指标,可以更准确地衡量可用性。

在论文中,作者讨论了目前衡量可用性的方法及其缺点,此外还解释了他们所提出的方法的价值。

我个人只接触过测量可用性的 "基于计数的 "指标(成功率),所以这篇论文是对其他方法的一个很好的介绍。它还很好地阐明了不同的应用在如何衡量可用性方面有不同的需求。

为什么我们使用什么指标很重要?

在这篇论文中,作者讨论了几个不同的衡量可用性的指标。但在深入讨论这些指标之前,作者描述了一个好的可用性指标的品质,然后可以用来评估一个指标是否适合手头的任务:

  • 有意义的。可用性指标应该与用户的实际体验相对应
  • 相称性。衡量标准的变化应该对应于用户体验的相应变化
  • 可操作性。衡量标准应该能够深入了解可用性低的原因。

现有技术:什么是 "可用性"?

作者在论文中首先介绍了现有的测量可用性的方法。

基于时间的可用性度量

衡量可用性的一个常见方法是使用服务运行时间的比率。这方面的标准公式是:

\\frac{MTTF}{MTTR + MTTF}

这里MTTF是 "平均故障时间",也就是服务在发生故障前运行了多长时间,MTTR是 "平均修复时间",也就是在故障期间需要多长时间来解决。

使用这个方法的主要问题是,它需要把时间段标记为故障或 "非故障",而在分布式系统中,故障通常是部分的。 正因为如此,这个指标不是很有意义,因为这里没有办法区分一个服务在90%的可用性和完全停机的时间。

基于计数的可用性度量

另一种衡量可用性的常用方法,也是我最熟悉的方法,就是使用 "成功率"。这是用成功的请求除以总请求来计算的。

success rate = frac{successful/request}{total/request}

与基于时间的指标不同,SR考虑到了部分中断。然而,对于某些服务来说,它仍然是一个不完美的指标:

  • 对于那些用户之间使用量变化很大的服务,这个指标可能会有偏差。在谷歌应用程序的情况下,活跃的用户可能比不太活跃的用户提出1000倍的请求。 如果一个活跃的用户的账户有问题,这些错误将在基于计数的指标中被过度代表。
  • 如果一项服务出现故障,这可能会导致不同的用户行为。例如,用户可能会放弃并减少请求,使成功率出现偏差。它也可能导致重试,进一步偏向于SR,尽管方向不同。
  • 这个指标完全没有考虑到时间。这使得它很难区分两种情况,一种是随着时间的推移不断出现错误,这可能不会对用户造成干扰,因为他们可以重试请求,另一种是一小时以上的中断,这是有干扰的。

鉴于基于计数和基于时间的可用性指标的缺点,这些指标都不符合上面定义的标准。

引入用户正常运行时间

作者随后介绍了一个他们称之为 "用户正常运行时间 "的指标,这个指标与上述两个指标不同,它既是有意义的,又是成比例的。

这个指标被计算为每个用户在应用上经历的 "正常运行时间 "的总和,除以在应用上花费的总时间。

user\\ uptime = frac{sum\_{u \\ in users} uptime(u)}{ sum\_{u \\ in users } uptime(u) + downtime(u)}

这与上面定义的基于时间的可用性指标的概念相似,只是在每个用户的基础上测量,这在分布式系统的背景下更合适。这是因为,衡量一个用户是在经历 "正常运行时间 "还是 "停机时间 "是可行的。

计算用户正常运行时间

计算这个指标的棘手之处在于将用户使用应用程序的时间标记为正常运行时间或停机时间。作者在这里提供了几个选项,每个选项都涉及分析用户请求之间的时间。对于一个给定的用户,两次成功请求之间的时间肯定是正常运行时间,而两次失败请求之间的时间肯定是停机时间。那么,一个成功的请求和一个失败的请求之间的时间呢?

作者认为,在这种情况下,你可以采取这样的方法:把一个失败的请求之前的所有时间算作成功的时间,或者把一个成功的请求 "之前 "的所有时间算作失败的时间,两者的结果是一样的。另一种方法是把时间分成两半,一半算作正常运行时间,另一半算作停机时间。

为什么这样做是成比例的、有意义的?

有意义的

与基于计数的成功率指标不同,这个指标是有意义的,因为它衡量的是应用程序对用户不可用的时间量。如果有一个中断,例如,客户行为的变化(发出大量的重试,或放弃),不会影响这个指标。

比例性

与基于时间的可用性指标不同,这个指标是与用户感知的可用性成比例的。在最初的基于时间的可用性指标中,没有说明有多少用户受到了中断的影响。例如,在基于时间的指标中,高峰时段的中断与使用应用程序的用户较少时的中断没有区别,但在用户正常运行时间指标中会有区别。

性能

作者做了一个实验,比较了成功率(基于计数的)指标和用户使用时间指标。在这个实验中,他们运行了一个小时的流量,并在15分钟内模拟了一次停电。失败的请求将导致重试。

用户正常运行时间指标准确地测量出系统有75%的正常运行时间,而成功率的结果是一个较低的数字,表明这个数字的准确性更高。

让它成为可操作的:窗口用户正常运行时间

前面提到的基于时间和基于数量的可用性指标的一个问题是,在一个较长的时间段内,很难区分故障,例如,不断出现的错误,和中断(即每个季度有6小时的中断)。用户使用时间也不能解决这个问题,因为到最后,我们仍然只有一个单一的数字来评估过去N天的可用性。

为了解决这个问题,作者提出了 "窗口化用户正常运行时间"。窗口化的用户正常运行时间是指,在给定的一系列时间长度中,在较长的时间段内这些时间长度中最差的一个。 因此,给定的时间长度如 "1分钟"、"1小时"、"1天 "等,一个季度的窗口化用户正常运行时间将给我们提供该季度内最差的一分钟用户正常运行时间、最差的小时和最差的一天。

因为这个指标在较小的时间尺度上提供了洞察力,这使得使用这个指标的团队可以挖掘出特别糟糕的可用性窗口,并在长期的基础上,实际跟踪团队是否在消除较高影响的故障方面变得更好。特别是因为在作者讨论的实施中,他们保留了每个时间段中最糟糕的窗口映射,他们可以挖掘并查看当时发生了什么。

应用

作者描述了谷歌是如何采用这个新指标的,他们将其与成功率一起使用,并描述了几个例子,说明它是如何让他们更好地了解其系统的。

一个坏客户

在其中一个例子中,作者描述了这样一种情况:由于一个重度客户的行为异常,整个服务的成功率大幅下降。而用户使用时间指标却没有,因为它没有受到与成功率相同的偏差影响。从这种分歧中,作者能够确定这种SR下降可能是由于少数客户造成的,然后能够挖掘出他们拥有的专门针对重度用户的图表。

两个事件的案例

在另一种情况下,谷歌应用程序的成功率和用户使用时间都下降了相当长的时间。这最初表明这种性能下降的原因很单一。然而,通过将时间排在图表上,用户使用时间成功率之前就恢复了。这两个指标的分歧表明,可能有第二个原因需要调查。

进一步的问题

读完这篇论文后,我仍然好奇的主要是了解更多关于切换到窗口化的用户-时间实际上推动了谷歌工程团队的不同行为的案例。

虽然从上面描述的事件中可以看出,新指标的洞察力是有用的,但我很好奇的是,拥有窗口化的数据是否真的促使谷歌将项目放在优先位置,否则他们不会这样做。

结论

总的来说,这是一篇非常有趣的论文。它绝对改变了我对如何衡量可用性的看法。成功率(基于计数)和MTTR/MTTF(基于时间)指标都是不完美的,可能会有偏差,所以重要的是要从你的应用角度考虑你真正关心的是什么来衡量。这需要考虑到应用程序的行为,客户在中断期间的行为,以及关于你的特定应用程序的其他信息。