十年前,集群基础设施 SRE 团队似乎每隔几个月都要雇用新人。事实上,大约与我们新集群上线的频率相同。因为在新集群中启动新的服务能够让新员工接触到服务内部的信息,这个任务似乎是一个自然的和有效的培训工具。
为使一个集群达到可用状态所需采取的步骤如下∶
1. 给数据中心大楼装配电源和冷却设备。 2.安装和配置核心交换机和与主干网的连接。 3.安装几个初始的服务器机架。 4.配置一些基本服务,例如DNS 和安装器(installer),然后配置 Ch y锁服务、存储服务和计算服务。 5.部署剩余的机架。 6.给面向用户的服务分配资源,使其团队可以建立服务。
第4步和第6步是极为复杂的。虽然基本的服务,如DNS是相对简单的,但存储和计算子系统当时正在全力开发中,所以每周都会增加新的功能开关、组件和优化。
一些服务有超过一百个不同的组件子系统,每一个都具有复杂的网状依赖。某个子系统的配置失败,或者是没有按照其他集群来配置一个系统或组件,将造成潜在的故障发生。
在一个案例中,一个存有数个PB的 Bigtable 集群因为延迟原因被配置为不使用 12 个磁盘系统中的第1个(日志型)磁盘。一年后,一些自动化程序假设如果一台机器的第一个磁盘没有被使用,这台机器就不被配置任何存储服务;因此,可以安全地清除数据。这导致所有的Bigtable数据立刻被清除了。幸好我们的数据有多个实时备份,但是这种意外也是很糟糕的。自动化应该对那些隐含的"安全"信号非常小心。
早期的自动化关注于加速集群交付。这种方法往往依靠"有创意"地使用SSH来应对繁琐的包分发和服务初始化问题。采用这种战略一开始很成功,但是这些格式自由的脚本逐渐堆积形成了技术债务。
随着集群的数量增长,一些集群需要手工调整功能开关和配置。这样做的结果是,团队在追逐难以发现的错误上浪费了越来越多的时间。如果某个使 GFS对日志处理响应更快的开关泄露到了默认模板中,文件很多的集群就可能在负载之下内存超标。每次大型配置改变时,令人恼怒和极为耗时的错误都会偷偷潜入。
我们用来配置集群的、有创造性的——但是脆弱的——shell脚本既无法适应需要修改该脚本的人的数量增加,也不能适应需要构建的集群的大量组合形式。这些 shell脚本同时在宣布服务状态良好,可以承受用户的流量的问题上也未能解决一些显著问题,比如∶
● 是否所有服务的依赖关系都可用,并且正确地配置了? ● 所有的配置和包都与其他部署一致吗? ● 团队是否能够确认配置中的每个例外都是合理的?
Prodtest(生产测试)是对这些问题的一个巧妙的解决方案。我们对Python单元测试框架进行了扩展,使其可以用来对实际服务进行单元测试。这些单元测试有依赖关系,允许进行链条式测试,一个测试中出现的故障可以很快中止整个测试。以图7-1所示的测试为例。
某个团队的Prodtest 执行时,会传入该集群的名字,这样它可以验证该集群中的服务。后来增加功能可以让我们生成一个有关单元测试和它们状态的图表。这个功能使工程师能够更快看到他们的服务是否在所有集群中都被正确配置了,如果没有,为什么没有。图中突出了出错的步骤,以及出现故障的单元测试会输出的更详细的错误信息。
每当一个团队遇到因另一个团队意外错误配置而导致的延迟时,可以提交一个Bug 来扩展Prodtest。这确保了类似问题以后可以尽早发现。SRE能够非常自豪地向用户保证,他们的所有服务———不管是配置的新服务还是现有服务——都可以可靠地服务生产业务。
我们的项目经理第一次可以准确地预测一个集群的"上线的时间"了,同时可以对为什么每个集群从"网络就绪"到"服务线上流量"需要6个星期甚至更长时间有了一个完整的理解。毫无准备的,SRE突然从管理高层收到任务∶在3个月内,有5个新的集群将在同一天进入网络就绪的状态。请在一周内完成上线。
|