我正在使用 Spark 2.4 并引用 https://spark.apache.org/docs/latest/rdd-programming-guide.html#rdd-persistence
bean 类:
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()
模式,RDD 大小相同。 RDD 作为序列化的 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),那就对了。然而,这里不是这种情况。申请Encoders.javaSerialization
时使用Java序列化它与 Encoders.kryo
一样,使用二进制序列化。
二进制序列化程序获取整个对象,使用通用序列化工具将其序列化,并将生成的字节数组存储为单个 DataFrame
列。结果对于优化器来说是不透明的(没有真正的存储优化,因为 blob 不能很好地压缩),并且只能用于功能性(“强类型”API)。
Encoders.bean
是一个完全不同的野兽,非常类似于 Encoders.product
.它利用类的结构,并反射(reflect)在模式中。因为它对各个字段进行编码,所以可以使用标准 Spark 方法有效地压缩列。因此存储内存要求较低。
关于apache-spark - 关于数据集中的 kryo 和 java 编码器的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54034205/