admin 发表于 2020-11-21 13:52:35

谷歌SRE们如何运行生产环境

《站点可靠性工程——谷歌是如何运行生产系统的》是一个开放的窗口,让大家可以看到谷歌在全世界范围内运行一些大型IT系统的经验和专业技能。这本书描写了支撑着站点可靠性工程(Site Reliability Engineering,SRE)学科的一些基本原则。她也详细描述了一些谷歌的关键实践,让谷歌可以以惊人的速度扩张而又不损失性能和可靠性。\
尽管站点可靠性工程出现得比DevOps还早,谷歌的副总裁,同时也是谷歌站点可靠性工程创始人的Benjamin Treynor Sloss却说可以把站点可靠性工程视为“DevOps带了一些特殊扩展的具体实现”。站点可靠性工程有八个原则:可用性、延迟、性能、效率、变化管理、监控、紧急响应和容量计划。这本书很大篇幅都在讨论站点可靠性工程团队该如何与这些核心原则保持一致,并且开展他们的工作。\
站点可靠性工程中的软件工程\
那么,用Sloss的话来说,到底什么是站点可靠性工程呢?在他看来,站点可靠性工程就是“当你请一个软件工程师去设计一个运维团队时会发生的事”。这主要源于团队的组成比例:50%到60%的站点可靠性工程师都是受过了培训的软件工程师。他们的技能和开发产品的软件工程师们一样。团队中剩下的成员们技能也相似,但是会有专门的运维知识,比如网络或Unix系统原理等。这样的组合是很理想的。但随着IT系统的增长而线性的扩张公司规模是不可能的。所以谷歌的站点可靠性工程团队里的软件工程师们都极力主张将一切自动化,而且尤其讨厌手工劳动这样的体力活,他们从这一点获益匪浅。\
但站点可靠性工程师们该怎样才能有足够的时间把所有问题用自动化的方式解决掉?谷歌的答案是50%的手工劳动。站点可靠性工程师们必须把他们的50%的工作时间花在工程内容上。谷歌会监控每个站点可靠性团队所做的运维工作。如果持续地超过50%,那就由产品团队负责超额部分的工作。这个方法非常有效地激励了产品开发团队以自动化的方式构建系统,从而不必依赖手工运维。而且根据经验,值班工程师应该每个班大概处理两个问题。如果数量少于二就是浪费时间。但如果数量远大于二就会超出值班工程师的承受能力,让他没办法彻底解决问题,并且从中有所收获。\
处理危机\
谷歌处理危机的方法很独特。开发团队会关注开发新功能,而运维团队关注可靠性,两者之间的冲突常常源于这个分歧。谷歌用故障预算的方法来促进大家的交流,在流程上改变整个讨论方式。\
随着可靠性级别的增长,要付出的代价就会以指数级增长。除了一些特别的象Pacemaker之类的领域,如果在其他领域要求100%的可靠性的话,这个目标就设立得不对。从现实的角度就很容易理解,当你获取终端用户和你的网页服务之间的所有参数时你就知道100%的可用性是不可能的,比如Wifi、网络提供商和电脑等都可能出问题。所以在谷歌,可靠性目标是一个产品,而不是一个技术上的决定。比如说一个产品团队把某个服务的可靠性目标设为99.9%,那就意味着这个服务每年只能宕机8.76小时。这就是这个服务的故障预算,产品团队可用利用它来合理地犯错误,从而进行尝试和创新。\
这本书中包含了很多真实的将概念转变为现实的示例,比如故障预算等。有一个很有名的就是谷歌的可靠性锁服务Ch y。随着时间的过去,越来越多服务要依赖Ch y,而且都会假设它永远都不宕机。如果它出故障,那所有的东西都会出问题,于是Ch y的故障就会变成用户可见的故障。因此Ch y的站点可靠性团队就决定要让Ch y达到或者稍微超过它的可靠性目标。如果Ch y远超过了它的目标,那就会触发一次规模可控的故障来把服务停掉。这样的行为促使所有其他服务在做设计时就考虑了Ch y有可能会出问题。\
监控的关键角色\
从理论上和实践上考虑监控都要考虑覆盖率。毫不意外,站点可靠性工程师们会把延迟、流量、错误和饱和度做为监控的四个关键指标。跟踪错误是衡量服务可靠性的重要手段。因为谷歌的很多服务都是面向全球的,所以很少会出现全面停服的情况。这样用服务时间和停服时间来衡量可用性就不充分。相反,谷歌把可用性定义成成功的请求占总请求数量的百分比。\
一个好的监控和告警管道不会让告警电话响个不停。它会关注那些迫在眉睫的问题,只是把故障现象发送给值班工程师。在调查问题的时候,系统还会提供足够多的与问题根源相关的细节。监控系统应该避免基于邮件的告警,相反应该提供有意义的显示板。这些显示板要展示累积的数据,也要提供对分析有启发性的日志。标准化的流程会收集和处理供给这些显示板和告警的指标。每个谷歌的二进制文件都会内嵌一个HTTP服务器,通过标准化的接口来 这些指标集。这些指标就会根据各种规则收集并积累起来。Prometheus就是一个开源监控工具,和谷歌的模型很接近。\
负载处理\
编辑们用了好几章的篇幅来讲述负载处理这个艰巨的任务。负载均衡是第一道防线。负载均衡可能看起来简单,但那两章描述谷歌的负载均衡策略的内容却很直白地告诉了大家事实并非如此。在谷歌,负载均衡是从决定由哪个数据中心来处理用户的请求开始的。第一层负载均衡是DNS,它的功能是尽量把用户的请求转发给最近的数据中心。第二层使用虚拟IP地址技术来选择真正地处理请求的后台程序。\
一旦进到了数据中心里面,谷歌就对基础设施有了很多控制手段。它可以重新组织用户的请求包。在谷歌的RPC系统中,客户端一启动就会打开一个到服务端(某个服务的一个具体实例)的长连接,以此来避免为每个请求都要打开和关闭连接带来的开销。这种策略带来了两个问题。第一,该如何处理有问题的服务端?答案是将服务端归类为三种状态:健康、拒绝连接和跛脚鸭。如果一个服务端是跛脚鸭状态,那它仍会提供服务,但它会要求客户端不要再发送新的请求,从而让它可以干干净净的退出。第二个问题是对资源使用率(CPU和内存)的优化。假如有绝对数量的服务端在提供某种服务,那如果一个客户端要连上所有服务端就太浪费了。那么一个客户端该怎样挑选某几个服务端连上去呢?谷歌使用了一种带权重的轮询算法,事实证明可以非常有效地将负载分摊到所有可用的服务端上。带权重的轮询算法就是让客户端持续地查看每个服务端的处理能力。每个服务端根据实际的查询率和每秒的出错率来报告它自己的处理能力。\
即使负载均衡很完美,有时候过载仍是不可避免的。在这种情况下,目标就是要让每个服务端继续按它所计划的处理能力提供服务,同时拒绝掉超出它处理能力之外的请求,以此来避免雪崩效应。最有效的处理过载的方法需要客户端和服务端的协作。对于一个特定的服务,客户端不该超过它们的消耗额度。服务端应该拒绝掉超量的请求来避免灾难性的大面积故障,而且要打印出足够的错误信息。工程师们可以通过负载测试来理解各个服务的出错模式,并制定相应的应对策略。重试策略必须经过精心调校,要不然它们反而会给服务端增加负载从而加剧问题。有一些策略可以用,比如随机的指数级退避式重试,或者重试放大最小化(一种由底层触发的重试的迭加,从而进一步压垮堆栈)等。\
数据的挑战\
如果不存在要保持数据的一致性和持久性的问题,那软件工程师们的生活就轻松多了。可实事上就是存在这样的问题。谷歌的站点可靠性工程师们还要在超大规模的数据上处理这个问题,所以他们专门花了几章来讨论这些挑战,比如在分布式系统中保持数据的一致性状态、用Cron做大规模的周期性调度、数据处理管道和保证数据完整性等。最有趣的是对系统架构上分布式一致性问题的深入讨论,这主要要靠Paxos算法和它的变种,包括它们的性能损耗、部署考虑以及要监控的指标等。\
数据完整性一章强调了深入防范数据丢失的重要性。谷歌做了三重防范。第一层是软删除,就是只是给相应的数据项打上个“已删除”的标记,这样要恢复就非常容易。数据完整性必须和数据隐私之间做个权衡,这要看隐私策略或者法规,而在一定的时间周期之后数据必须被彻底删除掉。第二层就是传统而又关键的备份和恢复。第三层是提早发现,就是要在数据库问题真正发生的前几天、前几个星期甚至前几个月就要把这些潜在的问题定位出来。谷歌使用了旁路数据校验策略,来提高发现数据库之间或数据库内部数据不一致问题的机会。\
可能是出乎大家意料之外了,但谷歌的确有她自己的离线备份系统,即通过磁带驱动器备份。书中举了两个例子,来讲述这么受人尊重的磁带驱动器对于恢复用户数据是何等重要。读读恢复过程中要动用卡车去把1.5PB的存储着数据的磁带从一个仓库中拉出来,你就会受到启发了。而读到这一节你也会觉得非常振奋,就是站点可靠性工程师们是手动地把磁带一个一个装入磁带库的:因为根据以前的灾难恢复测试(Disaster Recovery Test,DiRT)经验,他们知道手动装磁带的方法会比用机器人装快得多。\
这本书的编辑们现在都是,或者曾经是谷歌的站点可靠性工程师,他们一起写出了这本书的34章内容。如编辑在序言中所说,书中的每一篇都更象是一篇短文,完全可以单独阅读(就象这篇书评一样)。事实上,某些章节也是基于以往发表过的文章的。尽管这种形式让这本书显得不那么理想化,风格有些不一致,而且也比较冗长,但Betsy Beyer、Chris Jones、Jennifer Petoff和Niall Richard Murphy等几位编辑们却非常专业地把这份知识的财富整合到了一起。你可以把这本524页的书从头读到尾,也会觉得很连贯。但最好的利用这本书的方式还是先读读基本原则相关章节,然后关注你最感兴趣的具体实践。\
页: [1]
查看完整版本: 谷歌SRE们如何运行生产环境