我想配置一个 AWS Glue ETL 作业来输出少量的大文件,而不是大量的小文件。
解决方法
增加 groupSize 参数的值
当您使用动态框架且 Amazon Simple Storage Service (Amazon S3) 数据集包含超过 50,000 个文件时,AWS Glue ETL 作业会自动对文件进行分组。要创建少量较大型输出文件,请增加 groupSize 值。有关详细信息,请参阅以更大的组形式读取输入文件。
在以下示例中,groupSize 设置为 10485760 个字节,或大约 10 MB:
dyf = glueContext.create_dynamic_frame_from_options("s3", {'paths': ["s3://awsexamplebucket/"], 'groupFiles': 'inPartition', 'groupSize': '10485760'}, format="json")
**注意:**仅 .csv、.ion、.grokLog、.json 和 .xml 文件格式支持 groupSize 和 groupFiles 参数。.avro、.parquet 和 .orc 文件格式不支持这些参数。
使用 coalesce 或 repartition
完成下面的步骤:
-
(可选)根据输入数据集大小计算目标分区数 (N)。使用 targetNumPartitions = 1 Gb * 1000 Mb/10 Mb = 100 公式控制输出文件的大小。
**注意:**在以上公式中,输入大小为 1 GB,目标输出大小为 10 MB,目标分区数为 100。
-
要检查当前的分区数,请运行以下命令:
currentNumPartitions = dynamic_frame.getNumPartitions()
-
要减少输出文件的数量,请在写入 Amazon S3 之前减少 Apache Spark 输出分区的数量。要减少分区数,请使用 Spark coalesce 函数:
dynamic_frame_with_less_partitions=dynamic_frame.coalesce(targetNumPartitions)
**注意:**如果 targetNumPartitions 过小,作业可能会因为磁盘空间问题而失败。
-or-
使用 Apache Spark repartition 函数。
dynamic_frame_with_less_partitions=dynamic_frame.repartition(targetNumPartitions)
**注意:**要生成更大的文件,请将 targetNumPartitions 设置为小于 currentNumPartitions 的值。
coalesce 和 repartition 函数可能会增加作业运行时间,因为这两个函数都会对数据进行重组。但是,**coalesce ** 函数会使用现有分区来最大限度地减少数据重组。
使用 maxRecordsPerFile
在 Spark write 方法中使用 maxRecordsPerFile 来增加每个文件的最大记录计数。以下示例将最大记录计数设置为 20:
df.write.option("compression", "gzip").option("maxRecordsPerFile", 20).json(s3_path)
**注意:**maxRecordsPerFile 选项为每个文件的记录计数设置了更高的配额。每个文件的记录计数可能仍小于 maxRecordsPerFile 的值。如果将 maxRecordsPerFile 设置为零或负数,则记录计数没有配额。
相关信息
修复使用分组处理多个文件时出现的问题