Вопрос относительно кодеров kryo и java в наборах данных

Я использую Spark 2.4 и ссылаюсь на https://spark.apache.org/docs/latest/rdd-programming-guide.html

Класс бобов:

public class EmployeeBean implements Serializable {

    private Long id;
    private String name;
    private Long salary;
    private Integer age;

    // getters and setters

}

Пример искры:

    SparkSession spark = SparkSession.builder().master("local[4]").appName("play-with-spark").getOrCreate();

    List<EmployeeBean> employees1 = populateEmployees(1, 1_000_000);

    Dataset<EmployeeBean> ds1 = spark.createDataset(employees1, Encoders.kryo(EmployeeBean.class));
    Dataset<EmployeeBean> ds2 = spark.createDataset(employees1, Encoders.bean(EmployeeBean.class));

    ds1.persist(StorageLevel.MEMORY_ONLY());
    long ds1Count = ds1.count();

    ds2.persist(StorageLevel.MEMORY_ONLY());
    long ds2Count = ds2.count();

Я искал хранилище в Spark Web UI. Полезная часть -

ID  RDD Name                                           Size in Memory   
2   LocalTableScan [value#0]                           56.5 MB  
13  LocalTableScan [age#6, id#7L, name#8, salary#9L]   23.3 MB

Несколько вопросов:

  • Разве размер сериализованного СДР Kryo не должен быть меньше, чем Сериализированный СДР Java, а не более чем в два раза?

  • Я тоже пробовал MEMORY_ONLY_SER() Режим и размер RDD одинаковы. СДР как сериализованные объекты Java должны храниться в виде одного байтового массива на раздел. Разве размер сохраняемых СДР не должен быть меньше десериализованных?

  • Что именно делает добавление кодеров Kryo и bean-компонентов при создании набора данных?

  • Могу ли я переименовать сохраненные СДР для лучшей читаемости?

1 ответ

Решение

Разве размер сериализованного RDD для крио не должен быть меньше, чем для сериализированного Java-RDD, а не более чем в два раза?

Это было бы верно, если бы вы когда-либо использовали сериализацию Java (или RDDs в этом отношении). Однако это не тот случай. Сериализация Java используется при применении Encoders.javaSerialization который так же, как Encoders.kryo, использует двоичную сериализацию.

Двоичные сериализаторы берут целый объект, сериализуют его с помощью универсальных инструментов сериализации и сохраняют полученный байтовый массив как один DataFrame колонка. Результат непрозрачен для оптимизатора (без реальной оптимизации хранилища, поскольку большие двоичные объекты плохо сжимаются) и может использоваться только с функциональным ("строго типизированный" API).

Encoders.bean это совершенно другой зверь, очень похожий Encoders.product, Он использует структуру класса и отражается в схеме. Поскольку он кодирует отдельные поля, столбцы могут быть эффективно сжаты с использованием стандартных методов Spark. Отсюда и более низкие требования к памяти.

Тесно связано с Spark Encoders: когда использовать бины ()

Другие вопросы по тегам