Spark / Java: не сериализуемая проблема - сериализация Kryo - PullRequest
0 голосов
/ 22 февраля 2019

Чего мне не хватает в сериализации крио?

Class1 и Class3 не являются сериализуемыми классами java (нет конструкторов по умолчанию, нет и методов получения и установки)

Когда я пытаюсь «использовать» экземпляр, созданный из контекста Spark, внутри Spark возникает проблема с сериализацией, независимо от того, регистрирую ли я Classe3 как класс Kryo или нет.

Работает нормально:

Dataset<Class1> ds = spark.createDataset(classes, Encoders.kryo(Class1.class));

Dataset<String> df = df.map((MapFunction<Class1, String>) class1 -> class1.getName(), Encoders.STRING());

df.show();

Ошибка сериализации, вызванная Class3

spark = SparkSession
        .builder()
        .master("local[*]")
        .config(new SparkConf().registerKryoClasses(new Class[] {Class3.class}))
        .appName("spark_test")
        .getOrCreate();

Class3 class3 = Class3.getInstance();

Dataset<Class1> ds = spark.createDataset(classes, Encoders.kryo(Class1.class));

Dataset<String> df = df.map((MapFunction<Class1, String>) class1 -> class1.getName() + "-" class3.getId(), Encoders.STRING());

df.show();

1 Ответ

0 голосов
/ 26 февраля 2019

Обобщение обсуждения, которое произошло в комментариях, для формирования ответа. Когда вы пытаетесь вызвать преобразование, драйвер Spark должен создать и отправить закрытие для кода в рамках этого преобразования исполнителю (-ям), который отвечает за него.для запуска этого.В вашем случае строка кода Class3 class3 = Class3.getInstance(); является частью объекта Scala, который включает в себя создание и использование контекста Spark для получения какого-либо результата, приложения-драйвера.Следовательно, когда вы пытаетесь передать class3 в преобразовании карты, драйвер пытается сериализовать включающий объект Scala.Этот объект scala сам по себе не является сериализуемым, если вы не реализуете сериализуемость, следовательно, вы получаете проблему с сериализацией.

Re: Сериализация Kryo. Поскольку вы зарегистрировали свой Class3 в Kryo, он поможет вам сериализовать экземпляр Class3, однако он не будет сериализовать объект Composite, в котором экземпляр Class3 является переменной.

Следовательно, если вы извлекаете значение class3.getId() и затем передаете его преобразованию своей карты, вам не нужно регистрировать Class3 в Kryo.

В вашем примере с объектом Scala, о котором я упоминалвыше то же самое, что и приложение для драйвера.

Надеюсь, это поможет.

...