介紹三個最主流的分布式計算框架Apache Spark、Dask和Ray的歷史、用途和優缺點
以便了解如何選擇最適合特定數據科學用例的框架。
1 歷史
1.1 Apache Spark
Spark是由Matei Zaharia于2009年在加州大學伯克利分校的AMPLab啟動的。這個項目的主要目的是加快分布式大數據任務的執行,在那個時候,這些任務是由Hadoop MapReduce處理的。MapReduce在設計時考慮到了可擴展性和可靠性,但性能和易用性一直不是它的強項。MapReduce需要不斷將中間結果存儲到磁盤,這是Spark要克服的關鍵障礙。Spark通過引入彈性分布式數據集(RDD)范式,并利用內存緩存和惰性計算的優勢,能夠比MapReduce減少幾個數量級的延遲。這使Spark確立了其作為大規模、容錯、并行化數據處理的事實標準的主導地位。該項目通過添加GraphX(用于分布式圖形處理)、MLlib(用于機器學習)、SparkSQL(用于結構化和半結構化數據)等功能得到進一步加強。 值得注意的是,Spark是用Scala編寫的,后來又增加了對Python/ target=_blank class=infotextkey>Python和R的支持,因此與它互動一般不會有Pythonic的感覺。理解RDD范式和Spark中的工作方式需要一點時間來適應,但這對任何熟悉Hadoop生態系統的人來說通常不是問題。
1.2 Dask
Dask是一個用于并行計算的開源庫,它在2015年發布,所以與Spark相比,它相對較新。該框架最初是由Continuum Analytics(現在的Anaconda Inc.)開發的,他們是許多其他開源Python包的創造者,包括流行的Anaconda Python發行。Dask的最初目的只是為了將NumPy并行化,這樣它就可以利用具有多個CPU和核心的工作站計算機。與Spark不同,Dask開發中采用的最初設計原則之一是 "無發明"。這一決定背后的想法是,使用Dask的工作應該讓使用Python進行數據分析的開發者感到熟悉,而且升級時間應該最小。根據其創造者的說法,Dask的設計原則經過多年的發展,現在正被開發成一個用于并行計算的通用庫。
最初圍繞并行NumPy的想法得到進一步發展,包括一個完整而輕量級的任務調度器,可以跟蹤依賴關系,并支持大型多維數組和矩陣的并行化。后來又增加了對Pandas DataFrames和scikit-learn并行化的支持。這使該框架能夠緩解Scikit中的一些主要痛點,如計算量大的網格搜索和太大無法完全容納在內存中的工作流程。最初的單機并行化目標后來被分布式調度器的引入所超越,這使Dask能夠在多機多TB的問題空間中舒適地運行。
1.3 Ray
Ray是加州大學伯克利分校的另一個項目,其使命是 "簡化分布式計算"。Ray由兩個主要部分組成--Ray Core,它是一個分布式計算框架,而Ray Ecosystem,廣義上講是一些與Ray打包的特定任務庫(例如Ray Tune--一個超參數優化框架,RaySGD用于分布式深度學習,RayRLib用于強化學習,等等)。
Ray與Dask類似,它讓用戶能夠以并行的方式在多臺機器上運行Python代碼。然而,與Dask不同的是,Ray并不模仿NumPy和Pandas的API--它的主要設計目標不是為數據科學工作做一個落地的替代品,而是為Python代碼的并行化提供一個通用的低層次框架。Ray更像是一個通用的集群和并行化框架,可以用來構建和運行任何類型的分布式應用。由于Ray Core的架構方式,它經常被認為是一個構建框架的框架。也有越來越多的項目與Ray集成,以利用加速的GPU和并行計算。 spaCy、Hugging Face和XGBoost都是引入Ray互操作性的第三方庫的例子。
2 選擇正確的框架
這里沒有簡單明了的方法來選擇 "最佳 "框架,就像每個復雜的問題一樣,答案在很大程度上取決于我們具體工作流程中的背景和許多其他因素。我們需要逐個看看這三個框架,分析它們的優劣勢,同時考慮到各種常見的使用情況進行選擇。
2.1 Spark
優點:
成熟穩定:Spark 的原始版本發布于2014年5月,是比較成熟的技術。 商業支持:大量的公司提供商業支持/服務。 處理大數據集:適用于針對大型數據集進行數據工程/ ETL 類型的任務。 提供高級 SQL 抽象層(Spark SQL)。 弊端:
需要學習新的執行模型和API,學習曲線陡峭。 調試困難。 復雜的架構,僅靠IT部門很難維護,因為適當的維護需要了解計算范式和Spark的內部運作(如內存分配)。 缺少豐富的數據可視化生態系統。 沒有內置的GPU加速,需要RAPIDS加速器來訪問GPU資源。
2.2 Dask
優點:
純Python框架,非常容易上手。 直接支持Pandas DataFrames和NumPy數組。 通過Datashader輕松實現對數十億行的探索性數據分析。 提供Dask Bags--它是PySpark RDD的Python版本,具有map、filter、groupby等功能。 Dask能夠帶來令人印象深刻的性能改進。 2020年6月,Nvidia使用RAPIDS、Dask和UCX在16個DGX A100系統(128個A100 GPU)上進行TPCx-BB測試,取得了驚人的結果。但是,需要謹慎對待,因為2021年1月,TPC強制Nvidia將該結果下架,因為它們違反了TPC的公平使用政策。 弊端:
缺乏商業支持(但有幾家公司已開始在此領域的工作,例如Coiled和QuanSight)。 沒有內置的GPU支持,依賴于RAPIDS進行GPU加速。
2.3 Ray
優點:
最小的集群配置 最適合于計算密集型工作負載。已經有證據表明,Ray在某些機器學習任務上的表現優于Spark和Dask,如NLP、文本規范化和其他。此外,Ray的工作速度比Python標準多處理快10%左右,即使是在單節點上也是如此。 因為Ray正被越來越多地用于擴展不同的ML庫,所以你可以以可擴展的、并行的方式一起使用所有的ML庫。另一方面,Spark將你限制在它的生態系統中可用的框架數量明顯減少。 獨特的基于actor的抽象,多個任務可以在同一個集群上異步工作,從而實現更好的利用率(相比之下,Spark的計算模型不太靈活,基于并行任務的同步執行)。 弊端:
相對較新(2017年5月首次發布)。 不太適合分布式數據處理。Ray沒有用于分區數據的內置原語。該項目剛剛引入了Ray Datasets,但這是一個全新的補充,仍然非常新且基礎。 對GPU的支持僅限于調度和預留。由遠程函數來實際利用GPU(通常通過外部庫,如TensorFlow和PyTorch)。 從這三個框架的優缺點出發,我們可以提煉出以下選擇標準:
如果工作負載是以數據為中心的,主要是ETL/預處理方面的工作,那么我們最好選擇Spark。特別是如果該組織擁有Spark API的機構知識。 Dask/Ray的選擇并不那么明確,但一般的規則是,Ray旨在加速任何類型的Python代碼,而Dask是面向數據科學特定的工作流程。 為了讓事情變得更加復雜,還有Dask-on-Ray項目,它允許你在不使用Dask分布式調度器的情況下運行Dask工作流。 為了更好地理解Dask-on-Ray試圖填補的空白,我們需要看一下Dask框架的核心組件。這些是集合抽象(DataFrames,數組等),任務圖(DAG,表示類似于Apache Spark DAG的操作集合),以及調度器(負責執行Dask圖)。分布式調度器是Dask中可用的調度器之一,它負責協調分布在多臺機器上的若干工作進程的行動。這個調度器很好,因為它設置簡單,保持最小的延遲,允許點對點的數據共享,并支持比簡單的map-reduce鏈復雜得多的工作流。另一方面,分布式調度程序并非沒有缺點,它的缺點包括:
它是一個單點故障--分布式調度器沒有高可用性機制,因此如果它發生故障,整個集群需要重置,所有正在進行的任務都會丟失。 它是用Python編寫的,這使得它易于安裝和調試,但也會引入通常與Python搭配使用的標準性能考慮因素。 Client API是為數據科學家設計的,并不適合從高可用性的生產基礎設施中調用(例如,它假定客戶是長期存在的,可能從Jupyter會話中與集群一起工作)。 它對有狀態執行提供的支持很少,所以很難實現容錯的流水線。 它可能會成為瓶頸,并且不能本地擴展。 相比之下,容錯和性能是深深嵌入Ray調度器設計中的原則。它是完全分散的(沒有瓶頸),提供更快的數據共享(通過Apache Plasma),各個調度器是無狀態的(容錯),支持有狀態的Actor等。這使得在Ray集群上運行Dask任務的吸引力非常明顯,也是Dask-on-Ray調度器存在的理由。
3 如何做出選擇
現在我們已經看過了Spark、Dask和Ray的優缺點--并簡要討論了Dask-on-Ray混合解決方案,很明顯這不是“一刀切”的情況。這三個框架從一開始就有不同的設計目標,試圖把根本不同的工作流程硬塞到其中一個框架中不是最明智的選擇。更好的方法是以靈活性為基礎設計數據科學流程和相應的基礎架構,最好能夠讓您啟動并使用適合工作的正確工具。一個典型的流程可能涉及在Spark中進行一些類似ETL的數據處理,然后在Ray中執行機器學習工作流。提供自由度以控制、容錯和按需方式運行兩個框架,使數據科學團隊能夠利用兩個框架的優勢。
從Spark(DataFrames)到Ray(分布式訓練)再返回到Spark(Transformer)的流程的高級概述。Ray Estimator在Spark Estimator接口中封裝了這種復雜性。
混合使用框架的重要性已經顯而易見,因為出現了使這種跨框架通信更加簡化的集成庫。例如,Spark on Ray正是這樣做的--它 "結合了你的Spark和Ray集群,使你可以輕松地使用PySpark API進行大規模數據處理,并無縫地使用這些數據來使用TensorFlow和PyTorch訓練你的模型。"還有Ray on Spark項目,它允許我們在Apache Hadoop/YARN上運行Ray程序。這種方法也已經成功地在實際生產工作負載中得到了測試。例如,Uber的機器學習平臺Michelangelo定義了一個Ray Estimator API,該API抽象了終端用戶在Spark和Ray之間移動的過程。Uber工程公司最近的出版物中詳細介紹了這一點,該出版物涵蓋了涉及Spark和XGBoost在Ray上的分布式訓練的架構。
4 總結
在這文中,我們介紹了三種最流行的并行計算框架。我們討論了它們的優缺,并給出了一些關于如何為手頭的任務選擇正確框架的一般性指導。推薦的方法不是尋找適合所有可能的需求或用例的終極框架,而是理解它們如何適合各種工作流程,并擁有一個靈活的數據科學基礎架構,使該基礎設施允許采用混合和匹配方法。






