关于数据集中的 kryo 和 java 编码器的问题

Question regarding kryo and java encoders in datasets

我正在使用 Spark 2.4 并参考 https://spark.apache.org/docs/latest/rdd-programming-guide.html#rdd-persistence

豆子class:

public class EmployeeBean implements Serializable {

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

    // getters and setters

}

Spark 示例:

    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

几个问题:

Shouldn't size of kryo serialized RDD be less than Java serialized RDD instead of more than double size?

如果您曾经使用过 Java 序列化(或与此相关的 RDD),那就对了。然而,这里不是这种情况。 Java 当您应用 Encoders.javaSerialization 时使用序列化,与 Encoders.kryo 相同,使用二进制序列化。

二进制序列化程序获取整个对象,使用通用序列化工具对其进行序列化,并将生成的字节数组存储为单个 DataFrame 列。结果对于优化器来说是不透明的(没有真正的存储优化,因为 blob 不能很好地压缩),并且只能用于函数 ("strongly typed" API).

Encoders.bean 是完全不同的野兽,与 Encoders.product 非常相似。它利用 class 的结构并反映在模式中。因为它对各个字段进行编码,所以可以使用标准 Spark 方法有效地压缩列。因此存储内存要求较低。

密切相关