2019独角兽企业重金招聘Python工程师标准>>>
《空中之城》事件
在构建Twitter的架构和系统时,我们是以周为单位来确定那些系统的性能的,我们能清楚地知道每个服务维度的系统理论容量,从而尝试去了解整个系统的理论容量。基于这些信息,我们能够判断:(1)在任何时间点,我们是否都拥有合适数量的生产服务器,还是需要购买更多的机器。(2)我们可以理性地判断系统是否有效工作
应急预案
1、“运行手册”,在紧急情况下我们清楚地知道该做什么。我们考虑了各种不同类型的故障,虽然没有面面俱到,但至少考虑到了大多数常见情况,落实到文档里
2、总是对生产系统进行测试,所以能很清楚地知道当系统出问题时会是什么样的。我们可以做些演练。比如让系统出问题,团队成员待命
3、我们在数据中心里随机杀掉几台服务器,确保在此期间服务不会发生抖动
代码结构
不是大而全的代码库,而是由不同服务组成Twitter。Twitter的每段业务逻辑、每个功能都找到真正的拥有者。我们把东西都分开了,不仅有了不同方向的专家,这还让我们可以做到故障隔离,功能开发时的隔离。如果你想修改推文相关的东西,只需要修改特定的几个系统,不再需要修改整个Twitter。因此我们对故障和开发都有了良好的隔离性
Decider
Decider是Twitter的一个运行时配置机制,我们可以在不用执行部署的情况下关闭某些特性或者软件。Twitter中的每个服务都会不断地查看Decider系统,了解Twitter目前的运行值。以发现页为例,Decider实际上有一个针对它的值,这个值会告诉发现页此时此刻究竟该开启还是关闭。
因此我可以将发现页部署到Twitter上,但是通过Decider将其状态置为关闭。这能让我们避免不一致的状态。仍以发现页为例,它是运行在多台服务器上的,任何Twitter的功能都是如此。它不是运行在一台服务器上的,你不希望有不一致的状态,某些服务器上部署了该功能,而另一些则没有。我们可以通过Decider将其部署为关闭状态,在需要打开时,所有机器都会变为开启状态,我们只要轻击Decider的开关就能原子化地在数据中心里所有的服务器上开启该功能。
部署流程
我们是面向服务的架构,所以在Twitter发布实际上是由每个团队自己来控制的。团队,或者是服务的拥有者要确保他们在部署代码时,每个可能受本次发布影响的人都知道他们在发布,网络控制中心也要知道他们在做什么以便能把控全局。但从根本上来说,还是由每个团队自行决定何时发布,以及是否要发布。
平均来讲,团队的部署计划基本是每周部署两到三次,有的团队每天都在做部署,有的则一个月部署一次,但是部署流程对每个人来说基本都差不多。先部署到开发环境,开发者可以在里面快速修改内容,看看产品经理,看看设计师,确保功能正确。然后,会部署到一个名为“金丝雀”的系统里,其中拥有真实的生产流量,但我们现在并不依赖它的结果。基本就是确保它能高效运作,我们会检查它返回的结果并做比较,做些预期,保证在真实的流量下它的功能和设想的一样。
我们的测试场景无法覆盖真实流量下的所有不同情况,因此这能帮助我们了解真实的测试场景是什么样的。在部署到“金丝雀”之后,我们会以关闭的状态部署上线(dark),然后慢慢开启以了解它在实际环境中的情况。开启的过程从一天到一周都有可能,我们有不同的产品,有的花了一到两周才完全开启,有的则是几分钟就完全打开了。
总之,这是由团队决定的。每个团队都为自己的功能和服务负责,因此由他们自己决定怎么去做,但是开发环境、金丝雀、暗部署和Decider开启服务这样的模式是所有人都要遵循的。
处理推文的存放
我们有针对不同数据的不同SLA。对于推文,我们是以毫秒计的。为了对付数据库的锁,我们开发了Snowflake,它能以惊人的速度为我们生成唯一ID,并且还是去中心化的,因此在生成ID方面我们不存在单点故障。
Gizzard是用来处理数据流入并尽快分片的,有了它,系统中的不同集群间不会有热点,它会尽可能分散负载,以确保在大数据流入Twitter时数据库不会过载。再重申一下,推文能很快被系统处理掉。
再说说日志,人们进行点击、查看推文,这是以分钟计的,不是毫秒,所以它会进入另一条完全不同的处理管道。如今日志大多是用Scribe来处理的,它们缓慢地流过系统,被聚合、收集并导入HDFS,以便后续能做分析。
从长期保存的角度看,无论是实时与否,最后都会落到HDFS,我们会执行大量MapReduce任务和Hadoop任务,真正了解系统正在发生什么。