1. 程式人生 > >Spark優化(八):使用Kryo優化序列化效能

Spark優化(八):使用Kryo優化序列化效能

使用Kryo優化序列化效能

 

在Spark中,主要有三個地方涉及到了序列化:

 

  • 在運算元函式中使用到外部變數時,該變數會被序列化後進行網路傳輸(見“Spark優化(七):廣播大變數”中的講解)。

  • 將自定義的型別作為RDD的泛型型別時(比如JavaRDD、Student是自定義型別),所有自定義型別物件,都會進行序列化。因此這種情況下,也要求自定義的類必須實現Serializable介面。

  • 使用可序列化的持久化策略時(比如MEMORY_ONLY_SER),Spark會將RDD中的每個partition都序列化成一個大的位元組陣列。

 

對於這三種出現序列化的地方,我們都可以通過使用Kryo序列化類庫,來優化序列化和反序列化的效能。

 

Spark預設使用的是Java的序列化機制,也就是ObjectOutputStream/ObjectInputStream API來進行序列化和反序列化。但是Spark同時支援使用Kryo序列化庫,Kryo序列化類庫的效能比Java序列化類庫的效能要高很多。

 

官方介紹,Kryo序列化機制比Java序列化機制,效能高10倍左右。Spark之所以預設沒有使用Kryo作為序列化類庫,是因為Kryo要求最好要註冊所有需要進行序列化的自定義型別,因此對於開發者來說,這種方式比較麻煩。


以下是使用Kryo的程式碼示例,我們只要設定序列化類,再註冊要序列化的自定義型別即可(比如運算元函式中使用到的外部變數型別、作為RDD泛型型別的自定義型別等):

 

 

// 建立SparkConf物件。

val conf = new SparkConf().setMaster(...).setAppName(...)

// 設定序列化器為KryoSerializer。

conf.set("spark.serializer", "org.apache.spark.serializer.KryoSerializer")

// 註冊要序列化的自定義型別。

conf.registerKryoClasses(Array(classOf[MyClass1], classOf[MyClass2]))