拥抱风险
文摘
2024-09-07 08:57
四川
大多数人会认为只有100%的服务才是可靠的。事实证明,超过一定值后,再提高可靠性对于一项服务(和它的用户)来说,结果可能会更差而不是更好!极端的可靠性会带来成本的大幅提升:过分追求稳定性限制了新功能的开发速度和将产品交付给用户的速度,并且很大程度地增加了成本,这反过来又减少了一个团队可以提供的新功能的数量。此外,用户通常不会注意到一项服务在高可靠性和极端可靠性之间的差异,因为用户体验主要是受较不可靠的组件主导,例如手机移动网络或者他们正在使用的设备。简单地说,用户在一个有着99%可靠性的智能手机上是不能分辨出99.99%和99.999%的服务可靠性的区别的!度量服务风险
标准做法是通过一个客观的指标来体现一个待优化的系统属性。对于大多数服务而言,最直接的能够代表风险承受能力的指标就是对于计划外停机时间的可接受水平。计划外停机时间是由服务预期的可用性水平所体现的,通常我们愿意用提供的“9”系列的数字来体现,比如可用性为99.9%、99.99%或99.999%。每个额外的“9”都对应一个向100%可用性的数量级上的提高。对于服务系统而言,这个指标通常是基于系统正常运行时间比例的计算得出的。可用性=系统正常运行时间/(系统正常运行时间+停机时间)使用这个公式,我们可以计算出一年内可接受的停机时间,从而可以使可用性达到预期目标。举例来说,一个可用性目标为99.99%的系统最多在一年中停机52.56分钟,就可以达到预计的可用性目标。基于时间的可用性通常是毫无意义的。因为我们需要着眼全球范围内的分布式服务。Google所采用的故障隔离手段使得我们能够保证在任何时候、任何地方对于一个给定的服务,总是可以处理一定的用户流量。(也就是说,我们随时都是部分“在线”的)。因此,我们通过请求成功率来定义服务可用性。公式3-2体现了这个基于产量的指标是怎样通过滚动窗口计算出来的(比如,一天内成功请求的比率)。 例如,一个每天可用性目标为99.99%的系统,一天要接受2.5M个请求。它每天出现少于250个错误即可达到预计的可用性目标。 在一个典型的应用中,不是所有的请求都是平等的:一个新的用户注册请求失败和一个后台调用的新邮件的轮询请求失败是不同的。然而在许多情况下,从终端用户的角度来看,通过计算全部请求成功率是一个对于计划外停机时间的合理估计。 使用请求成功率指标量化计划外停机时间使得这种指标更适合在不直接服务终端用户的系统中使用。大多数非服务性的系统(比如,批处理、流水线、存储服务以及交易系统等)对成功和非成功的工作单元有明确的定义。事实上,虽然在本章中讨论的系统基本上都是有关消费者类型和基础设施服务类型的系统,但是同样的原则也基本上适用于非服务型系统。 例如,一个批处理进程通过提取、转换,并将客户数据库中的一位客户的数据内容插入数据仓库中,以便进行定期的进一步分析。通过使用某条记录处理成功和处理不成功来定义请求成功率,我们能计算出一个有效的可用性指标,尽管事实上该批处理系统并不是持续运行的。 通常,我们会为一项服务设定季度性的可用性目标,每周甚至每天对性能进行跟踪。我们通过寻找、跟踪和调整重要的、不可避免的偏差来使服务达到一个高层次的可用性目标。服务的风险容忍度
如何辨别服务的风险容忍度?在一个正式的环境或安全关键的系统中,服务的风险容忍度通常是直接根据基本产品或服务的定义建立的。在 Google内部,服务风险容忍度往往定义得没有那么清楚。 为了辨别服务的风险容忍度,SRE必须与产品负责人一起努力,将一组商业目标转化为明确的可以实现的工程目标。这些商业目标会直接影响所提供服务的性能和可靠性目标。在实践中,这种转化说起来比做起来容易得多。消费者类型的服务往往有明确的产品负责人,而对于基础设施服务来说,拥有类似的产品所有权结构是很少见的(例如,存储系统或者通用的HTTP缓存层)。接下来,我们会分别讨论消费者服务和基础设施服务。辨别消费者服务的风险容忍度
我们的消费者服务通常会有一个对应的产品团队,是该服务的商业所有者。比如说,Search、Google Maps和Google Docs,它们每一个都有自己的产品经理。这些产品经理负责了解用户和业务,在市场上塑造产品的定位。存在产品团队时,我们能够更好地通过这个团队来讨论服务的可靠性要求。在没有专门的产品团队的情况下,建立系统的工程师们经常在知情或不知情的情况下扮演了这个角色。 评价服务风险容忍度时,有许多需要考虑的因素。如下所示: ● 我们如何使用服务成本来帮助在风险曲线上定位这个服务?可用性目标
对于某个Google服务而言,服务的可用性目标通常取决于它提供的功能,以及这项服务在市场上是如何定位的。下面列出了要考虑的一些问题: ● 这项服务是否直接关系到收入(我们的收入或我们的客户的收入)? ● 如果市场上有竞争对手,那些竞争对手提供的服务水平如何? 例如 Google Apps for Work,这个服务的主要用户是企业类用户,包括大型企业和中小企业。这些企业依靠Google应用程序提供的办公类型的服务(例如Gmail、Calendar、Drive和Docs)让员工进行日常工作。另一方面,一个Google Apps for Work服务的中断不仅会影响Google本身,也会影响到那些在业务上非常依赖于我们的企业。对于这类服务,我们可能会设置季度性的外部可用性目标为99.9%。同时,我们会设置一个更高的内部可用性目标,以及签署一份如果我们未能达到外部目标的处罚性协议。 YouTube则需要截然不同的考虑。当Google收购YouTube后,我们需要为该网站提供一个更恰当的可用性目标。2006年,YouTube比当时的Google更加专注于消费者,并且当时处于一个与Google 非常不同的企业生命周期阶段。尽管当时YouTube已经有了一个很出色的产品,但它仍然在不断变化和快速发展着。因此,我们为YouTube设定了一个相比我们企业的产品更低的可用性目标,因为快速发展更加重要。故障的类型
对于一项给定的服务的故障预期是另一个需要重点考虑的因素。我们的业务对于服务的停机时间的容忍程度有多高?持续的低故障率或者偶尔发生的全网中断哪一个会更糟糕?这两种类型的故障可能会导致绝对数量上完全相同的错误被返回,但可能对于业务的影响相差很大。 下面这个例子说明了一个提供私人信息的系统中自然发生的完全和部分服务中断的区别。假设有一个联系人管理应用程序,一种情况是导致用户头像显示失败的间歇性故障,另一种情况是将A用户的私人联系列表显示给B用户的故障。第一种情况显然是一个糟糕的用户体验,SRE会努力去快速地解决这个问题。然而,在第二种情况下,暴露私人数据的风险可能会破坏基本的用户信任。因此,在第二种情况下,在进行调试和事后的数据清理时,完全停止该服务更加恰当。对于Google提供的其他服务,有时候,我们可以接受计划内的常规的服务中断。几年前,Ads前端曾经就是这样的一种服务。它是广告商和网站创建者用来建立、配置、运行和监控他们的广告活动的服务。因为这项工作大部分发生在正常工作时间内,我们认为维修窗口中发生的偶然的、正常的、计划之中的故障是可以接受的,并且我们把这些故障看作计划内停机时间,而不是计划外停机时间。 决定一项服务的合理可用性目标时,成本是很重要的考虑因素。广告服务就能很好地体现出这种取舍,因为成功与失败直接通过赢利和亏损体现。在为每一项服务确定可用性目标时,可以考虑如下的问题: ● 构建和运维可用性再多一个“9”的系统,收益会增加多少? ● 额外的收入是否能够抵消为了达到这一可靠性水平所付出的成本?为了使这个权衡等式更精确,假设一项业务中每一个请求的价值是一样的,考虑如下的成本与收益: 改进可用性后的价值:100万美元×0.0009=900美元 在这种情况下,如果可用性提高一个“9”的成本不到900美元,这就是合理的投资。但是,如果成本超过900美元,那么成本将超过预计增加的收入。 当我们无法简单地解释可靠性和收入的关系时,可能会更难设置这些目标。这时,考虑在互联网中ISP的背景误差率可能是个不错的实用策略。如果从最终用户的角度测算故障,那么让服务的误差率低于背景误差率就是可能的。这些误差将归入给定用户的互联网链路的噪声当中。虽然ISP和各种应用协议之间差距很大(比如,TCP vs.UDP、IPv4 vs.IPv6),但是我们测算的ISP的背景误差率基本在0.01%和1%之间。往期系列文章
阿里微服务质量保障系列:异步通信模式以及测试分析
阿里微服务质量保障系列:微服务知多少
阿里微服务质量保障系列:研发流程知多少
阿里微服务质量保障系列:研发环境知多少
阿里微服务质量保障系列:阿里变更三板斧
阿里微服务质量保障系列:故障演练
阿里微服务质量保障系列:研发模式&发布策略
阿里微服务质量保障系列:性能监控
阿里微服务质量保障系列:性能监控最佳实践
阿里微服务质量保障系列:基于全链路的测试分析实践
阿里微服务质量保障系列: 服务虚拟化技术