s3distcp 从 S3 复制到 EMR HDFS 数据副本始终在一个节点上

s3distcp copy from S3 to EMR HDFS data replica always on one node

我正在使用 s3distcp 将 500GB 的数据集复制到我的 EMR 集群中。这是一个 12 节点 r4.4xlarge 集群,每个节点有 750GB 磁盘。它使用 EMR 发布标签 emr-5.13.0,我正在添加 Hadoop:Amazon 2.8.3、Ganglia:3.7.2 和 Spark 2.3.0。我正在使用以下命令将数据复制到集群中:

s3-dist-cp --src=s3://bucket/prefix/ --dest=hdfs:///local/path/ --groupBy=.*(part_).* --targetSize=128 --outputCodec=none

当我查看 Ganglia 或名称节点 UI(EMR 集群上的端口 50070)中的磁盘使用情况时,我可以看到一个节点的大部分磁盘已满,其他节点也有类似情况使用的百分比。单击大量文件 (~50) 我可以看到文件的副本总是出现在完整节点上。

我正在使用 Spark 转换此数据,将其写入 HDFS,然后复制回 S3。当我的任务被终止时,我在处理这个数据集时遇到了问题。我不确定这是问题的原因。我不需要在本地复制数据,也不需要解压缩它。最初我认为 BZIP2 编解码器不可拆分,解压缩将有助于在我的 Spark 作业中获得并行性,但我错了,它是可拆分的。我还发现了我用来重新分配副本的 hdfs balancer 命令,看看这是否解决了我的 Spark 问题。

但是,现在我看到了我认为奇怪的行为 我想了解 s3distcp/HDFS 始终在一个节点上创建文件副本是否正常?

s3distcp 是闭源的;我无法详细评论其内部结构。

当 HDFS 创建数据副本时,它会尝试将一个块保存到本地机器,然后再在其他地方保存 2 个(假设复制==3)。无论哪个主机是 运行,distcp 工作进程最终都会拥有整个文件的副本。因此,如果只有一台主机用于复制,那么它就会填满。

FWIW,我认为您不需要执行该 distcp,如果您可以直接从 S3 读取和过滤数据,并将结果保存到 hdfs,则不需要。您的 spark worker 将进行过滤,并将他们的块写回机器 运行 这些 worker 和链中的其他主机。对于短期集群,您还可以尝试降低 hdfs 复制因子(2?),这样可以节省整个集群的 HDFS 数据,代价是减少了一个用于 spark 安排与数据相邻的工作的地方