HashMap 的 Kryo 反序列化因 Spark 而失败
Kryo deserialization of HashMap fails with Spark
我有一个 Java class,它有几个 String
字段和一个 HashMap
字段。我正在使用默认的 Kryo 序列化序列化此 class 的对象并将它们存储在 HBase 中。
在内存中读取它们后,在 Spark 中的 RDD 的 flatMap
函数中反序列化会产生以下错误。尽管相同的代码段在不涉及 Spark 的情况下仍然有效。
16/06/22 11:13:05 WARN TaskSetManager: Lost task 20.0 in stage 3.0 (TID 85, localhost): com.esotericsoftware.kryo.KryoException: Unable to find class: Dadaisme
at com.esotericsoftware.kryo.util.DefaultClassResolver.readName(DefaultClassResolver.java:138)
at com.esotericsoftware.kryo.util.DefaultClassResolver.readClass(DefaultClassResolver.java:115)
at com.esotericsoftware.kryo.Kryo.readClass(Kryo.java:610)
at com.esotericsoftware.kryo.Kryo.readClassAndObject(Kryo.java:721)
at com.esotericsoftware.kryo.serializers.MapSerializer.read(MapSerializer.java:126)
at com.esotericsoftware.kryo.serializers.MapSerializer.read(MapSerializer.java:17)
at com.esotericsoftware.kryo.Kryo.readClassAndObject(Kryo.java:729)
at prSpark.EmPageRank.call(EmPageRank.java:227)
at prSpark.EmPageRank.call(EmPageRank.java:1)
at org.apache.spark.api.java.JavaRDDLike$$anonfun$fn.apply(JavaRDDLike.scala:149)
at org.apache.spark.api.java.JavaRDDLike$$anonfun$fn.apply(JavaRDDLike.scala:149)
at scala.collection.Iterator$$anon.hasNext(Iterator.scala:371)
at org.apache.spark.util.Utils$.getIteratorSize(Utils.scala:1595)
at org.apache.spark.rdd.RDD$$anonfun$count.apply(RDD.scala:1157)
at org.apache.spark.rdd.RDD$$anonfun$count.apply(RDD.scala:1157)
at org.apache.spark.SparkContext$$anonfun$runJob.apply(SparkContext.scala:1858)
at org.apache.spark.SparkContext$$anonfun$runJob.apply(SparkContext.scala:1858)
at org.apache.spark.scheduler.ResultTask.runTask(ResultTask.scala:66)
at org.apache.spark.scheduler.Task.run(Task.scala:89)
at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:214)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.ClassNotFoundException: Dadaisme
at java.net.URLClassLoader.run(URLClassLoader.java:372)
at java.net.URLClassLoader.run(URLClassLoader.java:361)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:360)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:340)
at com.esotericsoftware.kryo.util.DefaultClassResolver.readName(DefaultClassResolver.java:136)
... 22 more
这里从堆栈跟踪 com.esotericsoftware.kryo.KryoException: Unable to find class: Dadaisme
它说 "Dadisme" class 未找到但 "Dadisme" 在我的程序中不是任何 class,它是数据在 HashMap 字段中。
出现此异常是因为用于序列化和反序列化的 Kyro 库版本不同。 Spark 默认使用 Kryo 的第 2 版,而我使用 Kryo 的最新版本(即 3.x)来序列化对象。所以序列化和反序列化版本应该匹配。
我有一个 Java class,它有几个 String
字段和一个 HashMap
字段。我正在使用默认的 Kryo 序列化序列化此 class 的对象并将它们存储在 HBase 中。
在内存中读取它们后,在 Spark 中的 RDD 的 flatMap
函数中反序列化会产生以下错误。尽管相同的代码段在不涉及 Spark 的情况下仍然有效。
16/06/22 11:13:05 WARN TaskSetManager: Lost task 20.0 in stage 3.0 (TID 85, localhost): com.esotericsoftware.kryo.KryoException: Unable to find class: Dadaisme
at com.esotericsoftware.kryo.util.DefaultClassResolver.readName(DefaultClassResolver.java:138)
at com.esotericsoftware.kryo.util.DefaultClassResolver.readClass(DefaultClassResolver.java:115)
at com.esotericsoftware.kryo.Kryo.readClass(Kryo.java:610)
at com.esotericsoftware.kryo.Kryo.readClassAndObject(Kryo.java:721)
at com.esotericsoftware.kryo.serializers.MapSerializer.read(MapSerializer.java:126)
at com.esotericsoftware.kryo.serializers.MapSerializer.read(MapSerializer.java:17)
at com.esotericsoftware.kryo.Kryo.readClassAndObject(Kryo.java:729)
at prSpark.EmPageRank.call(EmPageRank.java:227)
at prSpark.EmPageRank.call(EmPageRank.java:1)
at org.apache.spark.api.java.JavaRDDLike$$anonfun$fn.apply(JavaRDDLike.scala:149)
at org.apache.spark.api.java.JavaRDDLike$$anonfun$fn.apply(JavaRDDLike.scala:149)
at scala.collection.Iterator$$anon.hasNext(Iterator.scala:371)
at org.apache.spark.util.Utils$.getIteratorSize(Utils.scala:1595)
at org.apache.spark.rdd.RDD$$anonfun$count.apply(RDD.scala:1157)
at org.apache.spark.rdd.RDD$$anonfun$count.apply(RDD.scala:1157)
at org.apache.spark.SparkContext$$anonfun$runJob.apply(SparkContext.scala:1858)
at org.apache.spark.SparkContext$$anonfun$runJob.apply(SparkContext.scala:1858)
at org.apache.spark.scheduler.ResultTask.runTask(ResultTask.scala:66)
at org.apache.spark.scheduler.Task.run(Task.scala:89)
at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:214)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.ClassNotFoundException: Dadaisme
at java.net.URLClassLoader.run(URLClassLoader.java:372)
at java.net.URLClassLoader.run(URLClassLoader.java:361)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:360)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:340)
at com.esotericsoftware.kryo.util.DefaultClassResolver.readName(DefaultClassResolver.java:136)
... 22 more
这里从堆栈跟踪 com.esotericsoftware.kryo.KryoException: Unable to find class: Dadaisme
它说 "Dadisme" class 未找到但 "Dadisme" 在我的程序中不是任何 class,它是数据在 HashMap 字段中。
出现此异常是因为用于序列化和反序列化的 Kyro 库版本不同。 Spark 默认使用 Kryo 的第 2 版,而我使用 Kryo 的最新版本(即 3.x)来序列化对象。所以序列化和反序列化版本应该匹配。