平台与工具

导出器

师成师成· 更新于 2026-09-29· 阅读 13 分钟· 0 次阅读

登录后可跨设备保存划线和私人笔记登录

简介

HoodieSnapshotExporter 允许你将数据从一个位置复制到另一个位置,用于备份或其他用途。你可以将数据写为 Hudi、Json、Orc 或 Parquet 文件格式。除了复制数据之外,你还可以根据提供的字段对数据进行重新分区,或者通过继承下文详述的某个类来实现自定义的分区逻辑。

参数

HoodieSnapshotExporter 接收一个源路径和一个目标路径作为引用。该工具会执行查询,在需要时进行重新分区,并将数据写为 Hudi、parquet 或 json 格式。

参数说明是否必需备注
--source-base-path要创建快照的源 Hudi 数据集的基础路径必需
--target-output-path存储特定快照的输出路径必需
--output-format导出数据集的输出格式;可接受以下值:json、parquet、hudi必需
--output-partition-field用于 Spark 重分区的字段可选当指定输出格式为 "Hudi" 或指定 --output-partitioner 时将被忽略。输出数据集的默认分区字段将继承自源 Hudi 数据集。
--output-partitioner用于实现自定义重分区的类可选当输出格式为 "Hudi" 时将被忽略
--transformer-classorg.apache.hudi.utilities.transform.Transformer 的子类。允许在写入前将原始源 Dataset 转换为目标 Dataset(符合目标 schema)。可选当输出格式为 "Hudi" 时将被忽略。可用的转换器:org.apache.hudi.utilities.transform.SqlQueryBasedTransformer、org.apache.hudi.utilities.transform.SqlFileBasedTransformer、org.apache.hudi.utilities.transform.FlatteningTransformer、org.apache.hudi.utilities.transform.AWSDmsTransformer。
--transformer-sql用于在写入前转换源数据的 SQL 查询模板。查询中应将源数据引用为名为 "<SRC>" 的表。可选对于 SqlQueryBasedTransformer 转换器类为必需,其他情况将被忽略
--transformer-sql包含写入时要执行的 SQL 查询的文件。查询中应将源数据引用为名为 "<SRC>" 的表。可选对于 SqlFileBasedTransformer 为必需,其他情况将被忽略

示例

复制 Hudi 数据集

Exporter 会扫描源数据集,然后将其副本写入目标输出路径。

spark-submit \
  --jars "packaging/hudi-spark-bundle/target/hudi-spark3.5-bundle_2.12-1.2.1.jar" \
  --deploy-mode "client" \
  --class "org.apache.hudi.utilities.HoodieSnapshotExporter" \
      packaging/hudi-utilities-slim-bundle/target/hudi-utilities-slim-bundle_2.12-1.2.1.jar \
  --source-base-path "/tmp/" \
  --target-output-path "/tmp/exported/hudi/" \
  --output-format "hudi"

导出为 json 或 parquet 数据集

Exporter 还可以将源数据集转换为其他格式。目前仅支持 "json" 和 "parquet"。

spark-submit \
  --jars "packaging/hudi-spark-bundle/target/hudi-spark3.5-bundle_2.12-1.2.1.jar" \
  --deploy-mode "client" \
  --class "org.apache.hudi.utilities.HoodieSnapshotExporter" \
      packaging/hudi-utilities-slim-bundle/target/hudi-utilities-slim-bundle_2.12-1.2.1.jar \
  --source-base-path "/tmp/" \
  --target-output-path "/tmp/exported/json/" \
  --output-format "json"  # or "parquet"

带转换/过滤功能的 JSON 或 Parquet 数据集导出

Exporter 支持在写入 JSON 或 Parquet 数据集之前,对记录进行自定义的转换/过滤。这可以通过 --transformer-class 选项提供 org.apache.hudi.utilities.transform.Transformer 的实现来完成。

spark-submit \
  --jars "packaging/hudi-spark-bundle/target/hudi-spark3.5-bundle_2.12-1.2.1.jar" \
  --deploy-mode "client" \
  --class "org.apache.hudi.utilities.HoodieSnapshotExporter" \
      packaging/hudi-utilities-slim-bundle/target/hudi-utilities-slim-bundle_2.12-1.2.1.jar \
  --source-base-path "/tmp/" \
  --target-output-path "/tmp/exported/json/" \
  --transformer-class "org.apache.hudi.utilities.transform.SqlQueryBasedTransformer" \
  --transformer-sql "SELECT substr(rider,1,10) as rider, trip_type as tripType FROM <SRC> WHERE trip_type = 'BLACK' LIMIT 10" \
  --output-format "json"  # or "parquet"

重新分区

导出为其他格式时,Exporter 会接受 --output-partition-field 参数以执行自定义的重新分区。注意:所有 _hoodie_* 元数据字段在导出过程中都会被剥离,因此请务必使用已有的非元数据字段作为输出分区字段。

默认情况下,如果未指定任何分区参数,输出数据集将不包含分区。

示例:

spark-submit \
  --jars "packaging/hudi-spark-bundle/target/hudi-spark3.5-bundle_2.12-1.2.1.jar" \
  --deploy-mode "client" \
  --class "org.apache.hudi.utilities.HoodieSnapshotExporter" \
      packaging/hudi-utilities-slim-bundle/target/hudi-utilities-slim-bundle_2.12-1.2.1.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 ...`

自定义重新分区

--output-partitioner 参数用于指定实现 HoodieSnapshotExporter.Partitioner 接口的类的全限定名。该参数的优先级高于 --output-partition-field,若提供了此参数,则 --output-partition-field 将被忽略。

下面给出一个实现示例:

MyPartitioner.java

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,并把该 jar 放到作业的 classpath 中,提交命令如下:

spark-submit \
  --jars "packaging/hudi-spark-bundle/target/hudi-spark3.5-bundle_2.12-1.2.1.jar,my-custom.jar" \
  --deploy-mode "client" \
  --class "org.apache.hudi.utilities.HoodieSnapshotExporter" \
      packaging/hudi-utilities-slim-bundle/target/hudi-utilities-slim-bundle_2.12-1.2.1.jar \
  --source-base-path "/tmp/" \
  --target-output-path "/tmp/exported/json/" \
  --output-format "json" \
  --output-partitioner "com.foo.bar.MyPartitioner"

评论

登录后参与评论

正在加载评论…