以可靠的方式运维大型分布式系统:我在Uber学到的实践 - Gergely Orosz

19-07-18 banq
                   

在过去的几年里,我一直在构建和运营一个大型分布式系统:优步支付系统。在此期间,我学到了很多关于分布式架构概念的知识,并亲眼目睹了高负载和高可用性系统不仅要构建还要运行的挑战。构建系统本身是一项有趣的工作。规划系统如何处理10x / 100x流量的增加,确保数据持久,面对硬件故障处理等等,这些都需要智慧。不管怎样,运维大型分布式系统对我来说是一次令人大开眼界的体验。

系统越大,墨菲的“什么可能出错,就会出错”的定律就越会体现。对于频繁部署情况、以及许多开发人员部署代码时,还有涉及多个数据中心以及系统被大量用户全局使用时,这种出错概率越大。在过去的几年里,我经历过各种各样的系统故障,其中很多让我感到惊讶。有些都来自可预测的事情,有些如硬件故障或生产中无名的错误,包括连接数据中心的网络电缆或同时发生的多个级联故障。我经历了数十次中断,系统的某些部分无法正常工作,从而导致巨大的业务影响。

这篇文章是我在Uber工作时可以有效地运维大型系统的实践的集合。我的经验并不是独一无二的 - 在类似规模的系统上工作的人也经历了类似的旅程。我与Google,Facebook和Netflix的工程师进行了交谈,他们分享了类似的经验和解决方案。这里列出的许多想法和流程应该适用于类似规模的系统,无论是在自己的数据中心(如Uber大多数情况下)上运行,还是在云上运行(Uber 有时可以扩展到)。但是,对于规模较小或较少关键任务的系统而言,这些做法可能过于苛刻。

banq注:下图是Uber的微服务图:

监控

要知道系统是否健康,我们需要回答“我的系统是否正常工作”的问题?为此,收集系统关键部分的数据至关重要。对于在多台计算机和数据中心上运行多个服务的分布式系统,可能很难确定哪些关键事项确实需要监控。

1. 基础设施健康监测 如果一个或多个计算机/虚拟机过载,则分布式系统的某些部分可能会降级。服务运行的计算机的运行状况统计信息 - CPU利用率,内存使用情况 - 是值得监控的基础知识。有些平台可以开箱即用地处理这种监控和自动扩展实例。在优步,我们拥有一支优秀的核心基础设施团队,提供开箱即用的基础设施监控和警报。无论如何实现,都要知道什么时候事情是红色的,或者服务的基础设施是必须的信息。

2.服务运行状况监控:流量,错误,延迟。这是用于回答问题“这个后端服务是否健康?”。观察访问端点的请求流量、错误率和端点延迟等事项都可以提供有关服务健康状况的有价值信息。我更喜欢将这些都显示在仪表板上。在构建新服务时,通过使用正确的HTTP响应映射并监视相关代码可以对系统有很多了解。因此,确保客户端错误能返回4XX,以及如果服务器错误则返回5xx,这种监控易于构建且易于解释。

监测延迟值得再考虑一下。对于生产服务,目标是让大多数最终用户获得良好的体验。事实证明,测量平均延迟并不是一个很好的指标,因为这个平均值可以隐藏一小部分高延迟请求。测量p95,p99或p999 - 第95百分位,第99百分位或第99.9百分位的请求所经历的延迟 - 是一个更好的指标。这些数字有助于回答诸如“99%的人的请求有多快?”之类的问题。(p99)或“至少1000人中有一人要求的速度有多慢?” (p999)。

对于那些对这个主题更感兴趣的人,这篇延迟入门文章很好进一步阅读。

围绕监控和可观察性有很多深度。值得一读的两个资源是Google的SRE书和关于分布式系统监控的四个黄金信号的部分。他们建议,如果您只能测量面向用户的系统的四个指标,请关注流量,错误,延迟和饱和度。

简短的阅读是来自Cindy Sridharan分布式系统可观察性电子书,它涉及其他有用的工具,如事件日志,指标和跟踪最佳实践。

3. 业务指标监控。虽然监控服务告诉我们很多关于服务看起来如何正常工作,但它没有说明它是否按预期工作,是否“照常营业”。在支付系统,一个关键问题是,“人们可以使用特定的支付方式进行支付业务吗?”。识别服务启用和监控这些业务事件的业务事件是最重要的监控步骤之一。

业务指标监控是我的团队在遭到因我们无法检测到的中断而受到伤害后建立的。我们所有的服务看起来都在正常运行,但关键功能却在服务中出现问题。这种监控对我们的组织和领域来说非常有用。因此,我们必须在Uber可观察性技术堆栈的基础上,为自己定制这种类型的监控做了大量的思考和努力。

Oncall,异常检测和警报

监控是人们检查系统当前状态的一个很好的工具。但它实际上只是一个自动检测出现问题的绊脚石,并提出人们可以采取行动的警报。

Oncall本身就是一个广泛的话题 - “增量”杂志在On-Call问题上做了很多方面的工作。我强烈希望将oncall视为“你建立它,拥有它”思想的后续行动。建立服务的团队拥有他们,也拥有oncall。我的团队为我们建立的支付服务拥有oncall。因此,每当警报触发时,呼叫工程师都会响应并查看详细信息。但是我们如何从监控到警报呢?

从监控数据中检测异常是一项艰巨的挑战,也是机器学习可以发挥作用的领域。有许多第三方服务可以提供异常检测。我的团队再次幸运,我们有一个内部机器学习团队,他们为Uber用例量身定制了他们的解决方案。纽约的Observability团队撰写了一篇有关异常检测如何在Uber工作的有用文章。从我的团队的角度来看,我们将监控数据推送到该团队的管道,并获得各自置信水平的警报。然后我们决定是否应该寻找工程师。

何时发出警报是一个有趣的问题。警报太少可能意味着缺少有影响力的中断。太多可能会导致不眠之夜并将人们烧掉。在调整警报系统时,跟踪和分类警报以及测量信噪比至关重要。通过警报和标记它们是否可操作,然后采取措施减少不可操作的警报是实现可持续的随叫随到轮换的一个很好的一步。

位于维尔纽斯的Uber开发人员工具团队构建了整齐的随叫随到的工具,我们用它来注释警报并可视化上传调度。我们的团队每周都会对最后一次呼叫班次进行审查,分析痛点并花一些时间来改善呼叫体验,一周又一周。

停电和事故管理流程

想象一下:你是本周的工程师。寻呼机警报会在半夜唤醒你。您调查是否发生了生产中断。哦,哦。似乎系统的一部分已关闭。怎么办?监控和警报变得非常真实。

对于小型系统而言,停电可能不是那么重要,因为呼叫工程师可以了解正在发生的事情以及原因。它们通常很容易理解并且易于缓解。对于具有多个(微)服务的复杂系统,许多工程师将代码推向生产,仅仅为了确定潜在问题发生的位置就具有足够的挑战性。有一些标准流程可以帮助解决这个问题,这会带来巨大的变化。

附加到警报的Runbook,描述简单的缓解步骤是第一道防线。对于具有良好Runbook的团队,如果工程师oncall不深入了解系统,则很少会出现问题。Runbook需要随时更新,更新并重新处理新类型的缓解措施。

只要有多个团队部署服务,就必须在整个组织内进行通信中断:在我工作的环境中,成千上万的工程师在他们认为合适的时候将他们工作的服务部署到生产中,从而导致每小时数百次部署。在一个服务上看似无关的部署可能会影响另一个服务。在这里,标准化的中断广播和通信渠道有很大的不同。我有多个案例,警报不像我以前见过的任何事情 - 并且意识到其他团队中的其他人也看到了同样奇怪的事情。作为中断聊天组的中断,我们确定了导致中断的服务,并迅速缓解了问题。我们这样做的速度要快得多,作为一个团体比我们自己做的任何人都要快。

 当下是缓解,明天才调查。在宕机期间,我常常想要解决出错的“肾上腺素冲动”。通常根本原因是代码部署不好,代码更改中存在明显的错误。在过去,我会跳过修复错误,推送修复程序并关闭停止而不仅仅是回滚代码更改。但是,在宕机中解决造成宕机的根本原因是一个可怕的想法,通过前瞻性修复,几乎没有什么可以收获,单会有很多损失。必须快速完成新的修复,因此必须在生产中进行测试。搞清楚哪个是在现有错误之上引入第二个错误,只需先专注于减轻当前宕机压力,同时抵制对造成宕机的根本原因的调查和修复的冲动。详细的调查可以等到下一个工作日。

事后审查与持续改进的文化

正确完成的事后处理是强大系统的基石。是否可能花费大量精力进行后续工作,停止产品工作以进行系统级修复?优步事后模板随着时间的推移不断发展,包括事件摘要,影响概述,事件发展时间表,根本原因分析,经验教训以及详细的后续项目清单。

良好的事后调查深入挖掘根本原因并提出改进措施,以便更快地预防,检测或减轻所有类似的中断。深入挖掘“5 Whys”探索技术,深入挖掘,得出更有意义的结论。举个例子:

  • 问题为什么会发生?- >作为代码的一部分提交了一个错误。
  • 为什么Bug不会被其他人抓住?- >代码审查员没有注意到代码更改可能导致此类问题。
  • 为什么我们只依赖代码审查员来捕获这个bug?--->因为我们没有针对此用例的自动测试。
  • “为什么我们不对这个用例进行自动化测试?” - >因为没有测试帐户很难测试。
  • 为什么我们没有测试帐户? - >因为这个系统还不支持它们
  • 结论:这个问题指出了没有测试帐户的系统性问题。建议为系统添加测试帐户支持。在此之后,为所有未来类似的代码更改编写自动化测试。

事件审查是事后审查的重要附带工具。虽然许多团队在事后进行彻底的工作,但其他团队可以从额外的投入中受益,并受到预防性改进的挑战。团队也必须承担责任并有权执行他们提出的系统级改进。

对于那些认真对待可靠性的组织而言,最严重的事件会得到经验丰富的工程师的审核和挑战。还应该提供组织级工程管理,以提供授权以完成修复 - 特别是当这些修复非常耗时并阻止其他工作时。强大的系统不是一夜之间构建的:它们是通过连续迭代构建的。在从事故中学习之后,来自组织范围内的持续改进文化的迭代。

故障转移演习,计划停机和容量规划以及Blackbox测试

有一些常规活动需要大量投资,但对于保持大型分布式系统的正常运行至关重要。这些是我第一次在优步遇到的概念 - 在以前的公司,我们不需要使用这些,因为我们的规模和基础设施没有促使我们这样做。

数据中心故障转移机制是我认为是沉闷的东西,直到我观察到它们中的一些好处。

我观察到的最常见的故障情况是,在故障转移的情况下,新数据中心中没有足够资源来处理全局流量的服务。想象一下,ServiceA和ServiceB分别从两个数据中心运行。让我们假设资源的利用率为60% - 每个DC中运行数十或数百个VM - 并且警报设置为触发70%。现在让我们进行故障转移,将所有流量从DataCenterA引导到DataCenterB。如果没有配置新机器,DataCenterB突然无法应对负载。供应可能需要足够长的时间才能使请求堆积起来并开始下降。此阻塞可能开始影响其他服务,导致其他系统上的级联故障,甚至不是此故障转移的一部分。

其他常见故障情况涉及路由级别问题,网络容量问题或背压故障点。数据中心故障转移是任何可靠的分布式系统应该能够执行的演习,而不会对用户造成任何影响。我强调应该 - 这次演习是测试分布式系统网络可靠性的最有用的练习之一。

计划的服务停机时间是测试整个系统弹性的绝佳方法。这些也是发现特定系统的隐藏依赖关系或不适当/意外使用的好方法。虽然可以使用面向客户端且几乎没有已知依赖关系的服务相对容易地完成此练习,但对于需要高正常运行时间和/或许多其他系统所依赖的关键系统来说,这样做并不那么简单。但是有一天这个关键系统将无法使用时会发生什么?最好通过受控挖掘验证答案,所有团队都意识到并准备就绪,以防止意外停机。

黑盒测试是一种测量系统正确性的方法,它接近最终用户看到的条件。这种类型的测试类似于端到端测试。除了对大多数产品而言,进行适当的黑盒测试需要他们自己的投资。关键用户流程和最常见的面向用户的测试场景是很好的“黑盒子可测试”:以可以随时触发它们的方式执行此操作,以检查系统是否正常工作。

以Uber为例,一个明显的黑盒测试是检查乘客流量是否在城市一级运行。也就是说,特定城市的乘客是否可以请求优步服务,搭乘驾驶员的车?一旦此方案自动化,就可以定期运行此测试,模拟不同的城市。拥有强大的黑盒测试系统可以更轻松地验证系统(或系统的某些部分)是否正常工作。它对故障转移练习也有很大帮助:获得故障转移反馈的最快方法是运行黑盒测试。

容量规划对于大型分布式系统同样重要。从大到大,我的意思是计算和存储的成本每月数十或数十万美元。在这种规模下,具有固定数量的部署可能比使用自扩展云解决方案更便宜。至少,固定部署应该处理“一切照常”的流量,并为峰值负载进行自动缩放。但是下个月应该运行的最小实例数是多少?接下来的三个月?下一年?

预测成熟且具有良好历史数据的系统的未来流量模式并不困难。然而,对于预算,选择供应商或锁定云提供商的折扣都很重要。如果您的服务有大笔账单而您没有考虑容量规划,那么您就错过了一种简单的方法来降低和控制成本。

SLO,SLA和报告他们

SL0代表服务水平目标 - 系统可用性的数字目标。对于每个独立服务,定义服务级SLO(如容量,延迟,准确性和可用性目标)都是很好的做法。然后,这些SLO可用作警报的触发器。示例服务级SLO可能如下所示:

容量 最小吞吐量    500 req / sec
   最大预期吞吐量  2,500 req / sec
延迟 预期的中响应时间  50-90ms
    预期的p99响应时间 500-800ms
准确性 最大错误率    0.5%
可用性 保证正常运行时间 99.9%​​​​​​​

业务级SLO或功能SLO是服务之上的抽象。它们将涵盖面向用户或面向业务的指标。例如,业务级SLO可能是这样的:期望在旅行完成后1分钟内发送99.99%的电子邮件收据。此SLO可能映射到服务级别的SLO(例如,支付和电子邮件收据系统的延迟),或者可能需要以不同方式进行测量。

SLA - 服务水平协议 - 是服务提供商和服务消费者之间更广泛的协议。通常,多个SLO构成SLA。例如,99.99%可用的支付系统可以是SLA,它可以分解为每个支持系统的特定SLO。

在定义SLO之后,下一步是测量这些并报告它们。自动监控和报告SLA和SLO通常是一个复杂的项目,很容易为工程团队和业务确定优先级。工程团队不会那么感兴趣,他们已经有各种级别的监控来实时检测中断。另一方面,该业务宁愿优先提供功能而不是投资于不会对业务产生直接影响的复杂项目。

这将我们带到下一个主题:运营大型分布式系统的组织迟早需要投入专门的人员来确保这些系统的可靠性。我们来谈谈网站可靠性工程团队。

SRE作为独立团队

网站可靠性工程起源于Google,从2003年左右开始 - 至今已有超过1,500名SRE工程师。随着生产环境的运营变得越来越复杂,需要越来越多的自动化,这项工作很快就会成为一项全职工作。当公司认识到他们的工程师在生产自动化中接近全职工作时,情况会有所不同:这些系统越关键,他们的失败越多,发生的时间就越早。

快速发展的科技公司通常会在早期建立一个SRE团队,他们会制定自己的路线图。在优步,SRE团队成立于2015年,其使命是随着时间的推移管理系统复杂性。其他公司可能会在创建专用基础架构团队时开始组建这样的团队。当一家公司发展到可靠性时,跨团队的工作需要花费不少工程师的时间,现在是时候为此建立一个专门的团队。

有了SRE团队,该团队可以让所有工程师更轻松地保持大型分布式系统的运营。SRE团队可能拥有标准的监控和警报工具。他们可能购买或构建oncall工具,并且是oncall最佳实践的goto团队。它们可以促进事件审查和构建系统,以便更容易地检测,减轻和预防中断。它们肯定有助于故障转移演习,通常推动黑盒测试,并参与容量规划。他们推动选择,定制或构建标准工具,以定义和衡量SLO并对其进行报告。

鉴于公司有不同的痛苦领域他们寻求解决SRE,SRE组织在各公司之间是不同的。该名称通常也是其他名称:它可以称为运维,平台工程或基础结构。谷歌发布了两本关于网站可靠性的必读书籍,这些书籍是免费提供的,并且是深入了解SRE的绝佳读物。

作为持续投资的可靠性

在构建任何产品时,构建第一个版本只是一个开始。在v1之后,将在迭代中添加新功能。如果产品成功并带来业务成果,那么工作就会继续。

分布式系统具有类似的生命周期,除了它们需要更多投资,不仅仅是新功能,而是要跟上扩展规模。随着系统开始承受更多负载,存储更多数据,有更多工程师在其上工作,需要持续关注以保持平稳运行。许多人第一次构建分布式系统时假设这个系统就像一辆汽车:一旦建成,它每隔几个月就只需要必要的维护。这种比较无法进一步说明这些系统如何运作。

我喜欢考虑运行分布式系统的努力,类似于运营像医院这样的大型组织。为了确保医院运作良好,需要持续验证和检查(监测,警报,黑盒测试)。新员工和设备(新工程师和新服务)需要始终加入。随着人数和服务数量的增长,旧的做事方式变得低效:就像农村的一个小诊所与大都市的大医院不同。提出更有效的工作方式成为一项全职工作,衡量和报告效率变得非常重要。就像大医院有更多的支持人员,如财务,人力资源或安全; 运营较大的分布式系统同样依赖于支持团队,如基础设施和SRE。

对于运行可靠分布式系统的团队,组织需要持续投资于这些系统的运行以及它们所构建的平台。

进一步推荐阅读

虽然这篇文章的内容很冗长,但它仍然只涉及表面。为了深入了解操作分布式系统,我建议使用以下资源:

图书

  • Google SRE Book - 来自Google的优秀免费图书。该监控分布式系统包机是为这个职位尤为重要。
  • 分布式系统观测辛迪Sridharan说,另一个优秀且免费的书监测分布式系统大点。
  • Martin Kleppmann博士[url=https://www.amazon.com/gp/product/1449373321/ref=as_li_tl?ie=UTF8&tag=gregdoesit-20&camp=1789&creative=9325&linkCode=as2&creativeASIN=1449373321&linkId=adc1dc62fd3463b173cfd92dbe4ed821]设计数据密集型应用程序[/url] - 迄今为止我发现的关于分布式系统概念的最实用的书籍。但是,本书并没有涉及帖子中讨论的操作方面。

在线资源

请参阅有关Hacker News的这篇文章的评论

                   

1
sinaID78676
2019-07-20 20:52

原来是Uber大佬,失敬失敬~