用delta编码的coulmns编写镶木地板文件

时间:2020-03-23 06:39:13

标签: scala apache-spark pyspark parquet pyarrow

我正在尝试编写具有增量编码的镶木地板文件。 This page,指出实木复合地板支持三种类型的增量编码:

    (DELTA_BINARY_PACKED, DELTA_LENGTH_BYTE_ARRAY, DELTA_BYTE_ARRAY).

由于sparkpysparkpyarrow不允许我们指定编码方法,所以我很好奇如何编写启用增量编码的文件?

但是,我在互联网上发现,如果我有TimeStamp型镶木地板的列将使用增量编码。 因此,我在scala中使用了以下代码来创建实木复合地板文件。但是编码不是增量。


    val df = Seq(("2018-05-01"),
                ("2018-05-02"),
                ("2018-05-03"),
                ("2018-05-04"),
                ("2018-05-05"),
                ("2018-05-06"),
                ("2018-05-07"),
                ("2018-05-08"),
                ("2018-05-09"),
                ("2018-05-10")
            ).toDF("Id")
    val df2 = df.withColumn("Timestamp", (col("Id").cast("timestamp")))
    val df3 = df2.withColumn("Date", (col("Id").cast("date")))

    df3.coalesce(1).write.format("parquet").mode("append").save("date_time2")

parquet-tools显示有关书面镶木地板文件的以下信息。

file schema: spark_schema 
--------------------------------------------------------------------------------
Id:          OPTIONAL BINARY L:STRING R:0 D:1
Timestamp:   OPTIONAL INT96 R:0 D:1
Date:        OPTIONAL INT32 L:DATE R:0 D:1

row group 1: RC:31 TS:1100 OFFSET:4 
--------------------------------------------------------------------------------
Id:           BINARY SNAPPY DO:0 FPO:4 SZ:230/487/2.12 VC:31 ENC:RLE,PLAIN,BIT_PACKED ST:[min: 2018-05-01, max: 2018-05-31, num_nulls: 0]
Timestamp:    INT96 SNAPPY DO:0 FPO:234 SZ:212/436/2.06 VC:31 ENC:RLE,BIT_PACKED,PLAIN_DICTIONARY ST:[num_nulls: 0, min/max not defined]
Date:         INT32 SNAPPY DO:0 FPO:446 SZ:181/177/0.98 VC:31 ENC:RLE,PLAIN,BIT_PACKED ST:[min: 2018-05-01, max: 2018-05-31, num_nulls: 0]

如您所见,没有列使用增量编码。

我的问题是:

  1. 如何编写具有增量编码的镶木地板文件? (如果你可以的话 在scalapython中提供示例代码就可以了。)

  2. 如何确定要使用哪个“增量编码”:(DELTA_BINARY_PACKED, DELTA_LENGTH_BYTE_ARRAY, DELTA_BYTE_ARRAY)

1 个答案:

答案 0 :(得分:2)

弄清楚如何使用PySpark生成镶木地板文件时,如何启用DELTA编码确实具有挑战性。

我们生成了大量的数字数据,使用DELTA编码可以真正受益。在我的测试中,我能够使用DELTA编码将136.9MB的小型测试文件减少到101.6MB。对于我们的用例,我们生成了TB的数据,因此未来的S3节省值得考虑。

我的经验是使用EMR 5.29.0的Spark 2.4.5。在生成DELTA编码文件之前和之后,我都遇到了很多陷阱。我会提到它们,以便您意识到问题并且不会绊倒自己。

为了在PySpark中生成DELTA编码的Parquet文件,我们需要启用Parquet写入的版本2。这是它唯一起作用的方式。另外,由于某些原因,该设置仅在创建spark上下文时有效。设置为:

"spark.hadoop.parquet.writer.version": "v2"

结果是:

time: INT64 GZIP DO:0 FPO:11688 SZ:84010/2858560/34.03 VC:15043098 ENC:DELTA_BINARY_PACKED ST:[min: 1577715561210, max: 1577839907009, num_nulls: 0]

但是,您无法像现在那样在PySpark中读回相同的文件 java.lang.UnsupportedOperationException: Unsupported encoding: DELTA_BINARY_PACKED

为了读回文件,需要禁用以下conf: spark.conf.set("spark.sql.parquet.enableVectorizedReader", "false")

另外,一个可悲但值得一提的技巧是,熊猫在撰写本文时不会阅读这些文件。

Parquet files v2.0 created by spark can't be read by pyarrow