使用hadoop(emr)避免在s3中创建$folder$keys

kg7wmglp  于 2021-05-29  发布在  Hadoop
关注(0)|答案(4)|浏览(452)

我正在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数据管道中实现它。

zrfyljdw

zrfyljdw1#

在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
yyhrrdl8

yyhrrdl82#

使用s3a写入s3 bucket时,它将删除$folder$。我测试过这种胶水。不确定它是否适用于电子病历集群。
credit:- answered 在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()
j8ag8udp

j8ag8udp3#

在s3中没有办法真正创建一个空文件夹。s3是一个对象存储,所以所有的东西都是一个对象。当hadoop将其用作文件系统时,它需要组织这些对象,使其显示为文件系统树,因此它创建一些特殊的对象来将对象标记为目录。您只需存储数据文件,但可以选择将这些数据文件组织到路径中,这创建了一个类似于用于遍历的文件夹的概念。
如果你只是不创建一个文件夹,但把文件放在你想要的路径-这应该适合你。在s3中将文件写入文件夹之前,不必创建文件夹。
这也可能有助于:https://qubole.zendesk.com/hc/en-us/articles/213496246-how-to-remove-dir-marker-folders-in-s3-nativefs-

qxsslcnc

qxsslcnc4#

emr似乎并没有提供一种避免这种情况的方法。
因为s3使用一个键值对存储系统,hadoop文件系统通过创建后缀为“$folder$”的空文件来实现s3中的目录支持。
您可以使用 <directoryname>_$folder$ 出现在s3存储桶中的后缀。这些空文件是由hadoop框架在运行时创建的,但是hadoop被设计成处理数据,即使这些空文件被删除。
https://aws.amazon.com/premiumsupport/knowledge-center/emr-s3-empty-files/
它在hadoop源代码中,所以可以修复,但显然在emr中没有修复。
如果你觉得很聪明,你可以创建一个s3事件通知来匹配$folder$后缀,并让它启动lambda函数来删除创建后的对象。

相关问题