1. 引入
最近社区活跃贡献者:Raymond Xu & OpenOpened,给Hudi贡献了一个非常实用的工具:HoodieSnapshotExporter,该实用程序旨在促进导出(如备份复制和转换格式)Hudi数据集的任务。
2. 备份成Hudi格式数据集
与现有的 HoodieSnapshotCopier
相似,导出器将扫描源数据集,然后将其复制到目标输出路径。
spark-submit \ --jars "packaging/hudi-spark-bundle/target/hudi-spark-bundle_2.11-0.6.0-SNAPSHOT.jar" \ --deploy-mode "client" \ --class "org.apache.hudi.utilities.HoodieSnapshotExporter" \ packaging/hudi-utilities-bundle/target/hudi-utilities-bundle_2.11-0.6.0-SNAPSHOT.jar \ --source-base-path "/tmp/" \ --target-output-path "/tmp/exported/hudi/" \ --output-format "hudi" #Export as Hudi
3. 备份成Json/Parquet格式数据集
导出器还可以将源数据集转换为其他格式,当前仅支持json和parquet。
spark-submit \ --jars "packaging/hudi-spark-bundle/target/hudi-spark-bundle_2.11-0.6.0-SNAPSHOT.jar" \ --deploy-mode "client" \ --class "org.apache.hudi.utilities.HoodieSnapshotExporter" \ packaging/hudi-utilities-bundle/target/hudi-utilities-bundle_2.11-0.6.0-SNAPSHOT.jar \ --source-base-path "/tmp/" \ --target-output-path "/tmp/exported/json/" \ --output-format "json" # or "parquet"
2.1 Re-partitioning
当导出为其他格式(json/parquet)时,导出器将使用该参数进行一些自定义重新分区。默认情况下,如果以下两个参数均未给出,则输出数据集将没有分区。
2.1.1 --output-partition-field
此参数使用现有的非元数据字段作为输出分区。在导出时,所有 _hoodie_*
元数据字段都将被删除。
spark-submit \ --jars "packaging/hudi-spark-bundle/target/hudi-spark-bundle_2.11-0.6.0-SNAPSHOT.jar" \ --deploy-mode "client" \ --class "org.apache.hudi.utilities.HoodieSnapshotExporter" \ packaging/hudi-utilities-bundle/target/hudi-utilities-bundle_2.11-0.6.0-SNAPSHOT.jar \ --source-base-path "/tmp/" \ --target-output-path "/tmp/exported/json/" \ --output-format "json" \ --output-partition-field "symbol" # assume the source dataset contains a field `symbol`
输出目录如下所示:
_SUCCESS symbol=AMRS symbol=AYX symbol=CDMO symbol=CRC symbol=DRNA ...
2.1.2 --output-partitioner
此参数表示实现 HoodieSnapshotExporter.Partitioner
类的全路径名。此参数的优先级高于 --output-partition-field
,如果提供该参数, --output-partition-field
配置将被忽略。
一个示例实现如下所示:
package com.foo.bar; public class MyPartitioner implements HoodieSnapshotExporter.Partitioner { private static final String PARTITION_NAME = "date"; @Override public DataFrameWriter<Row> partition(Dataset<Row> source) { // use the current hoodie partition path as the output partition return source .withColumnRenamed(HoodieRecord.PARTITION_PATH_METADATA_FIELD, PARTITION_NAME) .repartition(new Column(PARTITION_NAME)) .write() .partitionBy(PARTITION_NAME); } }
将此类放在 my-custom.jar
中之后,然后将其放在作业类路径中,submit命令将如下所示:
spark-submit \ --jars "packaging/hudi-spark-bundle/target/hudi-spark-bundle_2.11-0.6.0-SNAPSHOT.jar,my-custom.jar" \ --deploy-mode "client" \ --class "org.apache.hudi.utilities.HoodieSnapshotExporter" \ packaging/hudi-utilities-bundle/target/hudi-utilities-bundle_2.11-0.6.0-SNAPSHOT.jar \ --source-base-path "/tmp/" \ --target-output-path "/tmp/exported/json/" \ --output-format "json" \ --output-partitioner "com.foo.bar.MyPartitioner"
请注意,其不会删除 _hoodie_*
元数据字段;它留给用户处理元数据字段。
3. 总结
相信有这个工具后,大家可以非常方便地备份Hudi数据集或者对初始数据集的格式进行特定的转换、转储。这个特性将会包含在Hudi的下一个版本0.6.0中。如果有小伙伴迫不及待想使用这个特性,也可以checkout master分支上的代码到本地,自己编译打包。