【问题标题】:Apache Spark - Write Parquet Files to S3 with both Dynamic Partition Overwrite and S3 CommitterApache Spark - 使用动态分区覆盖和 S3 提交器将 Parquet 文件写入 S3
【发布时间】:2022-01-17 20:33:01
【问题描述】:

我目前正在使用 Apache Spark (pyspark) 构建应用程序,我有以下用例:

  • 以本地模式运行pyspark(使用spark-submit local[*])。
  • 将 Spark 作业的结果以分区 Parquet 文件的形式写入 S3。
  • 确保每个作业都覆盖它正在写入的特定分区,以确保作业具有幂等性。
  • 确保在提交到 S3 之前将 spark-staging 文件写入本地磁盘,因为在 S3 中暂存,然后通过重命名操作提交,成本非常高。

由于各种内部原因,上述所有四个要点都是不可协商的。

除了最后一个要点外,我什么都有。我正在运行一个pyspark 应用程序,并写入S3(实际上是一个本地Ceph 实例),确保spark.sql.sources.partitionOverwriteMode 设置为dynamic

但是,这意味着我的 spark-staging 文件正在 S3 中暂存,然后使用删除和重命名操作提交,这非常昂贵。

我已尝试使用Spark Directory Committer 来暂存本地磁盘上的文件。这很好用,除非spark.sql.sources.partitionOverwriteMode

After digging through the source code,看来 PathOutputCommitter 不支持动态分区覆盖。

在这一点上,我被困住了。我希望能够将我的暂存文件写入本地磁盘,然后将结果提交到 S3。但是,我还需要能够在不覆盖整个 Parquet 表的情况下动态覆盖单个分区。

作为参考,我正在运行 pyspark=3.1.2,并使用以下 spark-submit 命令:

spark-submit --repositories https://repository.cloudera.com/artifactory/cloudera-repos/ --packages com.amazonaws:aws-java-sdk:1.11.375,org.apache.hadoop:hadoop-aws:3.2.0,org.apache.spark:spark-hadoop-cloud_2.12:3.1.1.3.1.7270.0-253

spark.sql.sources.partitionOverwriteMode 设置为dynamic 时出现以下错误:

java.io.IOException: PathOutputCommitProtocol does not support dynamicPartitionOverwrite

我的 spark 配置如下:


        self.spark.conf.set("spark.sql.files.ignoreCorruptFiles", "true")
        self.spark.conf.set("spark.sql.execution.arrow.pyspark.enabled", "true")

        self.spark.conf.set("spark.hadoop.fs.s3a.committer.name", "magic")

        self.spark.conf.set("spark.sql.sources.commitProtocolClass",
                            "org.apache.spark.internal.io.cloud.PathOutputCommitProtocol")

        self.spark.conf.set("spark.sql.parquet.output.committer.class",
                            "org.apache.spark.internal.io.cloud.BindingParquetOutputCommitter")

        self.spark.conf.set(
            "spark.sql.sources.partitionOverwriteMode", "dynamic"
        )

【问题讨论】:

    标签: amazon-web-services apache-spark amazon-s3 pyspark parquet


    【解决方案1】:

    担心 s3a 提交者不支持动态分区覆盖功能。这实际上是通过进行大量重命名来实现的,因此忽略了零重命名提交者的全部意义。

    “分区”提交程序由 netflix 编写,用于更新/覆盖活动表中的单个分区。它应该适合您,因为它是相同的用例。

    咨询the documentation

    【讨论】:

    • 谢谢指点!我设置了以下配置:self.spark.conf.set("spark.hadoop.fs.s3a.committer.name", "partitioned")self.spark.conf.set("fs.s3a.committer.staging.conflict-mode", "replace") 这似乎工作。但是,我仍然在日志中看到一行 - 22/01/17 17:09:53 INFO FileOutputCommitter: Saved output of task 'attempt_202201171709455031776784011683221_0006_m_000000_10' to s3a://mybucket/_temporary/0/task_202201171709455031776784011683221_0006_m_000000 为什么它仍然将临时数据保存到 s3?
    • 那里;恐怕需要更多的绑定,请查看 s3a 提交者文档和;或其他 SO 帖子。当 SO 帖子和文档不同意时 - 使用文档
    猜你喜欢
    • 2021-08-28
    • 2016-08-23
    • 2019-07-06
    • 1970-01-01
    • 2018-10-16
    • 1970-01-01
    • 1970-01-01
    • 2021-10-29
    • 1970-01-01
    相关资源
    最近更新 更多