Вопрос относительно кодеров 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: когда использовать бины ()