Amazon EMR で Hive または Spark ジョブが 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) のリクエストレートを超えた場合に発生します。リクエストレートは、バケットのプレフィックスごとに 1 秒あたり PUT/COPY/POST/DELETE リクエスト 3,500 回と GET/HEAD リクエスト 5,500 回です。

この問題を解決するには、次の 3 つの方法があります。

  • S3 バケットにプレフィックスを追加する。
  • Amazon S3 リクエストの数を減らす。
  • EMR ファイルシステム (EMRFS) の再試行制限を引き上げる。

解決方法

リクエストが多すぎる問題を特定するには、まず Amazon CloudWatch リクエストメトリクスを設定します。

CloudWatch リクエストメトリクスの設定

Amazon S3 リクエストをモニタリングするには、バケットの CloudWatch リクエストメトリクスを有効にします。次に、プレフィックスの フィルタを定義します。モニタリングに役立つメトリクスのリストについては、 Amazon S3 CloudWatch リクエストメトリクスを参照してください。

メトリクスを有効にしたら、メトリクスのデータを使用して、以下のうち、どれがユースケースに最適かを判断します。

S3 バケットにプレフィックスを追加する

バケット内のプレフィックス数に制限はありません。リクエストレートは、バケットではなく各プレフィックスに適用されます。たとえば、次のように、バケットに 3 つのプレフィックスを作成するとします。

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

この場合、そのバケットに対して 1 秒あたり 10,500 件の書き込みリクエストまたは 16,500 件の読み込みリクエストを行うことができます。

Amazon S3 リクエストの数を減らす

  • 複数の同時ジョブ (Spark、Apache Hive、または s3-dist-cp) が同じ Amazon S3 プレフィックスに対して読み込みまたは書き込みを行っている場合: ジョブの同時実行数を減らします。最も読み書きの多いジョブから開始します。Amazon S3 のクロスアカウントアクセスを設定した場合、他のアカウントもプレフィックスにジョブを送信している可能性があることに注意してください。
  • ジョブがレプリケート先バケットに書き込もうとしたときにエラーが発生した場合: ジョブの並列処理を減らします。たとえば、Spark の .coalesce() または .repartition() 演算を使用して、Amazon S3 に書き込む前に 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 シェルセッションの例を次に示します。

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 ....