Spark與緩存

預期成果

1.1   當前問題

當前以圖搜圖應用存在的問題:java

  1. 當前使用spark RDD方案沒法達到數據實時加載(每10分鐘加載一次,雖然可配,但過短可能會有問題)
  2. Spark RDD內存會被分爲兩部分,一部分用來緩存數據一部分用來計算,Spark默認配置只有差很少50%的內存用於緩存(也就是說executor配了100G,只有50多G能夠被用來作緩存),雖然比例能夠進行配置,但增長緩存內存比例後,是否會影響計算性能有待測試。
  3. 當前數據全緩存到spark jvm內存中,GC時間較長會致使影響計算性能
  4. 當前加載的RDD只有自身context才能使用,沒法作到應用間共享
  5. 當driver端服務宕掉後,緩存的數據也會丟失
  6. 指望能將增量數據加載時間縮小到足夠小達到準實時,或者直接可以達到實時
  7. 職責分明,緩存有分佈式緩存作,Spark只負責計算
  8. 緩存數據不佔用Spark jvm內存,減小GC對計算的影響
  9. 加載到內存的數據能夠被其餘應用使用
  10. Driver端服務宕掉後,緩存數據不會丟失,其餘driver段仍可以使用
  11. 採用新方案對比原方案,性能損耗盡量小,最好達到無損耗

1.2   預期成果

2       技術選型

根據上述問題和預期成果,指望選擇一款與Spark結合較好的分佈式內存緩存計算,從而將緩存工做從spark中抽離出來,讓spark專一於計算。apache

2.1.1  Apache Ignite

Apache Ignite內存數據組織是高性能的、集成化的以及分佈式的內存平臺,他能夠實時地在大數據集中執行事務和計算,和傳統的基於磁盤或者閃存的技術相比,性能有數量級的提高。api

選擇預研該技術最大的緣由爲,Ignite實現了一個可共享的Spark RDD,可實現增量數據實時在比對中體現。緩存

2.1.2  Alluxio(原Tachyon)

Alluxio在1.0版本後由原來的Tcahyon改名。Alluxio與Spark結合較好,Spark1.5後增長的緩存方式:OFF_HEAP(堆外緩存)當前只支持tachyon。性能優化

不過Alluxio和Spark RDD同樣都不可變,緩存文件一旦寫入就不能修改,且在完成寫入以前緩存數據是沒法讀取的,這樣就服務達到增量數據的實時性,但能夠實現儘量縮短增量加載時間來達到準實時性。數據結構

3       階段性結論

性能測試採用上述兩種技術三個版本(apache-ignite-fabric-1.5.0.final、alluxio-1.0.一、tachyon-0.7.1-hadoop2.6-build)八種方案:框架

  1. 直接採用Spark RDD緩存,且緩存數據不作序列化
  2. 直接採用Spark RDD緩存,緩存數據使用java序列化方式
  3. 直接採用Spark RDD緩存,緩存數據使用kryo序列化方式
  4. 採用Spark RDD OFF_HEAP模式(即緩存數據到tachyon),緩存數據使用java序列化方式
  5. 採用Spark RDD OFF_HEAP模式(即緩存數據到tachyon),緩存數據使用kryo序列化方式
  6. 使用tachyon緩存數據(調用saveAsObjectFile,直接將數據序列化成文件寫到tachyon中),saveAsObjectFile使用java序列化方式
  7. 使用Alluxio緩存數據(調用saveAsObjectFile,直接將數據序列化成文件寫到Alluxio中),saveAsObjectFile使用java序列化方式
  8. 使用ignite緩存數據,使用IgniteRDD進行統計

下面爲三臺256G內存集羣,58727000條數據,Spark分配36核,測試結果以下:jvm

緩存方式分佈式

內存配置oop

是否序列化

序列化實現

檢索耗時(s)

內存空間(GB)

Spark RDD

executor:150GB*3

 

11.527

112.8

Spark RDD

executor:150GB*3

java

20.09

56.4

Spark RDD

executor:150GB*3

kryo

16.275

51.8

Spark RDD + tachyon

executor:20GB*3 tachyon:100GB*3

java

21.771

51.56

Spark RDD + tachyon

executor:20GB*3 tachyon:100GB*3

kryo

17.772

51.83

tachyon

executor:20GB*3 tachyon:100GB*3

java

32.719

53.03

Alluxio

executor:20GB*3 alluxio:100GB*3

java

26.988

53.03

ignite

executor:20GB*3 ignite:10GB*3(數據保存在堆外,不使用jvm內存)

java

333.228

 

 

由上表分析以下:

  1. 檢索耗時最短爲方案一,直接緩存到spark jvm中且不作序列化,但該方案佔用內存也較多(目前是其餘方案的兩倍),不過當前以圖搜圖框架中數據結構採用map,因此較佔內存
  2. 方案1、2、三對比,採用序列化會有性能損耗,kryo序列化耗時是java序列化的1/2,與以前測試基本一致,採用kryo序列化112GB數據耗時4-5秒
  3. 對比方案2、方案四以及方案3、方案五,從tachyon拉數據到spark進行計算耗時爲1秒左右,但因爲存儲到tachyon必須序列化,因此得加上序列化的耗時,最少的性能損耗也差很少5-6秒
  4. 直接調用saveAsObjectFile保存數據到tachyon或者Alluxio,性能損耗較大,分別爲22秒和14秒,初步估計性能損耗因爲:(1)saveAsObjectFile採用java序列化方式,性能損耗將近9秒;(2)saveAsObjectFile內部實現使用的是hadoop api,tachyon可以兼容這些api,但可能有部分性能損耗;(3)spark可能對tachyon存儲作過必定優化
  5. 由表格能夠看出ignite結合spark性能不好,估計緣由可能爲:(1)可能修改某些配置後能夠優化性能,但iginte資料很是少,特別是跟spark結合這塊,基本沒有什麼資料;(2)ignite自己不僅僅包含存儲功能,還有檢索、計算等功能,因此它與spark自己也存在競爭關係

結論以下:

  1. ignite如需優化性能須要深刻源碼,且沒有對比數據,具體最後能到什麼程度沒法預估,且當前基本沒有什麼已知公司使用該技術與Spark結合

Alluxio(Tachyon)性能優化須要看Spark緩存代碼,可是該方法最終可以達到的性能指標基本可以預估(較現有方案有5-6秒的損耗,但內存消耗可能會有所減小)

相關文章
相關標籤/搜索