【Spark調優】Kryo序列化


【Java序列化與反序列化】

Java序列化是指把Java對象轉換為字節序列的過程;而Java反序列化是指把字節序列恢復為Java對象的過程。
序列化使用場景:
1.數據的持久化,通過序列化可以把數據永久地保存到硬盤上(通常存放在文件里)。
2.遠程通信,即在網絡上傳送對象的字節序列。

這篇文章寫的不錯https://blog.csdn.net/wangloveall/article/details/7992448

【Spark序列化與反序列化場景】

在Spark中,主要有三個地方涉及序列化與反序列化:
1.在算子中使用到廣播變量broadcast時,該變量會被序列化后進行網絡傳輸。
2.自定義對象的類型作為RDD的泛型類型時,例如JavaRDD<Student>,所有自定義類型對象,都會進行序列化,所以要求自定義類必須實現Serializable接口。
3.使用可序列化的持久化策略時,例如MEMORY_ONLY_SER,Spark會將RDD中的每個partition都序列化成一個大的字節數組。

 

【Spark序列化與反序列化機制】

  Spark默認使用的是Java的序列化機制,也就是ObjectOutputStream、ObjectInputStream API來進行序列化和反序列化。

  Spark也支持使用Kryo序列化庫,Kryo序列化類庫的性能比Java序列化類庫的性能要高很多。據官方介紹,Kryo序列化機制比Java序列化機制性能高10倍左右。

  那么,對於上述3種Spark有序列化處理的方法,建議使用Kryo序列化類庫,優化序列化和反序列化的性能。

  Spark之所以默認沒有使用Kryo作為序列化類庫,是因為Kryo要求最好要注冊所有需要進行序列化的自定義類型,使用上略微繁瑣,但並不麻煩。

【Spark使用Kryo序列化與反序列化】

例如,Student和School是自定義的2個類,Kryo使用注意點

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

Scala:
val conf = new SparkConf().setMaster(...).setAppName(...)
conf.registerKryoClasses(Array(classOf[Student], classOf[School]))
val sc = new SparkContext(conf)

Java:
SparkConf conf = new SparkConf().setMaster(...).setAppName(...)
conf.registerKryoClasses(Student.class, School.class)
JavaSparkContext sc = new JavaSparkContext(conf)

  此外

  1.Spark參數 spark.kryoserializer.buffer.mb=2,默認值為2,是指配置Kryo默認最大能緩存2M的對象,然后再進行序列化。

  如果注冊的要序列化的自定義的Class類型,本身特別大,比如包含的屬性過百,會導致要序列化的對象過大。此時,可使用SparkConf.set()方法,設置spark.kryoserializer.buffer.mb參數的值,將其調大來解決。

  2.在SparkStreaming2.4.0與Kafka2.1.1集成編碼中遇到過一個問題:開始沒指定序列化,日志中看到有Serialize的報錯,抱着試試看的心態,設置為kryo序列化方式,set("spark.serializer", "org.apache.spark.serializer.KryoSerializer"),問題得以解決。

  我的代碼實踐:https://github.com/wwcom614/Spark

 

  下一篇:【Spark調優】提交job資源參數調優 

  上一篇:【Spark調優】內存模型與參數調優

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM