我的 Amazon EMR 上的 Spark 或 Hive 作业失败并出现 HTTP 503“Slow Down”AmazonS3Exception

上次更新时间:2020 年 4 月 20 日

我的 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) 请求速率时,会发生此错误。请求速率为存储桶中每个前缀每秒 3500 个 PUT/COPY/POST/DELETE 请求和 5500 个 GET/HEAD 请求。

解决此问题的方式有三种:

  • 添加更多前缀到 S3 存储桶。
  • 减少 Amazon S3 请求的数量。
  • 提高 EMR 文件系统 (EMRFS) 重试限制。

解决方法

在您可以确定请求过多的问题前,首先配置 Amazon CloudWatch 的请求指标。

配置 CloudWatch 请求指标

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

在启用指标后,使用指标中的数据确定以下哪个解决办法最适用于您的使用情形。

添加更多前缀到 S3 存储桶

存储桶中的前缀数量没有限制。请求速率针对每个前缀,而不是存储桶。例如,如果您在一个存储桶中创建三个前缀,如下:

  • s3://awsexamplebucket/images
  • s3://awsexamplebucket/videos
  • s3://awsexamplebucket/documents

那么,您可以每秒对该存储桶发出 10500 个写入请求或 16500 个读取请求。

减少 Amazon S3 请求的数量

  • 如果多个并发作业(Spark、Apache Hive 或 s3-dist-cp)正在读取或写入相同的 Amazon S3 前缀:减少并发作业的数量。从最繁重的读/写作业开始。如果您为 Amazon S3 配置了跨账户访问,请记住其他账户也有可能会提交作业到前缀。
  • 如果作业尝试写入目标存储桶时发生错误:降低作业的并行性。例如,在写入 Amazon S3 前使用 Spark .coalesce().repartition() 操作减少 Spark 输出分区的数量。您还可以减少每个执行程序的内核数量,或减少执行程序的数量。
  • 如果作业尝试从源存储桶读取时发生错误:减少文件数量,从而减少 Amazon S3 请求的数量。例如,使用 s3-dist-cp 将大量小文件合并成少量大文件。

提高 EMRFS 重试限制

默认情况下,EMRFS 重试限制设置为 4。您可以在正在运行的集群上或在应用程序运行时提高新集群的重试限制。

要在没有 EMRFS 一致性的情况下提高新集群的重试限制,在启动集群时添加与下面类似的配置对象

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

要启动具有 EMRFS 一致性和更高重试限制的新集群:

代替在步骤 3:常规集群设置中启用 EMRFS 一致视图,在启动集群时,在其他选项下,添加与下面类似的配置对象。此配置指定 EMRFS 一致视图的所有必填属性,并将重试限制提高至 20。

[
    {
      "Classification": "emrfs-site",
      "Properties": {
        "fs.s3.maxRetries": "20",
        "fs.s3.consistent.retryPeriodSeconds": "10",
        "fs.s3.consistent": "true",
        "fs.s3.consistent.retryCount": "5",
        "fs.s3.consistent.metadata.tableName": "EmrFSMetadata"
      }
    }
]

在启动集群后, Spark 和 Hive 应用程序将使用新限制。

要提高正在运行的集群的重试限制:

1.    打开 Amazon EMR 控制台

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

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

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

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

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

对于分类:emrfs-site
对于属性:fs.s3.maxRetries
对于:新的重试限制的次数(例如,20)

7.    选择将此配置应用到所有活动的实例组,然后选择保存更改

在部署配置后, 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 ....