EMR 上的 Spark 或 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 请求)时发生。

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

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

 

解决方案

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

配置 CloudWatch 请求指标

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

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

减少 Amazon S3 请求的数量

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

添加更多前缀到 S3 存储桶

解决 "Slow Down" 错误的另一种方法是,添加更多前缀到 S3 存储桶。存储桶中的前缀数量没有限制。请求速率针对每个前缀,而不是存储桶。

例如,如果您在一个存储桶中创建三个前缀,如下:

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

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

提高 EMRFS 重试限制

默认情况下,EMRFS 重试限制设置为 4。运行以下命令,以确认集群的重试限制:

$ hdfs getconf -confKey fs.s3.maxRetries
  • 要提高新集群的重试限制:请在启动集群时添加以下类似的配置对象。
  • 要在运行的集群上提高重试限制:请使用以下配置对象覆盖实例组的集群配置(Amazon EMR 版本 5.21.0 及更高版本)。

 

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

提高集群的重试限制时,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/")

 

你可能感兴趣的:(AWS)