如何在 AWS EMR 上设置 Hadoop fs.s3a.acl.default?

How to set Hadoop fs.s3a.acl.default on AWS EMR?

我在 AWS EMR 上有一个 map-reduce 应用程序 运行,它将一些输出写入不同的(aws 帐户)s3 存储桶。我有权限设置,作业可以写入外部存储桶,但所有者仍然是 Hadoop 作业 运行 所在帐户的 root。我想将其更改为拥有存储桶的外部帐户。

我发现我可以将 fs.s3a.acl.default 设置为 bucket-owner-full-control,但这似乎不起作用。这就是我正在做的事情:

conf.set("fs.s3a.acl.default", "bucket-owner-full-control");
FileSystem fileSystem = FileSystem.get(URI.create(s3Path), conf);
FSDataOutputStream fsDataOutputStream = fileSystem.create(new Path(filePath));
PrintWriter writer  = new PrintWriter(fsDataOutputStream);
writer.write(contentAsString);
writer.close();
fsDataOutputStream.close();

感谢任何帮助。

conf.set("fs.s3a.acl.default", "bucket-owner-full-control");

你设置的属性是对的

因为这是 core-site.xml 中的 属性 以完全控制存储桶所有者。

<property>
  <name>fs.s3a.acl.default</name>
  <description>Set a canned ACL for newly created and copied objects. Value may be private,
     public-read, public-read-write, authenticated-read, log-delivery-write,
     bucket-owner-read, or bucket-owner-full-control.</description>
</property>

BucketOwnerFullControl

    Specifies that the owner of the bucket is granted Permission.FullControl. The owner of the bucket is not necessarily the same as the owner of the object.

我建议将 fs.s3.canned.acl 也设置为值 BucketOwnerFullControl

对于调试,您可以使用下面的代码片段来了解实际传递的参数..

for (Entry<String, String> entry: conf) {
      System.out.printf("%s=%s\n", entry.getKey(), entry.getValue());
    }

出于测试目的,使用命令行执行此命令

aws s3 cp s3://bucket/source/dummyfile.txt s3://bucket/target/dummyfile.txt --sse --acl bucket-owner-full-control

如果这行得通,那么通过 api 也行。

Spark 加分,对 spark scala 用户有用:

让 Spark 访问 s3 文件系统并设置正确的配置,如下例...

val hadoopConf = spark.sparkContext.hadoopConfiguration
    hadoopConf.set("fs.s3a.fast.upload","true")
    hadoopConf.set("mapreduce.fileoutputcommitter.algorithm.version","2")
    hadoopConf.set("fs.s3a.server-side-encryption-algorithm", "AES256")
    hadoopConf.set("fs.s3a.canned.acl","BucketOwnerFullControl")
    hadoopConf.set("fs.s3a.acl.default","BucketOwnerFullControl")

如果您使用的是 EMR,那么您必须使用 AWS 团队的 S3 连接器,使用 "s3://" URL 并使用他们记录的配置选项。他们不支持 apache,因此任何以 "fs.s3a" 开头的选项都不会产生任何影响。

正如 Stevel 在回答中提到的,对于带有 pyspark 的 EMR,请使用此

sc=spark.sparkContext
hadoop_conf=sc._jsc.hadoopConfiguration()
hadoop_conf.set("fs.s3.canned.acl","BucketOwnerFullControl")

罐装 ACL 描述

BucketOwnerFullControl 指定授予桶的所有者 Permission.FullControl。桶的拥有者不一定是 与对象的所有者相同。

https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-s3-acls.html