通过控制 HDFS 中的物理文件/块位置来减少 Spark Shuffle 读/写

问题描述 投票:0回答:1

设置: 我们每小时在 hdfs 中接收 gzip 压缩的 csv 文件(例如每 24 小时 1k+ 个文件)。这些文件组织在文件夹结构中

/data/<year>/<month>/<day>/<hour>/<unique_id>.csv.gz.

我们的 etl 流程(spark 应用程序每天运行一次。在该管道中,我们

  1. 阅读当天的所有文件,
  2. 应用一些变换,
  3. 按小时重新分区整个数据集并将结果写回 hdfs(每天产生 24 个 avro 文件)。

观察: 在监视 Spark 作业时,我可以看到很多 shuffle 操作(还涉及通过网络传输大量数据,尤其是在步骤 2 和 3 之间)。在步骤 1/2 中,为每个文件创建一个任务,该任务安排在提供最佳局部性级别 (

PROCESS_LOCAL
) 的执行器节点上。在步骤 3 中,我们每小时执行一个任务(总共 24 个任务),每个任务将一个 avro 文件写回 hdfs。

这些大型 shuffle 操作的原因是特定小时的输入 csv 文件物理上位于 hdfs 中的多个不同集群节点。读取/转换操作后,特定小时的所有记录都需要发送到单个执行器,该执行器在步骤 3 中运行该小时的写入任务。

优化思路: 为了优化这个过程,我们的想法是以某种方式物理定位同一节点同一小时内的所有原始 csv 文件/块。我们不会摆脱洗牌操作,但这主要需要执行器节点上的本地洗牌读/写,并最大限度地减少网络流量。在这一点上,还值得一提的是,网络带宽在我们的集群中是非常有限的资源。因此,Spark 应用程序大部分时间都在整理数据。

是否有可能在上传过程中或者通过按 cron 计划运行的单独脚本来影响/控制 hdfs 中文件的物理位置?

还有其他选项可以优化/简化此流程吗?

apache-spark hadoop hdfs hadoop-partitioning
1个回答
0
投票

作为一种可能的解决方案,不要将多个 .gz 文件写入一个小时,而是尝试将数据附加到 hdfs 文件。这可能更容易实现

© www.soinside.com 2019 - 2024. All rights reserved.