Kryo десериализация HashMap не работает с Spark

У меня есть класс Java, в котором есть несколько полей String и одно поле HashMap. Я сериализую объекты этого класса с сериализацией Kryo по умолчанию и сохраняю их в HBase.

После чтения их в памяти десериализация в flatMap функции RDD в Spark приводит к следующей ошибке. Хотя тот же сегмент кода работает, если он не связан с 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$1.call(EmPageRank.java:227)
    at prSpark.EmPageRank$1.call(EmPageRank.java:1)
    at org.apache.spark.api.java.JavaRDDLike$$anonfun$fn$3$1.apply(JavaRDDLike.scala:149)
    at org.apache.spark.api.java.JavaRDDLike$$anonfun$fn$3$1.apply(JavaRDDLike.scala:149)
    at scala.collection.Iterator$$anon$13.hasNext(Iterator.scala:371)
    at org.apache.spark.util.Utils$.getIteratorSize(Utils.scala:1595)
    at org.apache.spark.rdd.RDD$$anonfun$count$1.apply(RDD.scala:1157)
    at org.apache.spark.rdd.RDD$$anonfun$count$1.apply(RDD.scala:1157)
    at org.apache.spark.SparkContext$$anonfun$runJob$5.apply(SparkContext.scala:1858)
    at org.apache.spark.SparkContext$$anonfun$runJob$5.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$1.run(URLClassLoader.java:372)
    at java.net.URLClassLoader$1.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» не найден, но «Dadisme» - это не какой-либо класс в моей программе, это данные в поле HashMap.


person dnivog    schedule 22.06.2016    source источник
comment
Я тоже столкнулся с подобной проблемой. В моем случае HashMap был большим, ›400 000 записей. Я думаю, это из-за ошибки в kryo при работе с большими коллекциями. Позже я переключился на Джексона для моего варианта использования.   -  person bistaumanga    schedule 22.06.2016
comment
Я не думаю, что проблема возникла из-за размера HashMap в моем случае, который составляет около 1000.   -  person dnivog    schedule 27.06.2016


Ответы (1)


Это исключение произошло из-за разницы в версиях библиотек Kyro, используемых для сериализации и десериализации. Spark по умолчанию использует версию 2 Kryo, а я использовал последнюю версию (т.е. 3.x) Kryo для сериализации объектов. Так что версии сериализации и десериализации должны совпадать.

person dnivog    schedule 27.06.2016