为什么 Amazon EMR 上的 Spark 或 Hive 任务失败并显示 HTTP 503“Slow Down”(运行缓慢)AmazonS3Exception 错误?

上次更新日期: 2022 年 5 月 17 日

我的 Amazon EMR 上的 Apache Spark 或 Apache Hive 任务失败并出现 HTTP 503“Slow Down”(运行缓慢)AmazonS3Exception 错误,类似于以下内容:

java.io.IOException: com.amazon.ws.emr.hadoop.fs.shaded.com.amazonaws.services.s3.model.AmazonS3Exception: Slow Down (Service: Amazon S3; Status Code: 503; Error Code: 503 Slow Down; Request ID: 2E8B8866BFF00645; S3 Extended Request ID: oGSeRdT4xSKtyZAcUe53LgUf1+I18dNXpL2+qZhFWhuciNOYpxX81bpFiTw2gum43GcOHR+UlJE=), S3 Extended Request ID: oGSeRdT4xSKtyZAcUe53LgUf1+I18dNXpL2+qZhFWhuciNOYpxX81bpFiTw2gum43GcOHR+UlJE=

简短描述

当应用程序的 Amazon Simple Storage Service (Amazon S3) 请求速率超过每秒 5000 个请求的典型持续速率并且 Simple Storage Service (Amazon S3) 优化内部性能时,就会出现此错误。

要提高使用 Amazon EMR 访问 S3 数据时的请求成功率,请尝试以下方法:

  • 修改 S3 请求的重试策略。
  • 调整并发 S3 请求的数量。

解决方法

为了帮助确定请求过多的问题,最佳实践是为 S3 存储桶配置 Amazon CloudWatch 请求指标。您可以根据这些 CloudWatch 指标确定最适合您的使用案例的解决方案。

配置 CloudWatch 请求指标

要监控 Amazon S3 请求,请为存储桶启用 CloudWatch 请求指标。然后,为前缀定义筛选条件。有关要监控的有用指标列表,请参阅使用 Amazon CloudWatch 监控指标

修改 S3 请求的重试策略

默认情况下,EMRFS 使用指数回退策略重试对 Simple Storage Service (Amazon S3) 的请求。默认 EMRFS 重试限制为 15。但是,您可以在正在运行的集群上或在应用程序运行时提高新集群的重试限制。

要增加重试限制,请更改 fs.s3.maxRetries 参数的值。如果您为此参数设置了很高的值,则可能会遇到更长的任务持续时间。尝试将此参数设置为较高的值(例如,20),监控任务的持续时间开销,然后根据您的使用案例调整此参数。

对于新集群,您可以在启动集群时添加类似于以下内容的配置对象:

[
  {
    "Classification": "emrfs-site",
    "Properties": {
      "fs.s3.maxRetries": "20"
    }
  }
]

在启动集群后,运行在 Amazon EMR 上的 Spark 和 Hive 应用程序将使用新限制。

要提高正在运行的集群的重试限制,请执行以下操作:

1.    打开 Amazon EMR 控制台

2.    在集群列表中,在名称下选择要重新配置的活动集群。

3.    打开集群的集群详细信息页面,然后选择配置选项卡。

4.    在筛选条件下拉列表中,选择您想要重新配置的实例组。

5.    在重新配置下拉列表中,选择在表中编辑

6.    在配置分类表中,选择添加配置,然后输入以下内容:

对于分类:emrfs-site

对于属性:fs.s3.maxRetries

对于:新的重试限制的次数(例如,20)

7.    选择将此配置应用到所有活动的实例组

8.    选择保存更改

在部署配置后,Spark 和 Hive 应用程序将使用新限制。

要在运行时增加重试限制,请使用类似于以下内容的 Spark shell 会话:

spark> sc.hadoopConfiguration.set("fs.s3.maxRetries", "20")
spark> val source_df = spark.read.csv("s3://awsexamplebucket/data/")
spark> source_df.write.save("s3://awsexamplebucket2/output/")

以下是在运行时为 Hive 应用程序提高重试限制的示例:

hive> set fs.s3.maxRetries=20;
hive> select ....

调整并发 S3 请求的数量

  • 如果您有多个任务(Spark、Apache Hive 或 s-dist-cp)读取和写入相同的 S3 前缀,则可以调整并发性。从最繁重的读/写任务开始,降低这些任务的并发性,从而避免过高的并行性。如果您为 Simple Storage Service (Amazon S3) 配置了跨账户访问,请记住其他账户也有可能会提交任务到相同的前缀。
  • 如果您在任务尝试写入目标存储桶时遇到错误,请降低过高的写入并行性。例如,在写入 Simple Storage Service (Amazon S3) 前使用 Spark .coalesce().repartition() 操作减少 Spark 输出分区的数量。您还可以减少每个执行程序的内核数量,或减少执行程序的数量。
  • 如果您在任务尝试从源存储桶读取时遇到错误,请调整对象的大小。您可以将较小的对象聚合为较大的对象,以便减少任务要读取的对象数量。这便于您的任务以较少的读取请求读取数据集。例如,使用 s3-dist-cp 将大量小文件合并成少量大文件。