谷歌如何确保自己的服务连续运行,并且看起来似乎永远不会出错?如果你也纳闷过这个问题,谷歌存储 SRE 总监 Melissa Binde 在 GCP NEXT 2016 活动中通过一场名为谷歌如何通过全球级工程打造全球级基础架构的演讲向我们揭示了其中的诀窍。
Melissa 的演讲虽然简短但却充满智慧和干货,让人觉得如果自己的服务停机了肯定会想要向 Melissa 寻求帮助。
哦,那么 SRE 是什么?SRE 代表 _Site Reliability Engineering(站点可靠性工程)_,不过具体的定义似乎有些难以理解,这种问题的答案有些类似于当你询问“道教”的定义时获得的那种答案。SRE 更像是一种过程而非一种具体的实体,谷歌副总裁 Ben Sloss 对 SRE 的定义是:
当软件工程师需要承担所谓的“运维”这项任务后所发生的事。
先好好想想这句话吧。
抛开别的不谈,有一件事是很明确的:SRE 是生产任务的守护者,SRE 是客户体验的守护者,无论对谷歌或 GCP 均是如此。
我对此次演讲的一些重点摘录如下:
- 连续运行时间和功能的对抗所造成的毁灭性动机。开发者想要推出新功能,但为了保障系统连续运行时间,系统管理员不希望推出任何新功能。这两个角色之间存在一种与生俱来的紧张局面,SRE 应运而生。
- 误差预算(Error budget)。这种想法认为故障是不可避免的,不是什么坏事。服务连续运行时间到底是 100% 或 99.99%,对用户来说没有任何差异,因此错误也是可以容忍的。这样便可缓解开发和运维人员之间的紧张局面。只要留有误差预算就可以随时推出新功能,并且运维端也不会责怪你。
- 目标在于立刻还原服务,排错工作稍后再做。这意味着你需要在服务成功还原之后,再通过各种日志和工具进行调试。因为一些原因这一点在早前一篇文章中简单提过,当时这个观点源自谷歌 GRE 的一场演讲:备份无用,你真正应该关心的是服务的还原。
- 不要厌倦寻呼的哲学。收到寻呼意味着遇到了新的、有趣的问题。你肯定不想 SRE 整天忙于处理各种反复出现的相同问题,这种事应该交给机器人。
这次演讲还涉及其他一些有趣的话题,例如:SRE 的组织结构是如何安排的?如何招聘专注于生产任务、确保生产系统流畅运行的开发者?如何让谷歌内部重视这个团队的价值?如何帮助团队更好地通过沟通和数据来解决分歧,而不是通过各种主张或是权利的攫取?
一起来看看吧。谷歌是这样通过全球级工程打造全球级基础架构的…
维持平衡:持续运行时间与功能,动机的对立造成破坏性后果
站点连续运行时间可让系统管理员获益。站点连续运行时可以获得源源不断的访客,并能通过他们赚钱。
新功能可以让开发者获益。发布新功能可以吸引访客,并能通过他们赚钱。
生产冻结(Production freeze)其实是指新功能的冻结,通常可对应至连续运行时间的延长。
开发者和系统管理员之间存在与生俱来的紧张关系。开发者可从新功能的发布中获益,系统管理员可从连续运行时间中获益。
因此系统管理员阻止新功能发布可获得回报,而开发者如果突破系统管理员的阻止将能获得回报。
开发者会通过一种叫做 Beta(测试)的方式让新功能尽早发布。
系统管理员会通过一种叫做发布审核(Launch review)的方式减缓新功能发布速度。
团队成员每天全部时间都用于这种相互“斗争”,因此你会面临激增的故障、风险、混乱,以及无序。
你需要的是在这一过程中为大家指引明确的方向,为这种情况制定规则,让团队成员在统一的目标下相互合作。
通过 DevOps 这种方式可以让开发者和运维人员顺利合作。问题在于不同目标下 DevOps 的含义也不同。对比来看,SRE(Site Reliability Engineering)的定义就很明确了。
SRE:当软件工程师需要承担所谓的“运维”这项任务后所发生的事 – Ben Sloss,谷歌副总裁
- 软件工程师 – 由了解软件的人负责运维,运行状况反而更好。他们对服务的运转有更深入的了解。
- 设计和运行 – 脚踏实地设计你的生产环境,而不要让生产环境仅仅是“令人惊喜的意外”。
假设谷歌在网络、计算、存储等基础架构方面有 1000 名 SRE,其中有多少负责云服务?
- 全部。
- 谷歌自身业务的运行和 GCP(谷歌云平台)的运行并无差异。在工作任务方面,云团队和内部团队不分彼此,他们通过同一个环境确保所有东西正常运转。
技能:SRE 是不同领域的多面手
这一节的标题是我自己总结的。具备娴熟技能的 SRE 都是精英。他们全心全意从事着一种近乎神秘的工作:生产。
就算从事相同岗位,SRE 也要具备比开发者更全面的技能:
- 他们必须具备更加广泛的技能。
- 所有 SRE 入职前必须通过全面的软件开发者面试。
- 所有 SRE 必须通过非抽象的大规模系统设计面试。
SRE 必须具备与开发者相同的软件技能,这一点与应用领域不同。
- 开发者只需要在产品经理带领下开发功能。
- SRE 肩负生产的责任,要让生产过程尽善尽美。
当面向开发和面向生产的观点结合在一起之后,将获得更为强大的设计。
SRE 所提供的价值可以通过“接手”(OnBoarding)过程的例子了解,当团队的项目交给 SRE 负责时需要进行这样的接手过程。在对团队的软件进行评估时发现:
- 生产环境中达到一定规模后会出错。
- 开发者已经暗中假设某种类型的调用绝对不会失败。
- 他们已经假设请求的分部是均匀的。
- 他们已经假设自己不会成为用户关注的重心。
- 他们会假设所有请求的大小都与平均值一致。
- 他们在开发和生产这两方面都会失败(不解释)。
组织:告诉开发者运维工作不是堆积出来的
运维工作不是堆积出来的,系统应该围绕此目标予以设计,只有让开发者也涉足运维工作,他们才能对此更关心。
为 SRE 提供开发预算。如果某个系统的运营开销远超过开发开销,就无法推进更多功能发布。
SRE 使用了一套截然不同的指挥链。他们有自己独立于开发副总的副总裁,这样就可以得到权力和能力。当生产任务需要他们拒绝时,他们就有了说不的权力。很多整天因为寻呼疲于奔命的人并没有这种权力。
当开发者希望加入 SRE 运维某个指定项目时,SRE 并不一定要接受。SRE 可以说某个服务还不够重要,继续由你自己搞定吧。
SRE 是稀缺资源。谷歌也不是每个团队都有 SRE。云团队有,但其他团队未必有,并且就算云团队也不是每个小服务都有,只有一些重要服务有 SRE。
环境:怎样让生产团队中的开发者感到开心?
至少要有 50% 的工作属于项目工作。不是指待命、处理工单,或开会,而是实实在在的项目工作。
如果项目工作实在太多,或者由开发者向 SRE 提供帮助,或者让开发团队参与到额外的工作流中。
项目工作到底是什么?
- 通过更换底层数据库技术改善服务延迟。
- 编写自动化脚本加快部署速度。
- 横跨不同服务的项目。谷歌即服务(Google as a service)在内部可由其他服务进行内部查询,这通常是由软件机器人执行的,通过查询可以知道是否可以安全地将某台计算机关闭,或者是否可以安全地将整个机柜关闭,或者是否可以安全地将整个数据中心关闭。
SRE 是志愿军,他们行事不需要征募。
- 可以随时调任到其他 SRE 团队。
- 可以随时调任为开发者。
- 开发者可以通过一个名为 Mission Control 的程序体验 SRE 并看看自己是否喜欢这种工作。
团队是流动的。不断有人加入或退出团队,分享着自己的经验和观点。
预算:想怎么花就怎么花的误差预算
如果你的可用性有三个 9,而目标并不需要你实现四个 9,你就获得了 0.1% 的误差预算,好好利用吧。
如果你想更快速推出新功能借此让 GCP 变得更好,在误差预算花光之前大胆放手干吧。
如果你就是不喜欢进行全面的测试,就是喜欢自己的软件频繁出错并不断回滚,你也可以选择这样做,但你的误差预算可能很快就会花光,到时候就没法继续发布新的软件了。
误差预算以季度为周期。
同时还有一个安全阀:三颗银子弹。
- 开发者可以说我真的需要发布,给我一颗银子弹吧。
- SRE 可以答应,但你必须说服副总裁你确实是需要发布。
- 这个过程看起来似乎挺蠢,但非常强大,可以将控制权交给开发者。他们有三颗银子弹,并且要由他们的副总裁来决定是否适合发布。
每个服务都有自己的误差预算。因此如果有多个开发团队负责同一个服务,他们需要共享这些预算。
- SRE 并不会出面警告开发团队,他们只需要决定误差预算到底是怎样花掉的。
脱手。如果开发者和 SRE 尽一切努力也没能达成共识,SRE 可以终止与该开发团队的合作。
- 类似一种友好的分手。
- 是一种关键的“安全阀”,目的是确保团队不会在太长时间里处于各种争议中。
- 虽然罕见但确实发生过。例如这样的情况:假设团队不想为自己 ACID 类型的项目使用 Spanner,如果开发团队称他们想自行构建数据库,SRE 团队可能会说如果要自行构建数据库会无法得到他们的支持,因为这种做法并不适合生产用途。
SRE 是生产任务的守护者,SRE 是客户体验的守护者,无论对谷歌或 GCP 均是如此。
SRE 的支持是全方位的
交流和磋商。与开发者交流,开展各种白板讨论。
共同设计。与开发者一起完成设计工作。
全面拥有。完全拥有服务的方方面面:容量、供应、寻呼机。
寻呼机是保障大家努力工作的一种方法,但这并不是 SRE 的主要目的。
- 负责生产任务的人应该携带寻呼机,借此确保不会失去联系。
- 这也有助于确保 SRE 的技能、经验和观点能随时跟得上时代。
什么让这一切顺利实现?文化和流程
谷歌平时也会进行培训和并要随时待命。
谷歌还有一个名为厄运转轮(Wheel of Misfortune)的流程,这是一种角色扮演游戏。
- 一人充当地下城主,另一人扮演受害者,整个团队轮流猜出即将发生的事。
- 谷歌运营着非常复杂的系统。除了负责培训活动的人之外其他人很少能真正了解会发生什么以及正确的答案到底是什么。
- 这一过程对新的待命人员非常有用,可以帮助他们在受控的环境中测试不同软件。
- 一些团队还会遇到这样的情况:他们弄坏了生产环境中的一些程序,然后让新手来修复。
- 这种做法对老手同样有用,可以借机更新自己的知识,尤其是在处理涉及多方面技术的系统时。
事件管理
场景:你需要为 Gmail 服务随时待命,并接到一个工单称用户可以看到其他用户的邮件。你打算怎么办?关闭 Gmail?
待命人员可以用一切手段保护用户、信息,以及谷歌自身。如果为了保护谷歌而有必要关闭 Gmail 甚至关闭谷歌的整个系统,SRE 完全可以这样做并得到副总裁以及资深副总裁的支持。
目标在于立刻还原服务,排错工作可以稍后再做。
- 所有二进制程序的状态都有记录,还有日志。
- 当系统顺利还原后,开发者回到办公室,并且大家都在场后再开始排错。首要目标在于让服务尽快恢复并正常运转。
到底该责怪谁?
当“新手开发者”发布代码并导致整个谷歌的服务彻底停摆三小时,这时候该责怪谁?a) 新手开发者,b) 代码审核者,c) 测试者不全面(甚至完全被忽略)的测试工作,d) 代码缺乏妥善的金丝雀过程,e) 缺乏快速回滚工具。
- 除了新手开发者,可以责怪其他任何因素。如果新手开发者编写的代码让整个网站停摆,这时候责任不在开发者,而在于开发者和生产环境之间的其他所有负责人。
- 人为错误绝不允许传播到人力之外的其他领域。仔细调查一下为什么发布过程会允许有问题的代码部署出去吧。
无可指责的事后反思
关键在于避免养成相互指责的“文化”。
研究显示大部分事件都是人为错误造成的。
解决事件之前最好能彻底了解实际情况。两眼一抹黑是最佳解决方式吗?仔细调查每个事件,尽量找出责任人吧。
人们都善于隐藏,会尽量不留下痕迹,并会尽量确保别人无法了解到底发生了什么。试图找出责任人的做法只能让你了解实情的过程变得更困难。
谷歌内部“惹乱子”的人必须写事后报告。这些报告不需要指责或埋怨任何人,而是为了避免以后再犯类似的错误。任何对故障有责任的人都会尽可能诚实地写出自己到底是如何掉链子的。
造成网站故障的人还可以得到奖金,因为他们很爽快地承认了自己的错误。他们会通过 IRC 联系并进行回滚,并因为勇敢承担和快速处理而获得奖励。
无可指责并不意味着不需要知道问题到底是谁造成的,以及具体细节如何。只是说我们不会将人本身看作造成故障的原因。任何人都不会因为这种问题被解雇。
纵深防御
- 在纵深防御战略的要求下,针对预防、检测、缓解等措施专门制订不同的事后报告模板。
- 我们想预防故障,我们想更快速地检测出故障,我们也想缓解故障的影响程度。
- 如果以后再发生类似问题,至少可以保证问题传播范围不会那么广,持续时间不会那么长,或影响的客户不会那么多。
不要厌倦寻呼的哲学
团队成员最喜欢看到怎样的寻呼信息?新奇的,有趣的。
寻呼会让你知道问题的解决过程有多无聊。你应该开发专门解决各种问题的机器人。
谷歌开发了各种机器人,他们不喜欢无聊的工作。
如果你能把修复问题的全部过程都写出来,那么你应该就能写出可以自动修复问题的自动化程序。
凡是机器人可以帮你搞定的事,就不要自己动手。
通过创建各种可以自动修复的机器人,以后就只会因为出现的新问题收到寻呼,你也就不会感觉无聊了。就算有经验的工程师也有可能每次接到寻呼信息都会看到一些新奇的问题。
这是人生哲学方面的一次根本性改变。如果你每次遇到的都是新出现的问题,很少有什么问题会重复出现,这意味着在调试系统时就不能总躺在以往的经验上“吃老本”。
有关更强大调试工具的需求
如果你遇到的所有问题都是全新的,这意味着你可能需要更强大的调试工具才能找出问题所在。
文本日志算不得调试工具。如果你不确定到底要找什么,在日志文件中查找所存在的模式,这种标准化的调试方法将无法满足你对规模化的要求。以 GCP 这种规模的平台来说,你觉得需要查看多少日志才能找到造成问题的根源?
为了尽可能快速地还原服务,谷歌会大量运用各种可视化工具对不熟悉的问题进行排错。
图形化工具:Graphite、InfluxDB + Grafana、OpenTSDB。
- 这里提到的并非谷歌实际在使用或推荐使用的工具,这些只是此类开源工具的几个例子。
- 最好能针对汇总后的信息进行调查。谷歌有数以十亿计的流程,因此必须将不同信息汇总在一起才能把事情搞清楚。
- 谷歌在二进制文件中预置了大量 Instrumentation。对于一些比较新的情况你可能无法总是知道自己需要找什么。
通过创建框架让开发者可以更轻松地将自己的代码纳入监控框架。
为监控数据的存储提供了极大容量的存储空间。
- 主要想法在于服务中断的过程中你需要做的不是排错,而是尽一切可能尽快还原服务。
- 排错工作永远只能在服务还原之后进行。排错过程通常需要开发者的介入,因为他们对整个系统有更深入的了解。
- 必须具备所需的历史数据,这样才能在中断问题解决后进行排错。还原操作不能导致故障过程中的监控数据丢失。
- 这种方法可以让服务中断时间尽可能短,并能在问题解决后顺利进行修复。
事件图表 – 非常适用于相互关联的事件。
- 充分利用个人能力找出匹配的模式,机器人很难做到这些。
- 例如一个以数据中心作为行,时间作为列,单元格颜色代表不同事件类型的图表。
- 这样可以帮你找出大量相互关联事件之间的模式,例如新软件的推出导致连锁故障,或集群中反复出现的错误,或发现延迟激增并且紧跟着出现大量错误并且这样的问题反复出现。这样做可以帮你顺利找出造成问题的根源。
可视化进程追踪 – 有时候你需要深入到进程层面才能找出造成性能问题的原因。
- 并不太多的开源选项:Performance Co-Pilot + vector。
- 谷歌有一套非常全面的框架,可以将示例查询的结果拉取到存储中,并对结果进行全面的追踪。
- 可视化工具的优势在于,时间戳信息以往很难利用,但可视化工具可以让你更轻松地折叠、展开、对比不同事件。
网络的流动和容量
- 开源选项:Cacti、Observium、Nagios
- 发现存储速度慢这一问题大多数时候都是网络本身速度慢所引起的。
- 如果在调查存储系统速度慢的问题但没头绪,可以调查一下网络。
- 你需要通过某种工具快速查看网络状态,是否有链路已经超载?有多少数据包错误?链路断了吗?
日志文件 – 如果其他手段都于事无补的话
- 开源:ElasticSearch + Logstash(+Kibana)
- 不应该在海量日志文件中查询,而是应该使用类似 SQL 查询的系统分析日志文件。
- 日志必须要易于使用和易于理解。
堆栈驱动的错误报告
如果你想看看此类工具的示例,SRE 提供了 Google Stackdriver Error Reporting 。
- 这是一种以服务形式提供的内部工具。
- 通过堆栈分析跟踪可对错误信息进行分组和去重。
- 系统了解大家常用的框架,并会据此对错误信息进行分组。
整个计划的目标远不止如此。谷歌内部为云客户提供了一系列工具。
相关文章
- HackerNews 报道 / Reddit 讨论
- 图书:《站点可靠性工程:谷歌如何运维生产系统》(Site Reliability Engineering: How Google Runs Production Systems),本书作者为实际从事 SRE 工作的谷歌 SRE 员工,所有作者加在一起共有 500 年的工作经验。
- 大规模计算,或者说,谷歌是如何让我改变想法的
- 站点可靠性工程 — 确保谷歌能够 24/7 连续运转
- 服务级别和误差预算
- SREcon ,会议视频已发布,有很多不错的内容。
- 讨论会:SRE 是谁 / 是什么?
- 战略:像谷歌那样为停电问题制定计划
- 谷歌是如何备份互联网以及数 EB 其他数据的
- “站点可靠性工程”是什么?
- 在谷歌担任站点可靠性工程师(SRE)是怎样的体验?
- 我对于警报的人生哲学,作者谷歌 SRE:Rob Ewaschuk。
- 谷歌是这样确保(几乎)从不中断的
作者: Todd Hoff ,阅读英文原文: How Does Google Do Planet-Scale Engineering For A Planet-Scale Infrastructure?
感谢夏雪对本文的审校。
给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ , @丁晓昀),微信(微信号: InfoQChina )关注我们。
评论