首页 > 解决方案 > 无法在 AvroParquetWriter 中使用多个 KMS 密钥和 SSE 的 Hadoop 配置

问题描述

使用在 AWS EC2 实例(不是 hadoop 集群)上运行的 Java 应用程序,我使用 parquet-hadoop/avro 库创建 AvroParquetWriters 以生成 parquet 文件,然后将这些文件写入 S3 中的存储桶。我创建了多个具有不同配置的 AvroParquetWriter,它们指定了不同的 KMS 密钥用于加密,但创建的所有文件都使用相同的 kms 密钥进行加密(它使用配置中首次使用的密钥)。

这是我创建Configurations 和Writers 的方式:

Configuration conf1 = new Configuration();

conf1.set("fs.s3a.server-side-encryption.key", awsKmsId1);
conf1.set("fs.s3a.server-side-encryption-algorithm", "SSE-KMS");
conf1.set("fs.s3a.connection.ssl.enabled", "true");
conf1.set("fs.s3a.endpoint", s3Endpoint);


Configuration conf2 = new Configuration();

conf2.set("fs.s3a.server-side-encryption.key", awsKmsId2);
conf2.set("fs.s3a.server-side-encryption-algorithm", "SSE-KMS");
conf2.set("fs.s3a.connection.ssl.enabled", "true");
conf2.set("fs.s3a.endpoint", s3Endpoint);



ParquetWriter<GenericRecord> writer1 = AvroParquetWriter.<GenericRecord>builder(path)
                    .withSchema(parquetSchema)
                    .withConf(conf1)
                    .withWriteMode(ParquetFileWriter.Mode.CREATE)
                    .build();

ParquetWriter<GenericRecord> writer2 = AvroParquetWriter.<GenericRecord>builder(path)
                    .withSchema(parquetSchema)
                    .withConf(conf2)
                    .withWriteMode(ParquetFileWriter.Mode.CREATE)
                    .build();

writer1并创建不同的文件,但即使我指定了不同的writer2文件,它们也都用密钥加密。awsKmsId1

标签: javahadoopparquetamazon-kms

解决方案


我找到了解决这个问题的方法!这个问题是由FileSystemhadoop-common (3.3.0) 中的缓存引起的。它在构建缓存键时不使用该Configuration对象,因此当它尝试FileSystem从缓存中获取时,它会返回旧FileSystem的,因为 URI 方案是相同的。我通过禁用缓存来解决这个问题conf.set("fs.s3a.impl.disable.cache", "true");。这个问题可以在这个 Apache Jira问题中看到


推荐阅读