由 S3 异常 "Please reduce your request rate" 引起的 AWS Glue ETL"Failed to delete key: target_folder/_temporary"

AWS Glue ETL"Failed to delete key: target_folder/_temporary" caused by S3 exception "Please reduce your request rate"

Glue 作业配置为最大 10 个节点容量,1 个并行作业且失败时不重试会给出错误 "Failed to delete key: target_folder/_temporary",根据堆栈跟踪,问题是 S3 服务开始阻止 Glue 请求,因为请求数量:"AmazonS3Exception: Please reduce your request rate."

注意:问题不在于 IAM,因为胶水作业正在使用的 IAM 角色具有删除 S3 中对象的权限。

我在 GitHub 上找到了关于此问题的建议,建议减少工人数量:https://github.com/aws-samples/aws-glue-samples/issues/20

"I've had success reducing the number of workers."

但是,我认为 10 个工作人员并不过分,甚至想将工作人员数量实际增加到 20 个以加快 ETL。

有没有遇到过这个问题的人成功了?我将如何解决它?

缩短的堆栈跟踪:

py4j.protocol.Py4JJavaError: An error occurred while calling o151.pyWriteDynamicFrame.
: java.io.IOException: Failed to delete key: target_folder/_temporary
    at com.amazon.ws.emr.hadoop.fs.s3n.S3NativeFileSystem.delete(S3NativeFileSystem.java:665)
    at com.amazon.ws.emr.hadoop.fs.EmrFileSystem.delete(EmrFileSystem.java:332)
    ...
Caused by: java.io.IOException: 1 exceptions thrown from 12 batch deletes
    at com.amazon.ws.emr.hadoop.fs.s3n.Jets3tNativeFileSystemStore.deleteAll(Jets3tNativeFileSystemStore.java:384)
    at com.amazon.ws.emr.hadoop.fs.s3n.S3NativeFileSystem.doSingleThreadedBatchDelete(S3NativeFileSystem.java:1372)
    at com.amazon.ws.emr.hadoop.fs.s3n.S3NativeFileSystem.delete(S3NativeFileSystem.java:663)
    ...
Caused by: com.amazon.ws.emr.hadoop.fs.shaded.com.amazonaws.services.s3.model.AmazonS3Exception: Please reduce your request rate. (Service: Amazon S3; Status Code: 503; Error Code: SlowDown; Request ID: ...

Glue ETL python 脚本的一部分(以防万一):

datasource0 = glueContext.create_dynamic_frame.from_catalog(database="database", table_name="table_name", transformation_ctx="datasource0")

... relationalizing, renaming and etc. Transforming from DynamicDataframe to PySpark dataframe and back.

partition_ready = Map.apply(frame=processed_dataframe, f=map_date_partition, transformation_ctx="map_date_partition")
datasink = glueContext.write_dynamic_frame.from_options(frame=partition_ready, connection_type="s3", connection_options={"path": "s3://bucket/target_folder", "partitionKeys": ["year", "month", "day", "hour"]}, format="parquet", transformation_ctx="datasink")
job.commit()

已解决(有点),感谢用户 ayazabbas

接受了帮助我找到解决方案正确方向的答案。我一直在寻找的一件事是如何将许多小文件减少成大块,而重新分区正是这样做的。我没有使用 repartition(x),而是使用了 coalesce(x),其中 x 是粘合作业的 4*worker 计数,以便 Glue 服务可以将每个数据块分配给每个可用的 vCPU 资源。如果它们确实存在,则 x 至少 2*4*worker_count 来解释更慢和更快的转换部分可能是有意义的。

我做的另一件事是在将数据写入 S3 之前将数据分区的列数从 5 减少到 4。

目前的缺点是我还没有弄清楚如何在胶水服务为作业分配的胶水脚本中找到工人数量,因此数量是根据作业配置硬编码的(胶水服务分配有时更多节点数比配置的多)。

我遇到了同样的问题。在写入 S3 之前,我在动态框架上通过 运行 repartition(x) 解决了这个问题。这会强制每个分区 x 个文件,写入过程中的最大并行度将为 x,从而降低 S3 的请求率。

我将 x 设置为 1,因为我希望每个分区有 1 个 parquet 文件,所以我不确定在请求率变得过高之前您可以拥有的安全并行度上限是多少。

我想不出更好的方法来解决这个问题,这很烦人,因为在写入过程中您有太多空闲容量。

希望对您有所帮助。