60 TB 數據:Facebook 是如何大規模使用 Apache Spark 的-36大數據
作者 | Sital Kedia, 王碩杰, Avery Ching
Apache Spark 于 2009 年在加州大學伯克利分校的 AMPLab 由 Matei Zaharia 發起,后來在2013 年貢獻給 Apache。它是目前增長最快的數據處理平臺之一,由于它能支持流、批量、命令式(RDD)、聲明式(SQL)、圖數據庫和機器學習等用例,而且所有這些都內置在相同的 API 和底層計算引擎中。
— Sital Kedia, 王碩杰, Avery Ching
Facebook 經常使用數據驅動的分析方法來做決策。在過去的幾年,用戶和產品的增長已經需要我們的分析工程師一次查詢就要操作數十 TB 大小的數據集。我們的一些批量分析執行在古老的 Hive[1] 平臺( Apache Hive 由 Facebook 貢獻于 2009 年)和 Corona[2] 上——這是我們定制的 MapReduce 實現。
Facebook 還不斷增加其對 Presto 的用量,用于對幾個包括 Hive 在內的內部數據存儲的 ANSI-SQL 查詢。我們也支持其他分析類型,比如圖數據庫處理graph processing和機器學習(Apache Giraph[3])和流(例如:Puma[4]、Swift[5] 和 Stylus[6])。
同時 Facebook 的各種產品涵蓋了廣泛的分析領域,我們與開源社區不斷保持溝通,以便共享我們的經驗并從其他人那里學習。Apache Spark[7] 于 2009 年在加州大學伯克利分校的 AMPLab 由 Matei Zaharia 發起,后來在2013 年貢獻給 Apache。它是目前增長最快的數據處理平臺之一,由于它能支持流、批量、命令式(RDD)、聲明式(SQL)、圖數據庫和機器學習等用例,而且所有這些都內置在相同的 API 和底層計算引擎中。
Spark 可以有效地利用更大量級的內存,優化整個流水線pipeline中的代碼,并跨任務重用 JVM 以獲得更好的性能。最近我們感覺 Spark 已經成熟,我們可以在一些批量處理用例方面把它與 Hive 相比較。在這篇文章其余的部分,我們講述了在擴展 Spark 來替代我們一個 Hive 工作任務時的所得到經驗和學習到的教訓。
用例:實體排名的特征準備
Facebook 會以多種方式做實時的實體entity排名。對于一些在線服務平臺,原始特征值是由 Hive 線下生成的,然后將數據加載到實時關聯查詢系統。
我們在幾年前建立的基于 Hive 的老式基礎設施屬于計算資源密集型,且很難維護,因為其流水線被劃分成數百個較小的 Hive 任務。為了可以使用更加新的特征數據和提升可管理性,我們拿一個現有的流水線試著將其遷移至 Spark。
以前的Hive實現
基于 Hive 的流水線由三個邏輯階段stage組成,每個階段對應由 entity_id 劃分的數百個較小的 Hive 作業,因為在每個階段運行大型 Hive 作業job不太可靠,并受到每個作業的最大任務task數量的限制。
這三個邏輯階段可以總結如下:
- 過濾出非產品的特征和噪點。
- 在每個(entity_id, target_id)對上進行聚合。
- 將表格分割成 N 個分片,并通過自定義二進制文件管理每個分片,以生成用于在線查詢的自定義索引文件。
基于 Hive 的流水線建立該索引大概要三天完成。它也難于管理,因為該流水線包含上百個分片的作業,使監控也變得困難。同時也沒有好的方法來估算流水線進度或計算剩余時間。考慮到 Hive 流水線的上述限制,我們決定建立一個更快、更易于管理的 Spark 流水線。
Spark實現
全量的調試會很慢,有挑戰,而且是資源密集型的。我們從轉換基于 Hive 流水線的最資源密集型的第二階段開始。我們以一個 50GB 的壓縮輸入例子開始,然后逐漸擴展到 300GB、1TB,然后到 20TB。在每次規模增長時,我們都解決了性能和穩定性問題,但是實驗到 20TB 時,我們發現了最大的改善機會。
運行 20TB 的輸入時,我們發現,由于大量的任務導致我們生成了太多輸出文件(每個大小在 100MB 左右)。在 10 小時的作業運行時中,有三分之一是用在將文件從階段目錄移動到 HDFS 中的最終目錄。
起初,我們考慮兩個方案:要么改善 HDFS 中的批量重命名來支持我們的用例,或者配置 Spark 生成更少的輸出文件(這很難,由于在這一步有大量的任務 — 70000 個)。我們退一步來看這個問題,考慮第三種方案。
由于我們在流水線的第二步中生成的 tmp_table2 表是臨時的,僅用于存儲流水線的中間輸出,所以對于 TB 級數據的單一讀取作業任務,我們基本上是在壓縮、序列化和復制三個副本。
相反,我們更進一步:移除兩個臨時表并整合 Hive 過程的所有三個部分到一個單獨的 Spark 作業,讀取 60TB 的壓縮數據然后對 90TB 的數據執行重排shuffle和排序sort。最終的 Spark 作業如下:
對于我們的作業如何規劃Spark?
當然,為如此大的流水線運行一個單獨的 Spark 任務,第一次嘗試沒有成功,甚至是第十次嘗試也沒有。
據我們所知,從重排shuffle的數據大小來說,這是現實世界最大的 Spark 作業(Databrick 的 PB 級排序[8]是以合成數據來說)。我們對核心 Spark 基礎架構和我們的應用程序進行了許多改進和優化使這個作業得以運行。這種努力的優勢在于,許多這些改進適用于 Spark 的其他大型作業任務,我們將所有的工作回饋給開源 Apache Spark 項目 – 有關詳細信息請參閱 JIRA。
下面,我們將重點講述將實體排名流水線之一部署到生產環境所做的重大改進。
可靠性修復
處理頻繁的節點重啟
為了可靠地執行長時間運行作業,我們希望系統能夠容錯并可以從故障中恢復(主要是由于平時的維護或軟件錯誤導致的機器重啟所引發的)。雖然 Spark 設計為可以容忍機器重啟,但我們發現它在足夠強健到可以處理常見故障之前還有各種錯誤/問題需要解決。
其他的可靠性修復
任務是很困難的。Spark 執行程序會內存溢出,因為排序程序(sorter)中存在導致無限增長的指針數組的漏洞。當不再有可用的內存用于指針數組增長時,我們通過強制將數據溢出到磁盤來修復問題。因此,現在我們可以每主機運行 24 個任務,而不會內存溢出。
性能改進
在實施上述可靠性改進后,我們能夠可靠地運行 Spark 作業了。基于這一點,我們將精力轉向與性能相關的項目,以充分發揮 Spark 的作用。我們使用 Spark 的指標和幾個分析器來查找一些性能瓶頸。
我們用來查找性能瓶頸的工具
性能優化
在所有這些可靠性和性能改進之后,我們很高興地報告,我們為我們的實體排名系統之一構建和部署了一個更快、更易于管理的流水線,并且我們提供了在 Spark 中運行其他類似作業的能力。
Spark流水線與Hive流水線性能對比
我們使用以下性能指標來比較 Spark 流水線與 Hive 流水線。請注意,這些數字并不是在查詢或作業級別的直接比較 Spark 與 Hive ,而是比較使用靈活的計算引擎(例如 Spark)構建優化的流水線,而不是比較僅在查詢/作業級別(如 Hive)操作的計算引擎。
CPU 時間:這是從系統角度看 CPU 使用。例如,你在一個 32 核機器上使用 50% 的 CPU 10 秒運行一個單進程任務,然后你的 CPU 時間應該是 32 * 0.5 * 10 = 160 CPU 秒。
CPU 預留時間:這是從資源管理框架的角度來看 CPU 預留。例如,如果我們保留 32 位機器 10 秒鐘來運行作業,則CPU 預留時間為 32 * 10 = 320 CPU 秒。CPU 時間與 CPU 預留時間的比率反映了我們如何在集群上利用預留的CPU 資源。
當準確時,與 CPU 時間相比,預留時間在運行相同工作負載時可以更好地比較執行引擎。例如,如果一個進程需要 1 個 CPU 的時間才能運行,但是必須保留 100 個 CPU 秒,則該指標的效率要低于需要 10 個 CPU 秒而僅保留 10 個 CPU 秒來執行相同的工作量的進程。
我們還計算內存預留時間,但不包括在這里,因為其數字類似于 CPU 預留時間,因為在同一硬件上運行實驗,而在 Spark 和 Hive 的情況下,我們不會將數據緩存在內存中。Spark 有能力在內存中緩存數據,但是由于我們的集群內存限制,我們決定類似與 Hive 一樣工作在核心外部。
等待時間:端到端的工作流失時間。
結論和未來工作
Facebook 的性能和可擴展的分析在產品開發中給予了協助。Apache Spark 提供了將各種分析用例統一為單一 API 和高效計算引擎的獨特功能。
我們挑戰了 Spark,來將一個分解成數百個 Hive 作業的流水線替換成一個 Spark 作業。通過一系列的性能和可靠性改進之后,我們可以將 Spark 擴大到處理我們在生產中的實體排名數據處理用例之一。
在這個特殊用例中,我們展示了 Spark 可以可靠地重排和排序 90 TB+ 的中間數據,并在一個單一作業中運行了 25 萬個任務。 與舊的基于 Hive 的流水線相比,基于 Spark 的流水線產生了顯著的性能改進(4.5-6 倍 CPU,3-4 倍資源預留和大約 5 倍的延遲),并且已經投入使用了幾個月。
雖然本文詳細介紹了我們 Spark 最具挑戰性的用例,越來越多的客戶團隊已將 Spark 工作負載部署到生產中。 性能 、可維護性和靈活性是繼續推動更多用例到 Spark 的優勢。 Facebook 很高興成為 Spark 開源社區的一部分,并將共同開發 Spark 充分發揮其潛力。
End.
轉載請注明來自36大數據(36dsj.com): 36大數據 ? 60 TB 數據:Facebook 是如何大規模使用 Apache Spark 的