我在 Amazon EMR 上的 Apache Spark 或 Apache Hive 作业失败并显示 HTTP 503“Slow Down”AmazonS3Exception 错误。
简短描述
当应用程序的 Amazon Simple Storage Service (Amazon S3) 请求速率超过典型持续速率,并且 Amazon S3 在内部优化性能时,将会出现以下错误:
“java.io.IOException: com.amazon.ws.emr.hadoop.fs.shaded.com.amazonaws.services.s3.model.AmazonS3Exception: Slow Down (Service: Amazon S3;状态代码: 503;错误代码: 503 Slow Down; Request ID: 2E8B8866BFF00645; S3 Extended Request ID: oGSeRdT4xSKtyZAcUe53LgUf1+I18dNXpL2+qZhFWhuciNOYpxX81bpFiTw2gum43GcOHR+UlJE=), S3 Extended Request ID: oGSeRdT4xSKtyZAcUe53LgUf1+I18dNXpL2+qZhFWhuciNOYpxX81bpFiTw2gum43GcOHR+UlJE=”
解决方法
配置 CloudWatch 请求指标
为了确定请求过多的问题,最佳做法是为 Amazon S3 存储桶配置 Amazon CloudWatch 请求指标。
为存储桶启用 CloudWatch 请求指标并为前缀定义筛选条件。
修改 Amazon S3 请求的重试策略
默认情况下,EMR 文件系统 (EMRFS) 使用指数回退策略重试对 Amazon S3 的请求。默认 EMRFS 重试限制为 15。但是,您可以提高新集群、正在运行的集群或应用程序运行时的重试限制。
要提高重试限制,请更改 fs.s3.maxRetries 参数的值。
**注意:**如果您将此参数设置为非常高的值,则您的任务持续时间可能会变长。
将参数设置为较高的值(例如 20),并监控作业的持续时间开销。然后根据您的使用案例调整参数。
对于新集群,您可以在启动集群时添加配置对象,类似于以下内容:
[
{
"Classification": "emrfs-site",
"Properties": {
"fs.s3.maxRetries": "20"
}
}
]
启动集群后,在 Amazon EMR 上运行的 Spark 和 Hive 应用程序将使用新的限制。
要增加正在运行的集群的重试限制,请完成以下步骤:
- 打开 Amazon EMR 控制台。
- 选择要重新配置的活动集群。
- 选择 Configurations(配置)选项卡。
- 在 Filter(筛选条件)下拉列表中,选择要重新配置的实例组。
- 在 Reconfigure(重新配置)下拉列表中,选择 Edit in table(在表中编辑)。
- 在配置分类表中,选择 Add configuration(添加配置),然后使用以下值:
对于 Classification(分类),使用 emrfs-site
对于 Property(属性),使用 fs.s3.maxRetries
对于 Value(值),使用新的重试限制值。例如 20。
- 选择 Apply this configuration to all active instance groups(将此配置应用于所有活动实例组)。
- 选择 Save changes(保存更改)。
在部署配置后,Spark 和 Hive 应用程序将使用新限制。
要提高 Spark 应用程序在运行时的重试限制,请使用 Spark Shell 会话修改 fs.s3.maxRetries 参数,如下例所示:
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 ....
调整并发 Amazon S3 请求的数量
- 如果您有多个作业(Spark、Apache Hive 或 s-dist-cp)读取和写入相同的 Amazon S3 前缀,则您可以调整并发性。从最繁重的读/写作业开始,降低这些作业的并发性,以避免过高的并行性。
**注意:**如果您为 Amazon S3 配置了跨账户访问权限,则其他 AWS 账户也可能会向相同的前缀提交作业。
- 如果您在作业尝试写入目标存储桶时遇到错误,请降低过高的写入并行性。例如,在写入 Amazon S3 之前,使用 Spark .coalesce() 或 .repartition() 操作减少 Spark 输出分区的数量。您还可以减少每个执行程序的内核数量或减少执行程序的数量。
- 如果您在作业尝试从源存储桶读取时遇到错误,请调整对象的大小。要减少作业读取的对象数量,请将较小的对象聚合为较大的对象。例如,使用 s3-dist-cp 将大量小文件合并为少量大文件。
相关信息
最佳做法设计模式:优化 Amazon S3 性能
为什么我的 Amazon EMR 应用程序失败,并显示 HTTP 403“Access Denied”(访问被拒绝)AmazonS3Exception 错误?
为什么我的 Amazon EMR 应用程序失败并显示 HTTP 404“Not Found”(未找到)AmazonS3Exception 错误?