在 Facebook,我是這樣做運維的
作者簡介
譚芝蘭
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月活人數超過20億的訊息。20億人每天所產生的資料從幾年前的文字為主到圖片再到今天的視訊,資料以數十倍的速度增長,而使用者資料相對於內部的機器與機器之間的資料傳輸,實際上還只是冰山一角,尤其是大資料計算平臺,資料儲存和傳輸是使用者原始資料的幾何倍數。市場上現有的技術都不能支撐我們面臨的規模的擴充套件。我們怎樣來面對這樣的挑戰?
近幾年以來計算機CPU速度已經沒有象摩爾定律所說的成倍增長,計算的擴充套件來自於橫向擴充套件分散式的計算架構。在分散式計算系統裡面計算機單機的設計和容量都往簡單和小型單元發展。我們擴充套件大資料計算容量對於從網路到儲存(storage)到計算(compute)叢集的設計都有了一個全新的思路。
在這裡我們介紹一下Facebook分解式大資料計算架構的多個層面,也就是分解式網路系統(disaggregated network),分解式儲存系統(disaggregated storage), 以及以Spark為例的分解式計算系統(disaggregated compute, Spark)。
二、分解式的概念
分解式計算的理念,大致就是用通用機替代定製機; 硬體和軟體單獨開發替代軟硬體同步開發;計算和儲存分離替帶計算儲存共存。
在這種情況下,分解式的優點是:軟體和硬體分別以各自的步調升級。其次,計算和儲存分離,這就允許我們把compute和storage分開來擴充套件, storage可以在分級為cold storage和warm storage, 計算cluster則可以用high memory,high CPU機型來組成。
三、分解式的網路
有高可靠,無瓶頸,大容量,易管理等優良效能。有了這個基礎可以讓計算分離成為現實。
在上一代的網路架構裡,如上圖我們建立叢集來作為網路的組成單位。為了加強可靠性,一個叢集由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。
現在,新型的The Fabric架構是網狀的架構。而傳統的結構是金字塔型的,其頂端必然是一個瓶頸。在這樣一個網狀的網路裡,它是在Rack switch、Fabric switch的上面和之間全部都是網狀結構。
我們所得到的結果從這一端的Server到另一端的Server,兩者之間如果要傳輸資料,它有多條通道。在多條通道里,當任何一個節點壞掉或者多個節點壞掉,對於整個的傳輸沒有任何的影響;而且可以做到在幾十萬臺機器之間相互的傳輸,沒有瓶頸。
上述途中所說的一個模組叫做一個Pod。Fabric switch和spine switch所用的部件都是通用部件。網路的部署是以pod為單位,如果需要擴建,我們只要直接加一個Pod就可以了。如果需要在Fabric內部增加頻寬,就再增加uplink。上述的網路基礎就給我們的計算和儲存帶來了一個可獨立維護,獨立擴建的結構。
四、分解式的儲存
在過去的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打了一個基礎
在這裡我只舉一個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裡,傳統的整合式方法還是適用的。
原文來自微信公眾號:高效運維