这是我在 Uber 创立 SRE 组织的个人故事。如果您需要建议而不是回忆,请查看高速增长时代的Trunk and Branches Model and Productivity 。
2014 年离开 SocialCode 后,我花了一个月的时间在几家公司面试,试图弄清楚下一步该做什么。我在考虑两种不同的路径之间犹豫不决:(1)在一家非常小的初创公司领导工程,或(2)在一家快速发展的公司担任小得多的角色,期望增长会创造机会。经过一番考虑,我最终选择了后者加入优步。
我忘记了我在优步的确切面试时间表,但大致是“周二面试,周三报价,下周一开始。 (这不是我在 Uber 见过的最快的转变,远非如此!我曾经在周五 5:00 左右向某人提出要约,他发出通知并在两天后的周一开始。)聘用的是“DevOps Manager”,起初我很紧张,因为我不太确定 DevOps 的含义。等待周末开始,我焦急地阅读了凤凰计划,试图对我刚刚被雇用做的事情进行逆向工程。
据我所知,当我开始时,有四个团队在做可能被经典描述为“基础设施”的事情。数据和地图工程团队也隶属于基础设施组织,但他们非常专注于其他工作,因此为了叙述方便,我将省略它们。
基础设施团队是 (1) 开发工具团队,(2) 基础设施工程团队激光,专注于超越 PostgreSQL 索引对磁盘空间的需求,(3) 丹麦的一个团队主要专注于部署工具,以及 (4) InfraOps 团队那做了一切。在一个大约 200 人的工程组织中,我们大约有 20 人,而且正在迅速增加到 2000 人。
我加入了最后一个团队,InfraOps。我们一共 5 人,负责维护公司的大部分服务器(Uber 那时没有使用任何云提供商)、路由基础设施(主要是 HAProxy)、Kafka、大多数数据库、服务供应(在“面向服务-架构”这个词的含义)、一些安全的东西(当时只有一名专门的安全工程师)、puppet、 Clusto以及落在组织垫之间的各种软件结。
开始时,我评估了团队面临的挑战,并将它们缩小到几个需要紧急关注的领域:保持网站正常运行(由于负载加速,大多数周五下午经常出现问题,人们的手机经常用完由于 Pagerduty 在 12 小时值班轮班期间的 ping 导致的电源),扩展 Kafka,准备在 Uber 的万圣节流量高峰之前迁移出我们的第一个数据中心(我们决定不在我们当前的数据中心购买任何额外的容量,所以这是一个艰难的最后期限),并支持传入的提供服务的请求。在我的第二周和第三周,我为每个人都写了一个策略,感觉就像我们有一条清晰的前进道路。
这些计划——就我极其客观且绝不自私的记忆而言——是最出色的计划。如此好的计划,以至于我的经理后来透露,他最初担心我会走进去并立即解决他一直在努力解决的问题。当然,很快就会发现,那些非常出色的计划在纸面上效果最好。
我们的第一步是建立一个服务说明书:一个描述我们为其他团队所做的工作的 YAML 文件,以及一个 Python Flask 应用程序,该应用程序将该文件编译成一个 UI,在可能的情况下自动化这些请求,并生成结构良好的票证,其中包括必要的完成任务的信息。我们当时的票务系统 Phabricator 不支持为不同类型的请求添加必填字段,因此服务手册通过简单地确保每个请求中包含正确的信息来提供很多价值。更重要的是,服务指南为我们提供了我们一直缺少的东西:传入请求的数据。
随着使用数据的积累,很快我们就清楚地发现,我们大部分时间要么用于响应关键的生产火灾——这不是我们可以忽略的事情——要么用于提供新服务。
服务供应
在 Uber 的单体架构中工作变得很困难:迁移有风险,部署速度很慢,调试事件具有挑战性,因为每个部署都包含许多团队的提交,等等。已经做出弃用单体架构的决定,并且团队正在尽快逃离到新的服务中。
服务供应是一个随意的过程,遵循一个长期的运行手册,需要在至少三个不同的主机层上按顺序部署 puppet 更新,此外还要在 Clusto 中处理一些容易出错的位(类似于Hashicorp 的 Consul ,但早于它几年;Uber 的大部分初始基础设施技术堆栈都是由早期工程师 Jeremy 从 Digg 移植过来的)。在这些步骤之后,您将不可避免地开始调试您或请求新服务的团队做错了什么。总而言之,您可以轻松地花半天时间来配置一项新服务,然后再花一周时间与该服务的拥有团队来来回回,以使最后的部分正常工作。
我们每周在服务供应积压方面落后一点,如果不取消其他紧急计划,我们就无法在供应工作中增加更多人。所以我们专注于我们最好的剩余工具,自动化。
我们没有多少人专门从事服务供应,所以最初只有我兼职做这件事,还有一位在我做的同一天加入的工程师小健。这还不够,所以我们很快聘请了第二位工程师 Woody 来全职工作。伍迪在服务供应上花费了太多时间,以至于曾经有人困惑地得知伍迪是一个人而不是 Hipchat 机器人。
我们的服务手册为我们提供了一个接口来拦截传入的服务供应请求,我们不断扩展工具,直到人们可以在没有团队支持的情况下完全供应。一些中间步骤相当尴尬!我特别记得有一个阶段,我们为每个新服务自动生成Puppet配置,但仍然需要请求工程师自己实际合并更改。人们很困惑地请求一个新的服务端,他们将更改粘贴到我们的 Puppet 存储库中,并希望它不会破坏任何东西。
另一个有趣的子挑战是服务发现和路由。我们通过HAProxy进行服务发现,您可以通过将 localhost 连接到服务的静态分配端口来路由到当前环境中的服务,然后 HAProxy 将路由到在该环境中某处运行的实例。当 Puppet 运行时,HAProxy 会在每台服务器上单独配置,通常每小时在每台服务器上配置一次。 (每小时的 puppet 运行时间超过 20 分钟,因此在无效的 puppet 更改开始传播和整个舰队崩溃之间大约有 5 分钟的时间。我们擅长在胁迫下暂停部署,但我们也崩溃了很多东西。)要提供新服务,您需要预留一个全球唯一的端口。如果你重用一个端口,你将不可避免地导致中断。端口最初记录在某个地方的 wiki 页面中,尽管许多端口没有记录在任何地方。为了使服务供应的这一步自动化,我们从手动分配转向自动分配(后来摆脱了静态端口分配的恐惧)。这是我们必须紧急解除以自动化整个流程的许多早期选择的一个很好的例子。
这些问题绝不是原始基础设施设置中“错误选择”的结果。相反,与大多数技术决策一样,这些方法根本无法在几个数量级的增长中完好无损地存活下来。我们遇到的许多挑战在今天几乎闻所未闻,但是当 Uber 的基础设施首次建立时,大多数解决这些问题的工具根本不存在作为经过验证的选项。 (作为后来的例子,Uber 最终会运行 Mesos 而不是 Kubernetes,因为当时 Kubernetes 是一个早期项目,在负载时没有太多使用。)
当我们解决了这些问题中的每一个时,服务供应变得更快,更不容易出错。在 18 个月内,我们从 15 项服务扩展到 2,000 多项,其中每一项服务都由该团队或他们构建的平台提供。当团队达到顶峰时,大约有四个人致力于解决这个特定问题,绝大多数都是通过平台完成的。与最初的跨团队、为期一周的工作相比,服务供应变得非常容易,以至于每个入职工程师都会在第一天就提供新服务。
人数
除了我们在自动化方面的工作外,我们还增加了招聘。我遇到的第一个挑战是团队拒绝了所有候选人。在我的经理面试中,我最终在白板上用 Python 解决了旅行推销员问题,这基本上是面试过程的标准。没有标准化的问题,没有评估候选人的标准,每个招聘经理的整体结构各不相同。
今天,我将从推出这些常见做法开始,但在我职业生涯的那个阶段,我从未见过或听说过这些最佳做法。因此,我会和我的招聘伙伴坐在一起,调试为什么每个循环都无法生成报价。对于我认为可以帮助我们度过即将到来的工作冲击的候选人,我会去与团队争论我们为什么需要雇用他们。最终,他们对与我发生同样的争论感到恼火,并开始同意雇用一些候选人。
作为一个在加入优步之前雇佣了大约六名工程师的人,这是一次真正的烈火洗礼。我在优步的第一年,每周我经常会做十次电话筛选以及四到五次面试。我清楚地记得在一天做了三个背靠背的电话屏幕并努力区分笔记中的候选人之后,我在这些玻璃房间里。我们进行了如此多的面试,以至于我们制定了一个流程,让优秀的面试官在他们开始精疲力竭时主动轮换面试。
由于缺乏监督或标准化,我们也有过既搞笑又可怕的招聘经历。我们拒绝了一位候选人,他的推荐人说服我们在六个月后再次采访他们,我们立即再次拒绝了他们。没有被吓倒,另一个团队坚持第三次面试候选人。我联系了那支球队的经理劝阻他们,但他们坚持并提出了要约。候选人接受了,从优步开始,然后在他们第一天的几个小时后,他们在 Twitter 上接受了第二次报价(很方便,一个街区之外)。最后,他们在 Uber 面试的时间比他们在那里工作的时间还多。
以这样的速度招聘,加上频繁的生产火灾,以及一连串沮丧的合作伙伴团队,毫无疑问是我工作过的最辛苦的工作。这一切都在消耗。从好的方面来说,它确实有效。我们雇佣了很多人,一年之内,我们从五个人发展到大约四十人,完全由外部招聘驱动。
创立 SRE
随着我们团队的壮大和自动化程度的提高,我们的计划表明情况会有所改善。但他们没有。我们仍然深陷在水下。我们的方法是有效的,但它的工作速度不够快。我们周围的工程组织每六个月就翻一番,每隔几个月就会带来一个新的紧急项目,其规模例如在中国配置两个新的数据中心。
我们还能做些什么来从这个工作量下面挖掘出来?如果增加人力和软件能力还不够,那么我们能想到的唯一选择就是减少工作量。太明显了!任何减少工作量的方法都必须满足两个特定要求。首先,我们需要保持能力,为每六个月加倍负荷带来的不可预测但不可避免的生产问题配备人员。其次,我们必须为其他工程团队提供足够的支持,以便他们能够在关键的、独立的目标上取得进展。
有一种模因认为,减少工作量的解决方案就是强迫你的经理优先考虑你的工作量,但我只看到这种策略在自上而下的组织中奏效。这也是将自己从领导者降级为经理的可靠方法。诚然,我太着迷于我们的团队自己克服这一挑战,以至于没有考虑寻求帮助。最终我们想出了另一种方法:我们能否通过改变组织的形式来解决这些限制?
正是这个问题引发了 Uber 的 SRE 组织的成立。
如果我们能够保护他们免受传入的工作请求的影响,我们就有足够的人员来扩展我们的基础设施,因此我们专注于如何保护这些团队免受中断,同时为请求团队提供足够的支持以取得进展。该结构有效地:
- 我们的三四个顶级组织合作伙伴将获得专门的 SRE 支持。合作伙伴团队将明确优先考虑 SRE 支持他们的工作量。我们根据请求数量而不是影响来定义“top”
- 其他人都将从构建自助服务平台的团队中获得支持。他们会根据加速自动化的原则优先考虑工作
- 其余的基础设施将支持可扩展性和操作的特定领域,例如网络、Kafka。他们大多优先考虑可扩展性、可用性和效率
当我们开始推出这个项目时,我们遇到了一个典型的 Uber 问题:我们没有人为 SRE 团队配备人员。然而,不久之后,我们聘请了 Uber 的第一个 SRE, Rick ,Uber 的第一个 SRE 经理,Eamon,并且从那里开始招聘。
当 Rick 加入时,我对 Rick 的励志演讲不是很好,大概是“你真的很聪明,很有经验。您需要帮助该合作伙伴团队完成他们的工作,而无需向更广泛的基础架构团队提出任何请求。不要等待许可,去做一些事情。祝你好运!”完全值得 Rick 称赞的是,不知何故,这成功了。
此后不久,又聘请了另一位工程师加入 Rick,与同一个合作伙伴团队一起工作。然后又聘请了两名工程师来支持名单上的下一个合作伙伴团队。之后两人支持了第三支队伍,计划开始形成。我们继续这种模式,添加更多 SRE 直接嵌入顶级合作伙伴团队,直到我们用完足够大的合作伙伴团队来支持。
合作伙伴团队终于能够将基础设施请求与他们的工作保持一致,大部分都停止了升级。尽管我们没有给他们他们想要的支持水平,但我们已经给了他们明确的控制权,并让他们了解他们的团队要求做出的权衡,其中许多在早期的模型中是他们不知道的。
随着我们的 SRE 部署稳定下来,感觉就像我们终于解决了这个问题。
这个 SRE 模型并不完美。它与合作伙伴团队一起茁壮成长,但与其他团队一起挣扎,但它解决了它设计的问题:我们的合作伙伴团队正在取得可预测的进展,我们能够同时优先考虑可扩展性工作。最重要的是,它解决了这个问题,没有任何全局自上而下的优先级方向,而是依靠合作伙伴团队在本地解决他们的优先级。
SRE v2
优步更广泛的基础设施组织有解决问题的有机方法。它基本上是一个自下而上的组织,有地方战略,没有共同的总体战略,这造成了很多摩擦点。最终,随着公司规模的扩大,我开始寻找我的直接经理的职位,最终我们聘请了 Uber 的下一任基础设施负责人。
新的基础设施负责人根据他们以前的经验,采用了一种非常具体的方式来构建架构和基础设施组织。几周之内,他们启动了一个重新架构 Uber 技术和基础设施堆栈的项目。他还对 SRE 应该如何工作有一个具体的看法,并在几个月内聘请了一位以前的同事来接管领导 SRE 团队。
在新领导加入以重新实施他们以前的设置后,通常会出现这种情况,关于事情如何运作的重要背景被掩盖了。我也没有很好地解释我们通过 Uber 的 SRE 组织解决的具体问题。直到今天,我相信这些新领导者对 Uber 的 SRE 组织正在解决的问题存在根本性的误解(使自下而上的组织具有高度流动的优先级,而这些优先级在任何地方都没有解决成一个单一的优先级列表来成功运作),而是查看它从他们之前的经历来看。结果,SRE 迅速从嵌入式模型转变为完全不同的模型。
名字没有改变,但很快就变成了一个非常不同的团队。这个不变的名字隐藏了重大领导和文化转变的开始,这一转变将在 Susan Rigetti 反思 Uber 的一个非常非常奇怪的一年达到高潮。几个月后,我两年内的第五个老板出局了,不久我也跟着走了。
SRE 组织仍然存在。我们建立的 SRE 组织已经消失了。
反射
在讲述像这样的故事或 Digg V4 发布时,总是会努力以最好的方式展示自己,但我会尽量忠实地讲述这些事情:如果我可以重做我的时间,我会做很多不同的事情。优步对我来说是一个突破性的角色,如果没有我在优步首先学到的一切,我就不会在随后的工作中取得成功。也没有什么比我们一起取得的成就更让我感到自豪的了。致我在优步共事和学习的人:谢谢你们,你们让我的生活变得更好。
这并不是说体验非常好。在 Uber 的那个时代工作带来了损失。许多其他人付出了更惨的代价;我也付了一份。作为一个领导者,我有点不知所措,我为此苦苦挣扎。在 Uber 立陶宛办事处的一次工作旅行中,我七年的合伙人打电话告诉我他们已经搬走了。写作一直是我最喜欢的爱好,但在那里我放弃了写作。有些章节丰富了我们的生活,但我们不会重复,而 Uber 对我来说无疑是其中之一。