天天看點

Spark Cache 性能測試

作者介紹:塗小剛,攻城獅一枚,有代碼潔癖,熱愛學習,熱愛生活,痛恨醬油帝、跪舔帝。目前主要從事Spark大資料平台與機器學習平台相關方向的工作,關注Spark與TensorFlow

訓練資料是通過 Facebook SNS 公開資料集生成器得到,在HDFS上大小為9.3G,100個檔案,添加如下兩個參數以保證所有資源全部到位後才啟動task,訓練時間為加載資料到訓練完畢這期間的耗時。

測試叢集為3個節點的TS5機器搭建而成,其中一台作為RM,兩台NM。除以上配置外,其他配置全部保持Spark預設狀态。公共資源配置、分區設定以及算法參數如下表所示,<code>executor_memory</code>視不同的測試用例不同:

Spark Cache 性能測試

在不使用Cache的情況和使用Cache的情況下,分别測試<code>Spark-Kmeans</code>算法的訓練時間以及GC時間占比,相關測試名額資料如下表所示:

Spark Cache 性能測試

從以上測試資料看來,讓人有點出乎意料,一開始有點不太相信,但是多次測試後資料并沒有多大的抖動,是以說Spark的性能受多方面因素的影響,單單Cache這塊不同的Cache方式以及不同的資源情況下,其性能差别就相差較大,下面分析其内在原因。

不使用cache時,GC不是瓶頸,在每次疊代時均要讀一遍HDFS,通路HDFS有較大的開銷。從HDFS加載訓練資料後直接采用Spark原生的Cache:

當<code>executor_memory</code>為2g時,不足以Cache住原始訓練資料,從UI上看到Cache的比例隻有33%左右,導緻頻繁的<code>rdd-block</code> 剔除重建,同時由于記憶體吃緊,可能引發較重的GC,從UI上看到GC時間占到總的task運作時間的12%左右,已經成為瓶頸,其整體性能還不如不使用Cache;

當<code>executor_memory</code>為4g時,也不足以Cache住原始訓練資料,但是其Cache的比例有90%左右,同樣存在<code>rdd-block</code> 剔除重建,并引發較重的GC,GC時間占總的task運作時間的7%左右,雖然比<code>executor_memory</code>為2g的情況有所好轉,但是仍然不理想,隻比不做Cache好7%左右,但是記憶體卻多用了20g,并不是特别劃算;

當<code>executor_memory為6g</code>時,可以全部Cache住原始訓練資料,性能較優,GC占比較小,但是比不用Cache要多用40g記憶體,有些代價。

一般來說,當我們記憶體不夠時,可以選擇<code>MEMORY_AND_DISK</code>的緩存方式,但是測試發現<code>MEMORY_AND_DISK</code>的緩存效果并不是特别好,從測試資料來看,還不如直接使用<code>DISK_ONLY</code>的緩存方式,<code>MEMORY_AND_DISK</code>的緩存方式帶來的GC開銷非常大,可能是因為每次都盡可能地Cache資料到記憶體,不夠再Spill到磁盤,同時引發頻繁GC。

為了排除偶然性,拿 BigDataBenchmark 中的 PageRank 算法進行測試,分别測試各種Cache方式下整體性能,在保證每種Cache方式下都能100%Cache住資料的情況下,得到如下測試結果。

Spark Cache 性能測試

Spark的Cache并不是總是會加速任務運作,Cache的方式不同,對任務産生的影響不同。并不是能用記憶體Cache就用記憶體,而是要考慮是否有充足的記憶體Cache住你的資料,否則可能适得其反。在記憶體充足時,優先考慮使用<code>MEMORY_ONLY</code>,但是當記憶體不足以Cache住你的中間資料時,建議直接用<code>MEMORY_ONLY_SER(spark.rdd.compress=true)</code>或<code>DISK_ONLY</code>而不要用<code>MEMORY_AND_DISK,MEMORY_AND_DISK</code>可能會頻繁地觸發Spark的記憶體管理,增加Spill以及GC的開銷。