避免在带有hadoop(EMR)的S3中创建_ $ folder $键

时间:2017-03-18 15:27:25

标签: amazon-web-services hadoop amazon-s3 amazon-emr

我在AWS数据管道中使用EMR活动。此EMR活动正在EMR群集中运行配置单元脚本。它将dynamo DB作为输入并将数据存储在S3中。

这是EMR活动中使用的EMR步骤

s3://elasticmapreduce/libs/script-runner/script-runner.jar,s3://elasticmapreduce/libs/hive/hive-script,--run-hive-script,--hive-versions,latest,--args,-f,s3://my-s3-bucket/hive/my_hive_script.q,-d,DYNAMODB_INPUT_TABLE1=MyTable,-d,S3_OUTPUT_BUCKET=#{output.directoryPath}

其中

out.direcoryPath是:

s3://my-s3-bucket/output/#{format(@scheduledStartTime,"YYYY-MM-dd")}

因此,这会在S3中创建一个文件夹和一个文件。 (从技术上讲,它会创建两个键2017-03-18/<some_random_number>2017-03-18_$folder$

2017-03-18
2017-03-18_$folder$

如何避免创建这些额外的空_$folder$个文件。

编辑: 我在https://issues.apache.org/jira/browse/HADOOP-10400找到了一个解决方案,但我不知道如何在AWS数据管道中实现它。

4 个答案:

答案 0 :(得分:5)

EMR似乎没有提供避免这种情况的方法。

  

由于S3使用键值对存储系统,因此Hadoop文件系统通过创建带有“_ $ folder $”后缀的空文件来实现S3中的目录支持。

     

您可以安全地删除S3存储桶中出现<directoryname>_$folder$后缀的所有空文件。这些空文件由Hadoop框架在运行时创建,但Hadoop旨在处理数据,即使这些空文件已被删除。

     

https://aws.amazon.com/premiumsupport/knowledge-center/emr-s3-empty-files/

它在Hadoop源代码中,因此可以修复,但显然它在EMR中没有修复。

如果您感觉聪明,可以创建一个与_ $ folder $后缀匹配的S3事件通知,并启动Lambda函数以在创建对象后删除它们。

答案 1 :(得分:1)

在S3中无法实际创建空文件夹。 S3是一个对象存储,所以一切都是对象。当Hadoop将其用作文件系统时,它需要组织这些对象以使其显示为文件系统树,因此它会创建一些特殊对象以将对象标记为目录。 您只需存储数据文件,但您可以选择将这些数据文件组织到路径中,从而创建类似于遍历文件夹的概念。

如果您只是不创建文件夹,而是将文件放在您想要的路径中 - 这应该适合您。 在S3中将文件写入文件夹之前,您不必创建文件夹。

这也可能有所帮助: https://qubole.zendesk.com/hc/en-us/articles/213496246-How-To-Remove-Dir-marker-folders-in-S3-NativeFS-

答案 2 :(得分:0)

在EMR引导操作中使用以下脚本来解决此问题。由AWS提供的补丁

#!/bin/bash

# NOTE: This script replaces the s3-dist-cp RPM on EMR versions 4.6.0+ with s3-dist-cp-2.2.0.
# This is intended to remove the _$folder$ markers when creating the destination prefixes in S3.

set -ex

RPM=bootstrap-actions/s3-dist-cp-2.2.0/s3-dist-cp-2.2.0-1.amzn1.noarch.rpm

LOCAL_DIR=/var/aws/emr/packages/bigtop/s3-dist-cp/noarch

# Get the region from metadata
REGION=$(curl http://169.254.169.254/latest/meta-data/placement/availability-zone/ 2>/dev/null | head -c -1)

# Choose correct bucket for region
if [ $REGION = "us-east-1" ]
then
    BUCKET=awssupportdatasvcs.com
else
    BUCKET=$REGION.awssupportdatasvcs.com
fi

# Download new RPM
sudo rm $LOCAL_DIR/s3-dist-cp*.rpm
aws s3 cp s3://$BUCKET/$RPM /tmp/
sudo cp /tmp/s3-dist-cp-2.2.0-1.amzn1.noarch.rpm $LOCAL_DIR/

echo Rebuilding Repo
sudo yum install -y createrepo
sudo createrepo --update -o /var/aws/emr/packages/bigtop /var/aws/emr/packages/bigtop
sudo yum clean all

答案 3 :(得分:0)

在写入s3存储桶时使用s3a,它将删除 $ folder $ 。我已经测试过这种胶水了。不知道它是否将应用于EMR集群。

信用:-有人在reddit上回答

from pyspark.sql import SparkSession
spark=SparkSession.builder.getOrCreate()
df=spark.read.format("parquet").load("s3://testingbucket/")
df.write.format("parquet").save("s3a://testingbucket/parttest/")
spark.stop()