1. 程式人生 > >spark 序列化

spark 序列化

 

資料序列化

    序列化在分散式應用中起到很重要的作用。那些會讓物件序列化過程緩慢,或是會消耗大量位元組儲存的序列化格式會大大降低計算速率。通常這會使用者在優化Spark應用程式中的第一件事。Spark旨在在便利(允許您使用您的操作中的任何Java型別)和效能之間實現平衡。它提供了下面兩種序列化庫:

  1. Java serialization:Spark預設使用Java的ObjectOutputStream框架來序列化物件,可以對任何實現了java.io.Serializable的任何類進行序列化。使用者也可以通過繼承來實現更緊密的序列化效能控制。
  2. Kryo serialization:Spark也可以使用Kryo庫(version 2)來實現更快的物件序列化。Kryo比Java序列化更快、資料格式更緊湊,但不支援所有的Serializable型別。使用者如果希望使用Kryo來獲取更好的效能,需要先去註冊應用程式中會使用到的類。

幾乎所有的資料都顯示kryo 序列化方式優於java自帶的序列化方式,而且在spark2.*版本中都是預設採用kryo 序列化。

1.先給出定義:
    把物件轉換為位元組序列的過程稱為物件的序列化。
    把位元組序列恢復為物件的過程稱為物件的反序列化。
通俗地說序列化就是把記憶體(jvm)中一個物件的狀態通過網路傳輸,或者儲存到磁碟上,反序列化與之相反。

2.spark中的序列化
那麼物件以何種形式進行傳輸效能更好呢?
在spark2.0+版本的官方文件中提到:spark預設提供了兩個序列化庫:Java自身的序列化和Kryo序列化
官網的解釋是:java序列化靈活,但是速度緩慢。Kryo序列化速度更快且更緊湊,但是支援的型別較少。
而且spark現在已經預設RDD在shuffle的時候對簡單型別使用了Kryo序列化。

    使用者可以在初始化任務時通過設定SparkConf中的conf.set("spark.serializer", "org.apache.spark.serializer.KryoSerializer")來切換序列化框架為Kryo。這裡的序列化配置不僅可以對worker節點之間的shuffle資料起作用,還可以在將RDD序列化到disk上時起作用。Kryo不是預設序列化選擇的唯一原因它要求了使用者的註冊行為,但是我們建議在所有網路密集型應用程式中使用它。從Spark2.0.0開始,我們在傳輸簡單型別或是字串型別的Shuffle RDD時會預設使用Kryo序列化。

    Spark自動對許多在Twitter chill庫中的AllScalaRegistrar被覆蓋的常用的Scala類註冊了Kryo。

    註冊使用者自身的類到kryo時,可以使用registerKryoClasses方法:

val conf = new SparkConf().setMaster(...).setAppName(...)
conf.registerKryoClasses(Array(classOf[MyClass1], classOf[MyClass2]))
val sc = new SparkContext(conf)

    Kryo的文件https://github.com/EsotericSoftware/kryo描述了更多進階的註冊選項,例如增加使用者序列化程式碼等等。

    如果使用者的物件很大,也需要去增加spark.kryoserializer.buffer配置項。這個值需要達到足以儲存你將要序列化的最大的物件。

    最後,如果你不註冊使用者類,kryo也可以工作,但是它將會儲存每個物件的全類名,會造成儲存空間的浪費。