1. 程式人生 > >Spark與緩存

Spark與緩存

分布式 kryo 數量級 enc 問題: 分布式緩存 context ive 服務

預期成果

1.1 當前問題

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

  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專註於計算。

2.1.1 Apache Ignite

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

選擇預研該技術最大的原因為,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.1、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核,測試結果如下:

緩存方式

內存配置

是否序列化

序列化實現

檢索耗時(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. 方案一、二、三對比,采用序列化會有性能損耗,kryo序列化耗時是java序列化的1/2,與之前測試基本一致,采用kryo序列化112GB數據耗時4-5秒
  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秒的損耗,但內存消耗可能會有所減少)

Spark與緩存