com.esotericsoftware.kryo.kryoexception java.util.ConcurentModificationException 問題詳解

這次不扯蛋,直接開講。

該問題的本質是序列化問題!!!序列化問題!!!序列化問題!!!

重要問題說三遍。

把對象轉換爲字節序列的過程稱爲對象的序列化

把字節序列恢復爲對象的過程稱爲對象的反序列化

序列化和反序列化爲的是對象經過傳輸(也可能是通過文件方式)後,程序還能對他進行還原成對應object。

序列化 詳解 左拐 https://www.cnblogs.com/xdp-gacl/p/3777987.html

那麼爲什麼會報上面那個問題呢?

因爲你傳輸的對象沒有序列化,或者序列化錯誤。java中序列化  是 java.io.Serializable;

但是 該序列化方式開銷比較大,如果使用網絡傳輸大量對象,那麼可能造成帶寬的大量浪費。所以spark自己搞了個序列化方式。org.apache.spark.serializer.KryoSerializer。該序列化方式好處是開銷小。

spark 2.0以上版本 默認org.apache.spark.serializer.KryoSerializer序列化方式。如果你使用java 序列化那麼鐵定跪了。所以統一spark序列化方式 要不是這  spark成java序列化方式

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

要不對象註冊成 KryoSerializer序列化方式。

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

conf.set("spark.kryo.registrationRequired", "true")

var arrclasses: Array[Class[_]] =Array(classOf[Sub], classOf[DMPUser],

  classOf[SubType], classOf[org.apache.avro.generic.GenericData.Array[_]], classOf[BasicTag]

, classOf[ExtendTag], classOf[org.apache.avro.util.Utf8], classOf[java.util.HashMap[_, _]], classOf[java.util.Map[_, _]]

, classOf[java.util.ArrayList[_]], classOf[java.util.List[_]], classOf[java.lang.CharSequence])

conf.registerKryoClasses(arrclasses)

但是有時 使用KryoSerializer註冊也不是很方便。比如你用avro格式定義的嵌套格式。完了和我上面的例子一樣 需要註冊一大堆類。還不一定註冊全。那麼怎麼辦呢。

通用解決方式:

  寫代碼 實現 objectToByte  和 byteToObject 方法。在有傳輸操作地方 將object轉換成byte數組,在接收操作地方再轉回來。

對於初學各種大數據格式的小朋友會遇到問題。比如 avro自動生成的類報上面錯,無從下手。主要是 對avro理解錯誤。avro提供序列化方式,但是使用avro工具生成的類本身沒有序列化!!!但是使用avro工具生成的類本身沒有序列化!!!但是使用avro工具生成的類本身沒有序列化!!!。avro提供了序列化類,例如DatumReader。

如果使用scala編程,可以使用case class來定義類。case class 默認實現了java 序列化方式。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章