柴 寧 吳毅堅 趙文耘
1(復旦大學軟件學院 上海 201203) 2(復旦大學計算機科學技術學院 上海 201203) 3(上海市數(shù)據(jù)科學重點實驗室 上海 200433)
近年來移動互聯(lián)網(wǎng)和社交網(wǎng)絡的發(fā)展迅速,互聯(lián)網(wǎng)上的數(shù)據(jù)開始呈指數(shù)級的增長,如何高效而快速地對數(shù)據(jù)進行處理和分析逐漸成為了研究熱點。Google公司作為擁有海量搜索數(shù)據(jù)的互聯(lián)網(wǎng)公司,于2003年至2006年提出分布式文件系統(tǒng)HDFS和函數(shù)式編程模型Map-Reduce的概念[1]。Yahoo! 公司基于二者開發(fā)了可擴展的分布式計算框架Hadoop。由于Hadoop的基于硬盤存儲數(shù)據(jù)的特點,在進行大數(shù)據(jù)集的多輪迭代運算時,硬盤的I/O和數(shù)據(jù)傳輸相對耗時,達不到相對實時的處理速度[2]。這一點在對日志監(jiān)控,機器學習算法等領域,尤為明顯。
Spark作為分布式數(shù)據(jù)處理框架,采用內(nèi)存計算的方法引入彈性數(shù)據(jù)集RDD(Resilient Distributed Datasets)[3]的概念,將數(shù)據(jù)加載到內(nèi)存里,降低了數(shù)據(jù)交換的訪問延遲,達到了準實時分析大數(shù)據(jù)集的能力。Spark框架的推廣和普及,極大地提升了分布式數(shù)據(jù)處理任務的運行效率。
然而,Spark框架本身也同樣存在了運行效率的問題,存在可優(yōu)化的空間。Spark運行大致有如下兩個問題:(1) 彈性數(shù)據(jù)集RDD帶來的內(nèi)存不足的問題。出現(xiàn)內(nèi)存不足的情況是因為Spark選擇將數(shù)據(jù)持久化到機器內(nèi)存中。這樣設計的初衷是為了減少節(jié)點中的數(shù)據(jù)交換,可以加快數(shù)據(jù)任務的處理速度。但是當單個節(jié)點需要計算的數(shù)據(jù)超過機器內(nèi)存的處理極限的時候,任務會因為內(nèi)存不足而導致失敗。(2) 數(shù)據(jù)傾斜問題導致的運行效率低下。數(shù)據(jù)集合具有不同的數(shù)據(jù)特性。如一篇文章中不同單詞出現(xiàn)的次數(shù)是不相同的。我們把上述的數(shù)據(jù)分布不均的特性稱之為數(shù)據(jù)傾斜。具有數(shù)據(jù)傾斜特性的數(shù)據(jù)在Spark框架中會導致數(shù)據(jù)在不同節(jié)點分布不均的問題。這不僅僅會影響數(shù)據(jù)處理效率,嚴重情況下也會導致任務失敗。
針對上述問題,本文提出根據(jù)不同的數(shù)據(jù)特性自適應地對Spark代碼進行優(yōu)化的思路,從而達到對Spark數(shù)據(jù)處理任務進行調(diào)優(yōu)的目的。Spark系統(tǒng)本身已具有優(yōu)化不同數(shù)據(jù)集合特性的能力,但是程序員在編寫代碼時要了解所需要處理數(shù)據(jù)集的數(shù)據(jù)特性卻并不容易。對于需要進行性能優(yōu)化的任務,優(yōu)化的步驟如下:(1) 程序自動分析代碼片段[4],生成有向無環(huán)圖(DAG);(2) 計算圖中數(shù)據(jù)的傾斜度;(3) 根據(jù)不同的數(shù)據(jù)特性和場景自動選擇生成相應的優(yōu)化方案。
目前針對Spark任務的優(yōu)化研究的主要的思路有三點。一是針對數(shù)據(jù)對象的緩存進行優(yōu)化,二是針對Spark任務的運行參數(shù)進行優(yōu)化,三是針對任務調(diào)度中的資源分配進行優(yōu)化。
通過對Spark框架內(nèi)存計算模型的研究和分析,同時對Spark框架中內(nèi)存使用行為進行建模,可以針對Spark的緩存系統(tǒng)實現(xiàn)不同程度的優(yōu)化和改進。比如實現(xiàn)Spark系統(tǒng)的緩存策略自動化,通過代碼語義分析自動識別有緩存意義的中間數(shù)據(jù)加載到緩存系統(tǒng)中。比如根據(jù)RDD的大小和權重信息,提出新的緩存算法,優(yōu)化Spark系統(tǒng)的緩存模型等[5]。
Spark框架默認的參數(shù)配置不能使得所有數(shù)據(jù)分析任務都能夠高效運行。因此可以針對不同的數(shù)據(jù)分析任務進行Spark框架的參數(shù)配置,可以優(yōu)化Spark任務的運行效率。將Spark任務的運行數(shù)據(jù)和參數(shù)配置保存到數(shù)據(jù)庫中,同時針對Spark任務進行特征工程提取任務特征,最后通過計算任務之間的相似度從數(shù)據(jù)庫中選擇合適的參數(shù)配置對任務進行優(yōu)化[6]。
Spark框架在運行數(shù)據(jù)分析任務時需要結合當前集群的資源和任務所需要的資源進行動態(tài)分配。通過完整的分析Spark框架中任務執(zhí)行過程以及資源調(diào)度分配的策略,可以根據(jù)任務運行數(shù)據(jù)提出資源調(diào)度分配優(yōu)化模型,并針對調(diào)度資源優(yōu)化提出了系統(tǒng)的解決方案[7]。
同時,目前已經(jīng)有了較多技術文章針對數(shù)據(jù)傾斜問題提出了對應的優(yōu)化策略。美團公司在技術文檔中分享了如何利用Spark框架的調(diào)度機制處理具有數(shù)據(jù)傾斜特征的數(shù)據(jù)任務,可以對Spark任務增加分區(qū)數(shù)量或者對數(shù)據(jù)進行離散化操作,也可以利用廣播變量將小數(shù)據(jù)集合分布到各個計算節(jié)點中。
此外針對Spark官網(wǎng)及Cloudera提供的任務調(diào)優(yōu)方案上也有針對數(shù)據(jù)結構序列化、資源調(diào)度,以及任務運行時的參數(shù)設置的優(yōu)化建議。
為此本文提出了針對具有不同的數(shù)據(jù)特性的數(shù)據(jù)源,進行代碼的自動分析,嘗試解決因數(shù)據(jù)傾斜帶來的Spark任務運行的效率問題。
數(shù)據(jù)傾斜意味著數(shù)據(jù)集合中不同屬性的值出現(xiàn)的次數(shù)不是均勻分布的,在統(tǒng)計學中屬于數(shù)據(jù)分配不均的問題。科學研究中的很多數(shù)據(jù)都是分布不均勻的。比如在天體物理學領域描述宇宙演化的數(shù)據(jù)集Millennium simulation,數(shù)據(jù)集中每個節(jié)點的質(zhì)量分布如圖1所示。超過75%的數(shù)值出現(xiàn)不超過十次,而出現(xiàn)頻率最高的7個數(shù)值每一個的出現(xiàn)次數(shù)都超過了2 000萬次[8]。
圖1 數(shù)據(jù)集節(jié)點質(zhì)量分布圖
為了解釋數(shù)據(jù)傾斜對Spark任務產(chǎn)生的影響。我們首基于MapReduce的高效粗糙集屬性約簡算法先以一個統(tǒng)計詞頻的例子介紹Spark框架的工作流程[9]。
在程序的map階段,對輸入的文章中的每一行執(zhí)行map函數(shù),并生成
因為Spark具有shuffle機制,所以在數(shù)據(jù)傾斜的情況下,shuffle操作將位于不同節(jié)點中具有相同key的大量的數(shù)據(jù)拉到同一個節(jié)點中執(zhí)行reduce操作。而一個Spark 任務只能在一個partition中之行,所以某一些數(shù)據(jù)量異常巨大的key的任務運行時間就會非常緩慢。
以Word Count出現(xiàn)數(shù)據(jù)傾斜為例,在map階段,每一篇文章都被劃分為每個獨立的單詞,從而發(fā)現(xiàn)文中大量的單詞都是hello,少部分的單詞是world。在Shuffle階段,我們需要將不同節(jié)點上具有相同key的鍵值對分配到相同的節(jié)點中。在Reduce階段,有大量的帶有單詞hello的鍵值對被分配到了同一臺機器上,而剩余的少量的world的key被分配到同一臺機器。兩個節(jié)點的機器配置和網(wǎng)絡帶寬都是相同的,但是其中一臺機器處理的數(shù)據(jù)量是另一臺機器的成百上千倍。整個任務的運行瓶頸就在執(zhí)行reduce任務較多的節(jié)點上。當數(shù)據(jù)量上升到TB、PB級別時,就會出現(xiàn)運行時間長甚至內(nèi)存不足的情況。
如何解決數(shù)據(jù)傾斜帶來的問題,現(xiàn)有的方法是利用Spark本身的特性,緩解因為數(shù)據(jù)傾斜導致的分區(qū)不均的問題。根據(jù)3.1節(jié)的描述,數(shù)據(jù)傾斜的問題是出現(xiàn)在Spark任務處理的shuffle階段,如果要處理數(shù)據(jù)傾斜的問題,我們可以在shuffle階段進行優(yōu)化。
優(yōu)化的目標最終減少因為重新分配數(shù)據(jù)導致的某一個Reduce節(jié)點中數(shù)據(jù)過多的問題。處理方式有兩種思路,第一種是通過增加任務處理分區(qū)數(shù)或者是按照Key的維度對數(shù)據(jù)進行離散化,嘗試從shuffle階段緩解數(shù)據(jù)傾斜的壓力。第二種是利用Spark的廣播變量的特性直接忽略shuffle階段,從根本上解決數(shù)據(jù)傾斜的問題。具體的處理流程和分析在4.3節(jié)中介紹。
目前Spark將數(shù)據(jù)傾斜的優(yōu)化策略交給程序員中利用代碼手動完成,這就經(jīng)常會導致程序運行的效率低下甚至產(chǎn)生程序報錯。主要原因有:
(1) 程序員對數(shù)據(jù)特性本身不敏感,沒有針對具有數(shù)據(jù)傾斜特性的Spark程序進行優(yōu)化。
(2) 選擇錯誤的優(yōu)化方案。錯誤的優(yōu)化策略會占用系統(tǒng)的額外內(nèi)存和網(wǎng)絡帶寬。效果只會是適得其反,降低數(shù)據(jù)分析任務的性能。
隨著項目復雜度和代碼量的提高,優(yōu)化策略的問題會變得越來越嚴重。如果可以使用自動分析的方法,自動根據(jù)數(shù)據(jù)的傾斜特性選擇相應的代碼優(yōu)化策略,無疑會降低程序員的負擔,避免上述的問題。下面將對這方面進行初步研究,通過分析與建模,目的對處理數(shù)據(jù)傾斜數(shù)據(jù)的spark任務進行智能優(yōu)化,并加速任務的運行速度。
為了更好地衡量數(shù)據(jù)的傾斜程度,本文對數(shù)據(jù)集合中的數(shù)據(jù)分布的均勻程度進行了定義,提出了數(shù)據(jù)傾斜度的概念。數(shù)據(jù)傾斜度的計算借鑒了分類統(tǒng)計中的平均絕對偏差的概念,統(tǒng)計一個數(shù)據(jù)集合中每個Key出現(xiàn)的次數(shù),然后計算每個觀測值和算術平均值的偏差的絕對值的平均。同時為了對結果進行正則和標準劃,我們引入了相對平均絕對偏差的計算方式,也就是用平均絕對偏差除以算數(shù)平均值。最后數(shù)據(jù)傾斜度的定義就取二分之一的相對平均絕對偏差[10]。如公式所示:
(1)
式中:G代表數(shù)據(jù)傾斜度,xi代表數(shù)據(jù)集合中每個key出現(xiàn)的次數(shù)。選取平均絕對偏差的作為計算數(shù)據(jù)傾斜度主要是考慮結果的通用性和高效性,在比較了多重分類統(tǒng)計中的度量之后,最終選擇了絕對偏差方案。數(shù)據(jù)傾斜度G的范圍在0~1之間,G越接近1表明數(shù)據(jù)的傾斜程度越大,G越接近0表明數(shù)據(jù)的分布平均。
為了對Spark代碼進行靜態(tài)分析,獲取程序運行時中間數(shù)據(jù)的相互依賴,本文通過分析Spark程序運行時的日志信息,和各個中間數(shù)據(jù)之間的相互依賴及各項操作生成了一個有向無環(huán)圖(DAG)。DAG代表了Spark代碼的真正計算路徑。
Spark任務 DAG 圖上的每個節(jié)點表示一種 RDD類 型。在Spark代碼中,程序員在RDD上定義了一系列操作。這些操作可以是map接著reduce,也可以是一系列的map和reduce的集合,都會被Spark記錄下RDD之間的相互依賴,我們可以據(jù)此畫出一張關于計算路徑的有向無環(huán)圖(DAG)。用DAG圖可以從算法邏輯和數(shù)據(jù)規(guī)模大小兩個方面來準確地刻畫任務的特征。
為了便于理解,下面列出了統(tǒng)計詞頻任務的Spark代碼。圖2是任務對應的有向無環(huán)圖。圖的頂點(方框)表示系統(tǒng)中的數(shù)據(jù)類型RDD, 圖的邊代表不同操作之間的關系。圖中表示的過程是首先讀取文件,分別進行flatMap和map操作,然后再將map的結果執(zhí)行reduceByKey的操作進行聚合,最后將結果輸出到文件中。通過這樣的DAG已經(jīng)能夠清楚地刻畫任務執(zhí)行的基本流程[11]。
1. val text_file = spark.textFile(″source_path″);
2. val word_count=text_file.flatMap(lambda line: line.split())
.map(lambda word: (word, 1))
.reduceByKey(lambda a, b: a+b);
3. word_count.saveAsTextFile(′dest_path′)
圖2 統(tǒng)計詞頻任務的源代碼和有向無環(huán)圖
首先我們把數(shù)據(jù)傾斜的任務分為兩大類[12]:(1) 任務代碼中直接調(diào)用Spark的Map-Reduce方法;(2) 任務代碼中任務代碼中調(diào)用更抽象的rdd.join(),再有Spark的解釋器編編譯成具體的Map-Reduce 任務代碼。針對具體的任務分類,分別有不同的優(yōu)化方案。
針對普通的Map-Reduce的任務,如果出現(xiàn)數(shù)據(jù)傾斜的情況,在執(zhí)行reduce的任務時,不同節(jié)點執(zhí)行的數(shù)據(jù)量的不同,導致了數(shù)據(jù)任務的遲緩。解決方案通常有兩種思路。
1) 提高shuffle階段任務的最大并行度,即Spark框架中對于用戶設置的最大分區(qū),具體的參數(shù)名字是 spark.sql.shuffle.partitions。Spark框架對該值的默認值是200,對于傾斜程度不同的數(shù)據(jù)處理任務需要動態(tài)的進行調(diào)整。如圖3所示,增加分區(qū)數(shù)字之后,每個reduce節(jié)點執(zhí)行的數(shù)據(jù)量變少,執(zhí)行速度也更快。
圖3 shuffle過程中增加分區(qū)數(shù)
2) 對shuffle階段的
圖4 shuffle過程中為key增加隨機后綴
針對RDD之間需要Join的任務,如果出現(xiàn)數(shù)據(jù)傾斜的情況。也有如下兩種處理方法:
1) 如果其中一個RDD數(shù)據(jù)量較小,使用廣播變量方式減少shuffle階段的數(shù)據(jù)交換。Spark允許程序員在不同機器之間緩存一個只讀的變量,從而節(jié)省在不同的任務之間傳遞數(shù)據(jù)的消耗。這種變量被稱為廣播變量。廣播變量的優(yōu)勢包括,利用一種高效的方式在每個集群節(jié)點上緩存一個大量的數(shù)據(jù)集合。同時,Spark也嘗試利用高效的廣播算法來分布式的廣播變量,以期望降低數(shù)據(jù)交換的消耗,如圖5所示。
圖5 將RDD轉(zhuǎn)化為廣播變量,避免shuffle過程
2) 分拆RDD。根據(jù)每個KEY的傾斜程度,將RDD分拆為傾斜的和分布均勻的兩部分??梢詫⑸贁?shù)幾個KEY導致的數(shù)據(jù)傾斜分拆出去,然后進行數(shù)據(jù)離散化操作,此時數(shù)據(jù)會分散到多個任務中執(zhí)行。數(shù)據(jù)聚合操作之后,再使用Union方法將分拆的兩個RDD進行合并。如圖6所示。
圖6 根據(jù)key傾斜度將RDD分拆,reduce結束后再union
針對Spark程序中經(jīng)常出現(xiàn)的數(shù)據(jù)傾斜導致的運行效率的問題,通過程序的智能分析,針對數(shù)據(jù)傾斜的不同應用場景自動地對代碼執(zhí)行優(yōu)化策略。針對策略的自動化,算法的實現(xiàn)思路如下:
(1) 分析Spark代碼[13]。通過在Spark源碼中植入監(jiān)聽代碼,根據(jù)日志信息對數(shù)據(jù)結構RDD和相應的函數(shù)操作進行建模,即可以得到當前代碼的有向無環(huán)圖(DAG)。圖中的每一個點都代表一個RDD,圖中的每一個邊都代表RDD執(zhí)行的函數(shù)操作。
(2) 判斷RDD是否出現(xiàn)數(shù)據(jù)傾斜。方法是對DAG圖中的每一個點,也就是RDD依次進行采樣分析,根據(jù)數(shù)據(jù)集合大小和數(shù)據(jù)分布計算出數(shù)據(jù)傾斜度,如果數(shù)據(jù)傾斜度大于一定的閾值則被判斷為數(shù)據(jù)傾斜。
(3) 針對RDD的數(shù)據(jù)傾斜程度及RDD本身的數(shù)據(jù)場景,應用不同的代碼優(yōu)化策略。
本方法需要對代碼執(zhí)行兩次。第一次是為了獲取處于不同階段的RDD,從中間分析出有數(shù)據(jù)傾斜的RDD。所以第一次運行的時候,可以在代碼中對RDD進行數(shù)據(jù)采樣,只運行少量的數(shù)據(jù)集合,這樣在小數(shù)據(jù)集對代碼和RDD進行分析,不會影響運行的性能。代碼優(yōu)化后,再進行代碼的第二次運行。
方法的整體流程如圖7所示。
圖7 優(yōu)化算法整體架構
下面是關于如何進行代碼優(yōu)化的具體操作:
(1) 增加隨機后綴,并增加分區(qū)數(shù)。為數(shù)據(jù)集中分布不均勻的key分配一個隨機的后綴或者前綴,力圖將shuffle的key進行離散化,使數(shù)據(jù)的分布更加均勻。待每個新的key聚合完成以后,把添加的前綴或者后綴去掉,恢復成原本的key, 再重新計算一個reduce操作。
(2) 生成廣播變量。針對兩個RDD join的情況,將其中一個略小的RDD轉(zhuǎn)化為broadcast對象,然后分發(fā)到執(zhí)行任務的分布式集群的每個node中。最后在RDD的flatMapToPair的函數(shù)中利用map完成RDD之間的聚合操作。
(3) 分拆傾斜RDD。兩個RDD Join,但是其中一個RDD存在數(shù)據(jù)傾斜的問題,我們對有數(shù)據(jù)傾斜的RDD進行隨機前綴操作。對另一個RDD進行類似于數(shù)據(jù)膨脹的擴容操作。然后和第一種模式的流程一樣,重新進行Map-Reduce操作。
實驗采用的云計算集群是亞馬遜公司的EMR(Elastic Map Reduce)集群。EMR是亞馬遜公司提供的彈性Map-Reduce服務[13],服務內(nèi)容包括用戶可以自動配置分布式計算集群,集群上可以動態(tài)部署Hadoop、Hive、Spark等分布式計算框架,也可以動態(tài)部署Pig、Phoenix、Presto等分布式查詢引擎,減少了數(shù)據(jù)開發(fā)人員大量的配置分布式開發(fā)環(huán)境的時間成本。同時,作為彈性分布式集群服務,用戶可以按需求動態(tài)地啟動集群服務,配置集群規(guī)模,提交數(shù)據(jù)分析任務,改善了整個數(shù)據(jù)分析流程的效率。同時,作為亞馬遜的云服務,EMR可以使用亞馬遜提供的其他云服務組件配合使用,比如分布式文件存儲系統(tǒng)S3(Simple Storage Service)或者亞馬遜EC2(Elastic Computer Cloud)[14]等。綜上所述,EMR具有配置靈活,服務類型豐富,運維成本低等優(yōu)勢。因為,我們在實驗中采用了亞馬遜的EMR云服務作實驗環(huán)境。
我們基于亞馬遜的EMR服務分別進行了三組實驗,使用的集群配置都是相同的。我們使用了20臺節(jié)點配置的集群。配置如下:機器類型亞馬遜EC2 m4.xlarge,4核CPU,16 GB內(nèi)存,帶寬450 Mbit/s。使用的軟件及其版本為:EMR 4.7,Spark 2.1,Hadoop 1.7。
實驗目的是為了驗證根據(jù)數(shù)據(jù)場景提出的代碼優(yōu)化策略是否可以減少程序的運行時間,優(yōu)化任務運行效果。
為了保證數(shù)據(jù)集合和數(shù)據(jù)傾斜度的大小可控,實驗采用了模擬數(shù)據(jù)。具體模擬方法是:針對每個數(shù)據(jù)集合的RDD大小以及數(shù)據(jù)傾斜度大小,采用擴充或者采樣RDD的方式來控制數(shù)據(jù)集合大小,采用key分配隨機前綴或者key進行歸一化操作來控制數(shù)據(jù)傾斜度的大小。最終,利用現(xiàn)有的數(shù)據(jù)集合,我們就能模擬出合適的數(shù)據(jù)集合用于任務優(yōu)化效率[16]的實驗。
首先我們將任務優(yōu)化效率定義為可量化的指標。通過對任務優(yōu)化效率的分析,驗證對于相同的數(shù)據(jù)分析任務,本文提出的方法是否可以自動選擇數(shù)據(jù)場景并針對任務進行了優(yōu)化,同時在運行效率上確實達到了任務優(yōu)化的效果。
通過對比相同的Spark任務在算法優(yōu)化前后的任務運行時間,我們對任務優(yōu)化效率提出了定義。值得注意的是,在進行代碼優(yōu)化前后的運行時間對照實驗的時候,針對優(yōu)化后的程序運行時間,我們應當將第一部分試驗中進行數(shù)據(jù)場景判斷的時間也計算在內(nèi)。也就是需要將數(shù)據(jù)場景判斷所花費的時間和優(yōu)化后程序的運行時間結合在一起才是優(yōu)化方法的真正運行時間。關于任務優(yōu)化效率如公式所示:
(2)
式中:E代表任務優(yōu)化效率;ti表示優(yōu)化前的任務運行時間;tj表示優(yōu)化后的任務運行時間。針對相同的數(shù)據(jù)分析任務,通過優(yōu)化前的任務運行時間減去優(yōu)化后的運行時間,即得到總體任務的優(yōu)化時間。再得到優(yōu)化時間和優(yōu)化前任務運行時間的比值,即是任務的優(yōu)化效率。優(yōu)化效率越接近于1,則表示優(yōu)化效果越好。
針對任務優(yōu)化效率的實驗,本文設計了三種不同的任務優(yōu)化實驗。
第一個實驗是為了驗證在不同的數(shù)據(jù)場景下本文方法都能夠達到一定的任務優(yōu)化效率,縮短任務的運行時間。實驗內(nèi)容是針對三種不同的數(shù)據(jù)傾斜場景分別是用未優(yōu)化的代碼和優(yōu)化后的代碼進行數(shù)據(jù)分析,對比兩個任務的運行時間,最后計算任務優(yōu)化效率。同時,在實驗過程中保證三種不同的場景下數(shù)據(jù)集合和數(shù)據(jù)傾斜度都保持相同。這里,數(shù)據(jù)集合的大小是10 GB,數(shù)據(jù)傾斜度是0.5。
第二個實驗是為了驗證在數(shù)據(jù)集合數(shù)據(jù)傾斜度相同的情況下,數(shù)據(jù)集合大小對任務運行時間和任務優(yōu)化效率的影響。實驗內(nèi)容是在數(shù)據(jù)分析任務中采用的數(shù)據(jù)集合是數(shù)據(jù)集合大小不同但是數(shù)據(jù)傾斜程相同的數(shù)據(jù),同樣對比的是代碼優(yōu)化前后的程序運行時間。三組實驗的數(shù)據(jù)集合大小都是100 GB。這里,所有數(shù)據(jù)集的數(shù)據(jù)傾斜度都是0.5,數(shù)據(jù)集合的大小從1 GB到1 TB不等。
第三個實驗是為了驗證在數(shù)據(jù)集合大小相同的情況下,數(shù)據(jù)傾斜程度對任務運行時間和任務優(yōu)化效率的影響。實驗內(nèi)容是在數(shù)據(jù)分析任務中采用的數(shù)據(jù)集合是數(shù)據(jù)傾斜程度不同但是數(shù)據(jù)集大小相同的數(shù)據(jù)。同樣對比的是代碼優(yōu)化前后的程序運行時間。這里,數(shù)據(jù)集合的大小都是100 GB,數(shù)據(jù)集合的數(shù)據(jù)傾斜度從0.1到0.9不等。
第一個實驗中,針對三種不同的數(shù)據(jù)場景,優(yōu)化后的代碼運行效率都要比優(yōu)化前的代碼片段有了不同程度的提升。實驗結果如圖8所示,橫軸表示三種不同的數(shù)據(jù)場景,縱軸表示方法優(yōu)化前后程序的運行時間,單位是分鐘。橫軸中每個數(shù)據(jù)場景對應兩個柱狀圖,左邊直方圖代表優(yōu)化前的任務運行時間,中間的直方圖表示分析數(shù)據(jù)場景的時間,右側的直方圖表示優(yōu)化后的任務運行時間。根據(jù)優(yōu)化前后的任務運行時間以及任務運行效率的定義,可以計算出隨機前綴、廣播變量和分拆RDD的方法的優(yōu)化效率分別提升了40%、47%和58%。從而證明本文方法對Spark數(shù)據(jù)傾斜任務具有一定的優(yōu)化效果。同時,數(shù)據(jù)場景分析只占總體運行時間的小部分。因此可以得出結論,優(yōu)化方法的前期數(shù)據(jù)采樣工作對優(yōu)化算法的運行效率沒有影響。
圖8 不同數(shù)據(jù)場景下代碼優(yōu)化后運行效率有了大幅度提升
第二個實驗,針對相同的數(shù)據(jù)傾斜度,在數(shù)據(jù)集合大小不同的情況下,對比本文方法的優(yōu)化效率。其中圖9是實驗結果。其中X軸表示的是數(shù)據(jù)集合的大小,Y軸表示優(yōu)化前后代碼的優(yōu)化效率。實驗二的所有數(shù)據(jù)集的數(shù)據(jù)傾斜度都是0.5。實驗結果表明,在數(shù)據(jù)傾斜度大小相等或者近似相等的情況下。優(yōu)化后的代碼相比優(yōu)化前的代碼,運行效率有了明顯提升。同時,隨著數(shù)據(jù)大小的增加,當數(shù)據(jù)集合達到100 GB以后,優(yōu)化效率曲線開始保持平穩(wěn)。
圖9 實驗結果
第三個實驗是采用數(shù)據(jù)集大小相同但是數(shù)據(jù)傾斜程度不同的數(shù)據(jù),同樣對比的是優(yōu)化前后的代碼效率。三組實驗的數(shù)據(jù)集合大小都是100 GB。圖10是對應的結果。其中X軸表示的是數(shù)據(jù)傾斜度的變化,Y軸表示優(yōu)化前后代碼的優(yōu)化效率。實驗結果表明,在數(shù)據(jù)集合大小相等或者近似相等的情況下。優(yōu)化后的代碼相比較優(yōu)化前的代碼,運行效率有了大幅度提升。同時,隨著數(shù)據(jù)傾斜度的增加,優(yōu)化效率一直在不斷提高。
圖10 隨著數(shù)據(jù)傾斜程度增加,算法優(yōu)化效率顯著提升
場景選擇代碼優(yōu)化策略。實驗結果表明,這種調(diào)優(yōu)方法具有一定的可行性。在接下來的研究中我們可以獲取更多Spark運行時的數(shù)據(jù),從調(diào)度策略和內(nèi)存資源分配等不同的方向豐富數(shù)據(jù)模型,進一步提高算法的優(yōu)化性能。
[1] Dean J,Ghemawat S.MapReduce:Simplified Data Processing on Large Clusters[C]//Conference on Symposium on Opearting Systems Design & Implementation.DBLP,2004:137-150.
[2] 林海銘.基于Hadoop MapReduce的大規(guī)模線性有限元法并行實現(xiàn)[J].計算機應用與軟件,2017,34(3):21-26.
[3] 倪麗萍,馬馳宇,劉小軍.社會化信息對股市波動影響分析—基于SparkR平臺的實現(xiàn)[J].計算機應用與軟件,2017,34(3):181-188,266.
[4] 余雙雙,曾一,劉慧君,等.基于UML模型的多態(tài)性與Java接口代碼信息一致性檢測的方法[J].計算機應用與軟件,2017,34(2):8-13,47.
[5] 陳康,王彬,馮琳.Spark計算引擎的數(shù)據(jù)對象緩存優(yōu)化研究[J].中興通訊技術,2016,22(2):23-27.
[6] 陳僑安,李峰,曹越,等.基于運行數(shù)據(jù)分析的Spark任務參數(shù)優(yōu)化[J].計算機工程與科學,2016,38(1):11-19.
[7] 韓海雯.MapReduce計算任務調(diào)度的資源配置優(yōu)化研究[D].華南理工大學,2013.
[8] Gufler B,Augsten N,Reiser A,et al.Handling Data Skew in MapReduce[C]//Closer 2011-Proceedings of the,International Conference on Cloud Computing and Services Science,Noordwijkerhout,Netherlands,7-9 May.DBLP,2011:574-583.
[9] 李成,許胤龍,郭帆,等.基于MapReduce的內(nèi)存并行Join算法研究[J].計算機應用與軟件,2016,33(7):257-260,277.
[10] 裔傳俊,劉亮.采用邊緣分類和平均偏差比較的分形圖像編碼[J].計算機應用與軟件,2015,32(2):211-214.
[11] 陳龍,蘇厚勤.BPEL文檔基于DAG自動生成框架的研究與實現(xiàn)[J].計算機應用與軟件,2016,33(5):87-89,143.
[12] 李濤,劉斌.Spark平臺下的高效Web文本分類系統(tǒng)的研究[J].計算機應用與軟件,2016,33(11):33-36.
[13] 黃賽杰,陳銘松,金乃詠.一種基于約束求解的Verilog語言靜態(tài)分析方法[J].計算機應用與軟件,2015,32(12):1-3,87.
[14] Keshavjee K,Bosomworth J,Copen J,et al.Best Practices in EMR Implementation:A Systematic Review[J].AMIA.Annual Symposium proceedings/AMIA Symposium.AMIA Symposium,2006,2006(3):982.
[15] Simson L.Garfinkel.An Evaluation of Amazon’s Grid Computing Services:EC2,S3 and SQS[C]//Center for.2007.
[16] 程慧敏,李學俊,吳洋,等.云環(huán)境下基于多目標優(yōu)化的科學工作流數(shù)據(jù)布局策略[J].計算機應用與軟件,2017,34(3):1-6.