关于数据集中的 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
几个问题:
Kryo 序列化 RDD 的大小不应该小于 Java 序列化 RDD 而不是两倍以上?
我也试过MEMORY_ONLY_SER()
模式和RDDs大小是一样的。作为序列化 Java 对象的 RDD 应存储为每个分区的一个字节数组。持久化 RDD 的大小不应该小于反序列化的吗?
添加 Kryo 和 bean 编码器在创建数据集时究竟在做什么?
我可以重命名持久化 RDD 以提高可读性吗?
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 方法有效地压缩列。因此存储内存要求较低。
与密切相关
我正在使用 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
几个问题:
Kryo 序列化 RDD 的大小不应该小于 Java 序列化 RDD 而不是两倍以上?
我也试过
MEMORY_ONLY_SER()
模式和RDDs大小是一样的。作为序列化 Java 对象的 RDD 应存储为每个分区的一个字节数组。持久化 RDD 的大小不应该小于反序列化的吗?添加 Kryo 和 bean 编码器在创建数据集时究竟在做什么?
我可以重命名持久化 RDD 以提高可读性吗?
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 方法有效地压缩列。因此存储内存要求较低。
与