王軍
(西安外事學院,陜西西安,710077)
工業和研究領域數據量的增長帶來了巨大的機遇,同時也帶來了巨大的計算挑戰。由于數據規模已經超出了單機的計算能力,用戶需要新系統將計算擴展到多個計算節點。因此,針對不同計算負載的新型集群編程模型大量涌現。剛開始,這些模型相對專業化,為解決新的負載問題開發新模型。例如,MapReduce支持批處理,但Google也開發了用于交互式SQL查詢的Dremel和用于迭代圖算法的Pregel。在開源的Apache Hadoop堆棧中,Storm和Impala等系統也是為專門的運算開發的。即使在關系數據庫領域里,基本趨勢也是要避免“通用”的系統。然而現實情況中大多數大數據應用程序需要結合許多不同的處理類型。“大數據”的本質在于它是多樣性和無序性;典型的工作流程需要類似MapReduce的代碼用于數據加載、類似SQL的查詢以及迭代機器學習,使用專門的引擎會造成系統更加復雜,效率低下。為此,用戶還必須將不同的系統連接在一起,某些應用程序甚至根本無法在任何引擎中高效表達。
Spark框架編程的核心概念是彈性分布式數據集(RDDs),RDD是跨群集分區對象的容錯集合。Spark通過Scala、Java、Python和R等編程語言中的功能性API來提供RDD接口,用戶通過對自己的數據申請轉換操作(如map、filter和groupBy等)來創建RDD。Spark允許RDD為用戶的計算找到一個有效的計劃,用戶的轉換操作返回一個表示計算結果的新RDD對象,當一個動作被調用時,Spark會查看用于創建執行計劃的整個轉換圖,進而進行計算。
除了提供數據共享和各種并行操作外,RDD還可以自動從故障中恢復,因而具有很強的容錯能力。傳統的分布式計算系統通過數據復制或檢查點提供容錯功能,而Spark采用一種稱為“lineage”的方法,每個RDD跟蹤用于構建它的轉換圖,并在基礎數據上重新執行轉換操作以重建任何丟失的分區。基于lineage的恢復比數據密集型工作負載中的復制效率更高,因為通過網絡寫入數據比將數據寫入RAM以及存儲器的存儲空間要慢得多。有損節點通常包含多個RDD分區,這些分區可以在其他節點上并行重建,因而恢復通常比重新運行程序快得多。
Spark與存儲系統具有良好的集成性能。與谷歌的MapReduce很像,Spark被設計為與多個外部系統一起用于長期存儲。Spark最常用于集群文件系統,如HDFS、S3和Cassandra等的鍵值存儲,它也可以連接Apache Hive作為數據目錄。雖然Spark SQL JDBC服務器等應用程序也可以在多個用戶之間共享RDD,而RDD通常僅在應用程序中存儲臨時數據。Spark引擎與存儲系統無關的設計理念使用戶可以輕松地針對現有數據運行計算并增加多種數據源。
RDD編程模型僅提供對象和函數的分布式集合, Spark使用RDD針對許多專用計算引擎構建了各種更高級的庫。核心的思想是,控制存儲在RDD中的數據結構、跨節點的數據分區以及在其上運行的功能,就可以在其他引擎中實現許多執行操作。事實上,這些庫通常可以針對任務提供最優秀的性能,同時在庫組合使用時也具有顯著的優勢。現討論Apache Spark包含的四個主要庫。
SQL和DataFrames。數據處理中最常見的應用之一是關系查詢,Spark SQL及其前身Shark 23使用類似于分析數據庫的技術在Spark上執行關系查詢。這些系統支持列式存儲、基于成本的優化和用于查詢執行情況的代碼生成,背后的主要思想是使用與分析數據庫相同的數據布局,即壓縮列式存儲和內部RDD。在Spark SQL中,RDD中的每條記錄都包含一系列以二進制格式存儲的行數組,系統會生成代碼以直接針對這些行數組來運行。
除了運行SQL查詢之外,Spark SQL引擎為基本數據轉換DataFrames提供了更高級別的抽象,這些數據轉換是具有確定模式的RDD。DataFrames是R和Python中表格數據的常用抽象方式,用于過濾、計算和聚合新列的編程方法。在Spark中,這些操作映射到Spark SQL引擎并接收其所有優化。
Spark Streaming。Spark Streaming使用“離散化流”模型實現增量流處理。為了實現Spark的流式處理,我們將輸入數據在時間上(如每200毫秒)進行分割,再與RDD中存儲的狀態相結合來產生新結果。由于使用譜系故障恢復較為便宜,因此可以將流式傳輸與批處理和交互式查詢結合起來。
GraphX。GraphX提供了一個類似于Pregel和GraphLab的圖形計算界面,通過為其構建的RDD選擇分區功能,實現與這些系統相同的布局優化。
MLlib。MLlib是Spark的機器學習庫,實現了50多種分布式模型訓練的常用算法,包括決策樹(PLANET)、潛在狄利克雷分配和交替最小二乘矩陣分解等。
Spark庫可以在數據的所有RDD上運行,因而它們在應用程序中的組合也相對容易。由于Spark提供跨處理庫的優化功能,因此除了在API層的兼容性,Spark的庫組合在執行層也很有效。如果一個庫運行映射函數,另外一個庫在其映射結果上運行另外一個映射,則Spark將這些操作融合到一個映射中。同樣,Spark的故障恢復功能可以在這些庫中無縫連接,無論哪個庫生成它,都可以重新計算丟失的數據。
本文介紹了Apache Spark的發展歷史,并詳細介紹了編程模型并且解釋了其非常普遍的原因,針對高層庫介紹了ApacheSpark四個常用的庫,以及這些庫之間的相互調用的組合使用方法和應當注意的問題。對研究基于ApacheSpark的分布式大數據處理具有很好的參考價值。