代码之家  ›  专栏  ›  技术社区  ›  Dev

关于数据集中的KyRo和Java编码器的问题

  •  1
  • Dev  · 技术社区  · 6 年前

    我用的是Spark 2.4 https://spark.apache.org/docs/latest/rdd-programming-guide.html#rdd-persistence

    豆类:

    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用户界面中寻找存储空间。有用部分

    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
    

    几个问题:

    • KRIO序列化RDD的大小不应该小于Java序列化RDD,而不是大于两倍的大小吗?

    • 我也尝试过 MEMORY_ONLY_SER() 模式和RDD大小相同。RDD作为序列化的Java对象应该被存储为每个分区的一个字节数组。持久化RDD的大小不应该小于反序列化RDD吗?

    • 在创建数据集时,添加kryo和bean编码器究竟在做什么?

    • 为了提高可读性,我可以重命名持久化的RDD吗?

    1 回复  |  直到 6 年前
        1
  •  1
  •   Community kfsone    6 年前

    KRIO序列化RDD的大小不应该小于Java序列化RDD,而不是大于两倍的大小吗?

    如果你曾经使用过Java序列化(或者RDDs)。不过,情况并非如此。应用程序时使用Java序列化 Encoders.javaSerialization 哪一样 Encoders.kryo ,使用二进制序列化。

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

    Encoders.bean 是一种完全不同的动物 Encoders.product . 它利用类的结构,并反映在模式中。因为它对单个字段进行编码,所以可以使用标准的Spark方法有效地压缩列。因此存储内存需求较低。

    与…密切相关 Spark Encoders: when to use beans()