在 Facebook,我是这样做运维的_JAVA

作者 | 谭芝兰
编辑 | 济萌

作者简介

在 Facebook,我是这样做运维的_JAVA_02

谭芝兰

Facebook TechLead

在硅谷从事运维工作10多年。2012年至2016年先后在Twitter大数据平台(Data Platform) SRE和工程效率组(Engineer Effectiveness)任职。2016年起就职于Facebook广告部门,负责大数据和计算平台可靠性及性能优化等相关工作。几年来带领过的项目包括在线迁移输送价值数十亿美元数据的实时线上系统;Apace Spark @100TB Scale;持续整合线上线下大数据计算平台开发;以及不间断自动愈合服务平台。

序言

在刚刚起步的小公司,中型的Twitter以及规模庞大的Facebook做运维有什么不同?在硅谷十几年做这一行都经历了一遍。互联网时代的小公司里面做运维的人都是十项全能,在这样的环境中你的目标只有一个那就是支撑产品的运行,所有工具都可以用open source的平台,在云上搭出支架,最快实现产品的功能就是赢家。

当用户月活在十亿以上还要以每年50%以上的计算规模增长,要支撑这样的发展,我们把有限的资源放在哪里?如果规模还要增长十倍百倍呢,我们如何面这样的挑战?

本文的六个部分:

1、Facebook在可扩展中面临的挑战;

2、分解式的概念;

3、分解式的网络;

4、分解式的存储;

5、使用温数据存储(Warm Storage)的spark;

6、总结。

一、Facebook在可扩展中面临的挑战

在 Facebook,我是这样做运维的_JAVA_03

在几个星期以前,扎克伯格发布了Facebook月活人数超过20亿的消息。20亿人每天所产生的数据从几年前的文本为主到图片再到今天的视频,数据以数十倍的速度增长,而用户数据相对于内部的机器与机器之间的数据传输,实际上还只是冰山一角,尤其是大数据计算平台,数据存储和传输是用户原始数据的几何倍数。市场上现有的技术都不能支撑我们面临的规模的扩展。我们怎样来面对这样的挑战?

近几年以来计算机CPU速度已经没有象摩尔定律所说的成倍增长,计算的扩展来自于横向扩展分布式的计算架构。在分布式计算系统里面计算机单机的设计和容量都往简单和小型单元发展。我们扩展大数据计算容量对于从网络到存储(storage)到计算(compute)集群的设计都有了一个全新的思路。

在这里我们介绍一下Facebook分解式大数据计算架构的多个层面,也就是分解式网络系统(disaggregated network),分解式存储系统(disaggregated storage), 以及以Spark为例的分解式计算系统(disaggregated compute, Spark)。

二、分解式的概念

在 Facebook,我是这样做运维的_JAVA_04

分解式计算的理念,大致就是用通用机替代定制机; 硬件和软件单独开发替代软硬件同步开发;计算和存储分离替带计算存储共存。

在这种情况下,分解式的优点是:软件和硬件分别以各自的步调升级。其次,计算和存储分离,这就允许我们把compute和storage分开来扩展, storage可以在分级为cold storage和warm storage, 计算cluster则可以用high memory,high CPU机型来组成。

三、分解式的网络

在 Facebook,我是这样做运维的_JAVA_05

Facebook的分解式网络架构名为Fabric。它是Facebook数据中心核心网,这个强大的内网具有高可靠,无瓶颈,大容量,易管理等优良性能。有了这个基础可以让计算分离成为现实。

在上一代的网络架构里,如上图我们建立集群来作为网络的组成单位。为了加强可靠性,一个集群由3+1 CSW(Cluster Switch)组成, 多个TOR(Top of Rack)连到一组CSW 成为一个集群。

其可靠性取决于CSW的冗余倍数。一个CSW坏了,其他三个CSW可以支撑集群继续工作。它的局限性在于:我们不能无限制的扩大CSW的容量。集群大小完全取决于交换器的容量,一个集群可以达到1000台或者几千台机器。如果一个交换机坏掉了,对一个集群容量影响非常大,而且定制的大规模交换机维护起来困难。

当计算集群(compute cluster)容量超出网络集群(network cluster)范围时,网络就成为了瓶颈。现在很多的应用已经超过了网络集群范围,比如一个Spark或者Hadoop cluster一般超过几千台、上万台机器,computing cluster远远大于network cluster。

在 Facebook,我是这样做运维的_JAVA_06

现在,新型的The Fabric架构是网状的架构。而传统的结构是金字塔型的,其顶端必然是一个瓶颈。在这样一个网状的网络里,它是在Rack switch、Fabric switch的上面和之间全部都是网状结构。

我们所得到的结果从这一端的Server到另一端的Server,两者之间如果要传输数据,它有多条通道。在多条通道里,当任何一个节点坏掉或者多个节点坏掉,对于整个的传输没有任何的影响;而且可以做到在几十万台机器之间相互的传输,没有瓶颈。

上述途中所说的一个模块叫做一个Pod。Fabric switch和spine switch所用的部件都是通用部件。网络的部署是以pod为单位,如果需要扩建,我们只要直接加一个Pod就可以了。如果需要在Fabric内部增加带宽,就再增加uplink。上述的网络基础就给我们的计算和存储带来了一个可独立维护,独立扩建的结构。

四、分解式的存储

在 Facebook,我是这样做运维的_JAVA_07

在过去的Hadoop计算结构中,提高性能的方法是data locality。如果我的数据在一台机器上,我尽量用算法把我的计算单位放在数据单位同样一台机器上,这样来减少网络传输和增加performance。在分解式的计算中,由于网络的巨大的容量,我们可以做到运算在一个集群,而存储在另外一个集群。

另外比如机器设置的问题,在Hadoop的Cluster 里面,如果一台机器设置是40个cpu、128G的memory,这是一个固定的比例。如果想单独增加运算的容量或者存储的容量就非常困难。

传统的计算存储共存的方法对于硬盘的可靠性要求较高,硬盘损坏率对于计算可靠性有直接的关系。而分解式计算中网络的带宽和延迟都完全超过了local disk;所以网络不再是一个瓶颈,而且分离式存储可以对个体硬盘损坏有极强的抵抗力。

五、使用温数据存储(Warm Storage)的spark

Facebook内部用自己开发的Warm storage。Warm Storage 是一个分布式数据存储系统。我们在不需要考虑计算配置的情况下可以专门对Warm Storage进行一个硬件配置。在Hive 和spark这样的计算平台里,storage的最大瓶颈是iops(IO per second)。

在计算的时候,如果每一个IO数据特别小的话,这个IOps就会成为一个大问题。在local disk high io queue 情况下,p99 的IO延迟可以高达几秒钟的时间。Warm Storage对此做了很多的优化,它对于large io size,small io size做了针对性的优化,而且整体可靠性对于个别硬盘损坏的抵抗力极强。

前面讲了分解式网络和存储为下面的要讲的分解式的Spark打了一个基础

在 Facebook,我是这样做运维的_JAVA_08

在这里我只举一个Spark系统中的一个例子。Spark计算中在map和reduce之间有一个 Shuffle的步骤。当map stage完成的时候,中间步骤数据存储在当地机器的硬盘上等待stage2的机器前来读取,如果这时当地硬盘坏掉,这个单元的计算就必须回到Stage1,叫做retry。

这个步骤里一个硬盘损坏可以直接影响到Spark的稳定性和执行速度。而且在job越大的时候(比如我们的job经常是以年CPU时间计算的),其retry机率就会越大的;哪怕是硬盘的损坏率是1%或者0.5%,这个retry机率都会非常大,到mapper或reducer有几万个的时候基本上Spark就不能用了。

Spark以前是和HDFS共存在一个计算集群上的。HDFS跑的是数据的存储,Spark跑的是运算。这个想法很好,存储是用它的硬盘,运算是用它的CPU和memory。但是,实际上并非如此:在我们使用的过程当中发现Spark和HDFS之间相互竞争IO的资源,经常Spark的performance受到HDFS的影响。

硬件设置也受到限制,比如:40个CPU和128G的memory,每一个mapper的memory size 非常小的。如果说运算输入的数据比memory size更大,就会spill,也就是部分数据由内存暂时写到硬盘上。spill对于performance有极大的影响。

最近我们采用了Spark with Warm Storage的架构 因为有了网络的基础我们可以分开来scale计算单元。计算单元机器用高配置的memory和CPU,但是只有一个localdisk。计算单元通过网络读写数据到warm storage 集群。要扩展计算容量也会变得非常容易。

以前如果我们想要维护一个Spark的机器,需要等待HDFS排流。就是说,你想要把一台机器移出来,必须让它的数据移到另外一台机器上才可以将它下架。但是,通过Spark with Warm Storage,我们就不再需要考虑它的排流。

改用Spark with Warm Storage以后,其基本运算速度与传统方法相当或更快,但可靠性相对于local disk提高了4倍。

分解式的方法对于计算的Scalability有决定性的作用,而且不仅仅是说对一个feature做什么改变,而是对整个系统做非常根本的改变。

六、总结

在极大规模的环境下,分解式理念真正帮我们解决了Scalability的问题。但是并不是每一个场景都适合。在相对小的Scale里,传统的集成式方法还是适用的。