探秘Twitter的应急预案、部署流程与新架构

个人简介 Raffi 是Twitter工程团队VP,负责Twitter基础架构平台的。他的团队负责商业逻辑、可扩展性服务、API、存储、核心库,以及Twitter内部开发模型。 在加入Twitter之前,他曾帮助人们设计个人能量消耗与全球能量消耗的对应关系(获20008年Wattzon - Business Week's "Best Idea"),还写过一本《TiVo Hacks》的著作(在2003年8月由O'Reilly出版)。他还创办了一个专门支持各种疯狂项目的咨询公司,并曾在NYU大学任教。在那之前,Raffi还在MIT和MIT Media Lab挥洒了不少时光。

QCon是由InfoQ主办的全球顶级技术盛会,每年在伦敦、北京、东京、纽约、圣保罗、杭州、旧金山召开。自2007年3月份首次举办以来,已经有包括传统制造、金融、电信、互联网、航空航天等领域的近万名架构师、项目经理、团队领导者和高级开发人员参加过QCon大会。

   

1. Hi,Raffi。能否向InfoQ的观众和读者们介绍一下你自己。

Raffi:当然,我的名字是Raffi Krikorian,Twitter的平台工程副总裁。我们团队主要是负责Twitter的后端基础设施。

   

2. 在《天空之城》的帮助下,Twitter创造了新的TPS峰值记录,Twitter是如何应对无法预料的流量峰值的?

Raffi:当然。你所说的在我们内部称为《空中之城》事件,这是东京播放的电视节目。我们的新纪录大概是在该时间段内每秒涌入34000条推文。一般情况下,Twitter上每秒的推文数量在5000到10000条左右,所以这远远超出了我们的正常范围。我认为这说明了几点:它展示了Twitter是如何与世界互动的,比如世界上正在发生一些事情,它们会体现在Twitter上。

经过了多年的精心准备,此类事件可以发生在任何时间,完全不用提前通知。我们对Twitter的基础设施进行压力测试,每个月都会进行此类测试,然后分析Twitter的每个系统,我不清楚最近的详细时间计划。

在构建Twitter的架构和系统时,我们是以周为单位来确定那些系统的性能的,我们能清楚地知道每个服务维度的系统理论容量,从而尝试去了解整个系统的理论容量。基于这些信息,我们能够判断:(1)在任何时间点,我们是否都拥有合适数量的生产服务器,还是需要购买更多的机器。(2)我们可以理性地判断系统是否有效工作。

比如说,当出现了一些服务,它们只能处理其他服务一半的请求,我们就应该去看一下那些服务,从架构上理解它们,看看它们是否正确运转,还是说需要做些改变。

对我们而言,处理《空中之城》事件的架构是一个缓慢的演进过程。做一个变更,看看反应如何,它对系统的影响是怎么样的,在观察后,我们会决定是否要接受这个变更,我们也会做些权衡,是购买更多的服务器,还是写新的软件来达到目的。

虽然之前从来没有经历过《天空之城》这样的事件,但在此之前,压力测试把我们推向过这些极限,因此当它在现实中发生时,我们能从容应对。“是的,它就是这样的。”

   

3. Twitter有没有一些应急预案?平时会不会做些演练,比如干掉几台服务器、交换机或路由?

Raffi:是的,我们在做应急预案时基本有两类不同的事情,也许是三类,这要看你是如何看待它们的。每个系统都详细地在文档里写清楚了我们该怎么打开它,或者该怎么关掉它。每个系统都有一个称为“运行手册”的东西,在紧急情况下我们清楚地知道该做什么。我们考虑了各种不同类型的故障,虽然没有面面俱到,但至少考虑到了大多数常见情况,落实到文档里,我们明白要做什么。

第二点,我们总是对生产系统进行测试,所以能很清楚地知道当系统出问题时会是什么样的。我们可以做些演练。比如让系统出问题,团队成员待命,他们可能会拿到一个传呼机,有问题时传呼机会响。我们可以判断下是否需要做些不同的事情,如何进行应对。

第三点,我们是从Netflix那里受到的启发,他们的Chaos Monkey会主动杀死生产环境了的服务器。Twitter也有类似的东西,我们可以确认自己没有在不经意间引入单点故障。我们在数据中心里随机杀掉几台服务器,确保在此期间服务不会发生抖动。

所有这些都要求我们对所有不同系统的成功率了如指掌。因此我们有块大屏幕,这是块玻璃墙,通过上面的内容我们可以清楚地看到Twitter上发生的一切。当有情况出现时,我们可以立刻看到是不是有变更,是有突发流量,还是数据中心内有故障,可以快速做出应对。

   

4. 当有问题发生时,如何隔离故障模块的?你们的第一反应是什么?

Raffi:目前Twitter的架构就是要让故障被控制在发生故障的功能内。当然,越是在系统栈下部的故障,问题就越严重。如果我们的存储机制突然出问题了,大量系统会报错。如果是网站出问题了,现在是不会影响到API的。

同样地,只要看大屏的不同部分就能知道有东西出错了,我们有设置了不同阈值的服务级报警。因此,如果某个API的成功率下降到某个数字以下,一堆寻呼机立刻会响起来。在Twitter,每个服务都始终有人在待命,能在最短时间内做出反应。

我们的运维团队和网络指挥中心也会看到这些信息,他们可能会采取些初步的措施,比如我们是不是该把它重启一下,看看会怎么样。另一方面,真正的软件开发工程师会试着弄明白系统到底出了什么问题。运维要确保站点快速恢复正常,而开发则是要弄明白到底哪里出问题了,是不是有Bug要处理。

这就是我们的故障应急方式。正如我所说的,Twitter的架构让故障相对可控。如果我们认为故障可能会扩散,打个比方,社交图谱有问题,那只会在这个特定功能里看到问题,社交图谱团队会立刻通知其他人,以便在有东西出问题时大家能心中有数。

我可以开玩笑地说我们现在的强项正是应急管理,灾难发生时该怎么办,因为它随时会发生,我对世界的承诺是Twitter会始终在线,你不必担心它。

   

5. Twitter的新架构在稳定性和性能方面的作用不小,能不能给大家简单介绍一下你们的新架构?

Raffi:好的。几年前,当我加入Twitter时,我们的系统用的还是一个大而全的代码库,所以大家都工作在同一套代码里,每个人都能部署代码、接触代码、修改代码。这听起来很不错,理论上来说也很棒,Twitter的每个开发人员都有能力去做正确的事。

但实际上,这里存在一个平衡,开发者需要理解每个东西都是怎么运作的,然后才能对代码做出变更。在实际操作时,我关心的是以在Twitter里写新代码的速度,人们并不会深入思考之前没有看过的代码。我认为开发人员在开发软件时应该有个标准。往往我并不完全理解为什么我要改这个地方,如果我改了这行代码,它也许会有我所期望的效果。我并不是说这是个不好的行为,这很谨慎、很方便。但你在这么做的时候是在累计技术债。

所以我们将这个大而全的代码库去掉了,取而代之的是把它拆分成几百个不通过的服务,由这些服务来组成Twitter。这样一来,Twitter的每段业务逻辑、每个功能都找到真正的拥有者。真的有一组人,管理Twitter上的照片就是他们的工作内容之一。另一组人,他们要管理Twitter上的URL。现在公司里有了专门方向的专家,比方说你想对URL方面的东西做些修改,就可以去咨询他们。

我们把东西都分开了,不仅有了不同方向的专家,这还让我们可以做到故障隔离,功能开发时的隔离。如果你想修改推文相关的东西,只需要修改特定的几个系统,不再需要修改整个Twitter。因此我们对故障和开发都有了良好的隔离性。

   

6. 你们有个名为Decider的东西,它在系统中充当什么角色?

Raffi:Decider是Twitter的一个运行时配置机制,我们可以在不用执行部署的情况下关闭某些特性或者软件。Twitter中的每个服务都会不断地查看Decider系统,了解Twitter目前的运行值。以发现页为例,Decider实际上有一个针对它的值,这个值会告诉发现页此时此刻究竟该开启还是关闭。

因此我可以将发现页部署到Twitter上,但是通过Decider将其状态置为关闭。这能让我们避免不一致的状态。仍以发现页为例,它是运行在多台服务器上的,任何Twitter的功能都是如此。它不是运行在一台服务器上的,你不希望有不一致的状态,某些服务器上部署了该功能,而另一些则没有。我们可以通过Decider将其部署为关闭状态,在需要打开时,所有机器都会变为开启状态,我们只要轻击Decider的开关就能原子化地在数据中心里所有的服务器上开启该功能。

这也给了我们按百分比进行控制的能力。虽然部署在所有的服务器上,但我只希望50%的用户能用到某一功能。实际上我真的可以做到这一点,这要归功于Twitter部署东西的方式,这让我们能在无需发布代码的前提下实时控制Twitter。发布代码是很危险的一件事,像我们这样的系统里和故障关系最大的就是软件部署错误,不仅是Twitter,所有大型系统都是如此。用这样的方式,我们可以用一种相对安全的方式进行软件部署,因为它是关着的。出于某些目的,我们可慢慢地开启该功能,先确保它是好的,然后很快地全部开启。

   

7. 你前面提到了发布,Twitter是如何发布的,能不能分享一下你们的部署流程。比如有哪些不同的阶段,是每日发布还是每周发布,或者兼而有之。

Raffi:好的。由于我们是面向服务的架构,所以在Twitter发布实际上是由每个团队自己来控制的。团队,或者是服务的拥有者要确保他们在部署代码时,每个可能受本次发布影响的人都知道他们在发布,网络控制中心也要知道他们在做什么以便能把控全局。但从根本上来说,还是由每个团队自行决定何时发布,以及是否要发布。

平均来讲,团队的部署计划基本是每周部署两到三次,有的团队每天都在做部署,有的则一个月部署一次,但是部署流程对每个人来说基本都差不多。先部署到开发环境,开发者可以在里面快速修改内容,看看产品经理,看看设计师,确保功能正确。然后,会部署到一个名为“金丝雀”的系统里,其中拥有真实的生产流量,但我们现在并不依赖它的结果。基本就是确保它能高效运作,我们会检查它返回的结果并做比较,做些预期,保证在真实的流量下它的功能和设想的一样。

我们的测试场景无法覆盖真实流量下的所有不同情况,因此这能帮助我们了解真实的测试场景是什么样的。在部署到“金丝雀”之后,我们会以关闭的状态部署上线(dark),然后慢慢开启以了解它在实际环境中的情况。开启的过程从一天到一周都有可能,我们有不同的产品,有的花了一到两周才完全开启,有的则是几分钟就完全打开了。

总之,这是由团队决定的。每个团队都为自己的功能和服务负责,因此由他们自己决定怎么去做,但是开发环境、金丝雀、暗部署和Decider开启服务这样的模式是所有人都要遵循的。

   

8. Twitter有着海量的数据,你们一定有些特殊的基础设施和方法来存储数据,甚至是实时处理数据,比如Gizzard和Snowflake。能聊聊这块东西么?

Raffi:我觉得这是两个不同的问题。其一,Twitter是一个实时系统,我们是如何存下所有这么多进入Twitter的数据的,我估算一条推文只需几毫秒就能被推送到用户那里。其二,有这么多数据,我们都对这些数据做了什么。

关于第一个问题,你是对的。我们有像Snowflake、Gizzard这样的系统来处理推文的存放问题。很明显,推文只是进入Twitter的一部分数据,我们还有诸如“喜欢”、“转发”之类的东西,还有人们发送的直接消息,改变头像、背景图片之类的。所有点击URL、加载网页等事件都会进入Twitter。

我们会收下所有内容,将其记录下来以便能进行分析。这是件很困难的事,我们有针对不同数据的不同SLA。对于推文,我们是以毫秒计的。为了对付数据库的锁,我们开发了Snowflake,它能以惊人的速度为我们生成唯一ID,并且还是去中心化的,因此在生成ID方面我们不存在单点故障。

Gizzard是用来处理数据流入并尽快分片的,有了它,系统中的不同集群间不会有热点,它会尽可能分散负载,以确保在大数据流入Twitter时数据库不会过载。再重申一下,推文能很快被系统处理掉。

再说说日志,人们进行点击、查看推文,这是以分钟计的,不是毫秒,所以它会进入另一条完全不同的处理管道。如今日志大多是用Scribe来处理的,它们缓慢地流过系统,被聚合、收集并导入HDFS,以便后续能做分析。

从长期保存的角度看,无论是实时与否,最后都会落到HDFS,我们会执行大量MapReduce任务和Hadoop任务,真正了解系统正在发生什么。

我们试图达到一种平衡,什么是眼下需要关心的,尤其是数据涌入得很快;还有在哪里保存数据,因为数据累积得很快,比如每天会生成4亿推文,而Twitter已经运行了好几年了,你可以想象我们的数据量有多大。HDFS在帮我们处理这些东西,在HDFS上我们能运行大量的MapReduce任务。

   

9. Twitter是个工程师向往的地方,那么一个工程师在Twitter的成长路线会是什么样的?如何成为一个像你一样成功的极客,能否给大家一些建议呢?

Raffi:呃,我现在不算是个成功的工程师,因为我已经不写代码了。我是以工程师的身份加入Twitter的,一路走到现在的位置,管理着很多工程师。

Twitter有着不少不同的哲学和思路,但我们有一条工程师的职业发展路线,基本就是处理越来越难的问题。它实际上和你构建的功能运行效果如何关系不大,当然有些情况下它们会有关系,但更多的是你在从事的项目中运用的技术想法和技术价值的水平。

在Twitter中成长基本是在对等(peer-based)的机制下进行的。比方说让我们具体来聊聊晋升,在Twitter我们是不是该让某个工程师从一个级别晋升到下一个级别呢?这事需要合议,也不能算是合议,但要求在那更高一级的一堆工程师能认可,你完成了能够晋升到这一级的工作。

为了帮助工程师成长,主管要保证那些在寻求更大挑战的工程师能找到合适的项目。工程师可以在不同团队间流动,而不是定死在某个团队里,比如推文团队或时间线团队。如果一个工程师说“我想要去移动团队,因为那里很有意思,我觉得那是我的职业发展方向。”事实上,我个人作为管理者的工作就是让这事能成真。你在Twitter基本能做任何事,我告诉你我在工程管理方面的优先级,也会告诉你公司的优先级,有用户增长,有多少营收,你要做什么功能。而工程师应该去那些他认为自己能够产生最大影响的项目中去。

在此之上,我在Twitter开设了一个小的大学,我们称之为Twitter大学。那是一群全职负责培训的人。比方说如果有个工程师想要加入移动团队,但他是后端Java工程师,我们会说“太好了,我们有个培训课程,你可以学到Android或iOS开发,上一周的课你就能有向代码库提交代码的水平了,然后你就能真正加入那个团队了。”Twitter大学给了你在Twitter拓展视野的途径,你也可以安全地决定是否要去尝试新的东西。

我们在工程师身上投入心血,是因为他们是公司的支柱。工程师们打造了Twitter赖以成长的东西,打造了全世界都在使用的东西。因此我会尽我所能为他们提供机会去尝试不同的东西,探索不同的方向。

你可能感兴趣的:(探秘Twitter的应急预案、部署流程与新架构)