問題現象
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/")