3.

AWS RequestThrottled(リクエスト過多)の原因と回避策(指数バックオフ)

編集
この記事の要点
  • RequestThrottled = AWS API のレート制限に引っかかった状態
  • 原因: 短時間に大量リクエスト / アカウントレベル上限 / 特定 API のバースト制限
  • 対処: 指数バックオフ (Exponential Backoff) + ジッター付きリトライ
  • AWS SDK は自動リトライ機構を持つ → デフォルト 3 回 → 増やせる
  • 根本対策: バッチ API 利用 / 並列度制限 / Service Quotas で上限緩和申請

エラー内容

RequestThrottled: Request was throttled.
AWS Access Key ID: AKIAXXXXXXXXXXXXXXXX
You are submitting requests too quickly. Please slow down.

Error Code: Throttling / ThrottlingException / TooManyRequestsException / RequestLimitExceeded
HTTP Status: 400 / 429 / 503

名前は API ごとに異なります(Throttling / ThrottlingException / TooManyRequestsException / RequestLimitExceeded など)が、原因と対処は同じです。

原因の切り分け

原因確認対処
短時間バーストCloudWatch でリクエスト数のスパイク確認指数バックオフリトライ
並列度過多ECS / Lambda 同時実行数を確認並列度制限 / バッチ化
アカウント上限到達Service Quotas で現在値確認上限緩和申請
特定 API の制限(例: STS AssumeRole)該当 API ドキュメントの TPS 確認キャッシュ / 集約
他テナント・他リソースとの共有S3 / DynamoDB のホットパーティションキー分散 / リシャード

対処1: AWS SDK のリトライ設定を強化

AWS SDK はデフォルトで指数バックオフリトライを持っています。回数や戦略を調整できます。

AWS SDK for Java (v2)

import software.amazon.awssdk.core.retry.RetryPolicy;
import software.amazon.awssdk.core.retry.RetryMode;
import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration;

S3Client.builder()
  .overrideConfiguration(ClientOverrideConfiguration.builder()
    .retryPolicy(RetryPolicy.builder()
      .numRetries(10)                                     // 既定 3 → 10
      .retryMode(RetryMode.ADAPTIVE)                      // ★ 推奨
      .build())
    .build())
  .build();

// RetryMode:
//   LEGACY    - 旧デフォルト
//   STANDARD  - 新デフォルト(指数バックオフ + ジッター)
//   ADAPTIVE  - スロットリング検知時に自動でレート抑制

AWS SDK for Python (boto3)

import boto3
from botocore.config import Config

config = Config(
    retries = {
        'max_attempts': 10,
        'mode': 'adaptive',     # standard / adaptive / legacy
    }
)
s3 = boto3.client('s3', config=config)

AWS SDK for JavaScript (v3)

import { S3Client } from '@aws-sdk/client-s3';
import { ConfiguredRetryStrategy } from '@aws-sdk/util-retry';

const client = new S3Client({
  maxAttempts: 10,
  retryStrategy: new ConfiguredRetryStrategy(
    10,                                   // 最大リトライ
    (attempt) => 100 + attempt * 1000     // バックオフ ms
  ),
});

対処2: 自前で指数バックオフ実装

SDK でカバーしきれない場合や、自前 HTTP クライアントを使う場合:

import time
import random
from botocore.exceptions import ClientError

def call_aws_with_backoff(fn, max_retries=5):
    """指数バックオフ + ジッター付きリトライ"""
    for attempt in range(max_retries):
        try:
            return fn()
        except ClientError as e:
            code = e.response['Error']['Code']
            if code in ('Throttling', 'ThrottlingException',
                        'TooManyRequestsException', 'RequestLimitExceeded',
                        'RequestThrottled'):
                if attempt == max_retries - 1:
                    raise
                # 指数バックオフ + フルジッター
                base = 0.5 * (2 ** attempt)
                sleep = random.uniform(0, base)
                time.sleep(sleep)
                continue
            raise
    raise RuntimeError("max retries exceeded")

# 利用
result = call_aws_with_backoff(lambda: s3.list_objects_v2(Bucket='mybucket'))

対処3: 並列度を制限

from concurrent.futures import ThreadPoolExecutor
import boto3

s3 = boto3.client('s3')

# ❌ 1000 並列でスロットリング確定
with ThreadPoolExecutor(max_workers=1000) as ex:
    list(ex.map(lambda key: s3.delete_object(Bucket='b', Key=key), keys))

# ✅ 10 並列に制限
with ThreadPoolExecutor(max_workers=10) as ex:
    list(ex.map(lambda key: s3.delete_object(Bucket='b', Key=key), keys))

# ✅ バッチ API を使う(最強)
batch = [{'Key': k} for k in keys[:1000]]
s3.delete_objects(Bucket='b', Delete={'Objects': batch})

対処4: Service Quotas で上限緩和

頻繁にスロットリングする場合は、AWS コンソールから上限緩和を申請:

  1. AWS コンソール → Service Quotas を開く
  2. 該当サービス(例: EC2)を選択
  3. 該当クォータ(例: API requests per second)を選択
  4. クォータの引き上げをリクエスト
  5. 承認まで数時間〜数日

サービス別の主な制限

サービス制限の例緩和方法
S33500 PUT/s, 5500 GET/s per prefix★ プレフィックス分散
DynamoDBWCU/RCU、パーティション 1000 WCU 制限キー設計でホット回避 + Auto Scaling
STS AssumeRoleアカウント単位の TPS★ 認証情報キャッシュ
EC2 APIAPI ごとに別個の TPSバッチ API / 並列度制限
SES送信レート(秒間)+ 日次クォータSQS でキューイング
Lambda同時実行数上限(既定 1000)上限緩和申請 / リザーブド同時実行

監視: CloudWatch でスロットリングを可視化

# 主要サービスのスロットリングメトリクス
DynamoDB        : UserErrors, SystemErrors, ThrottledRequests
Lambda          : Throttles
API Gateway     : 4XXError (429含む)
SQS             : NumberOfMessagesSent + エラー
SES             : Bounce / Complaint / Send

CloudWatch アラームを設定して通知:
- ThrottledRequests > 0 → Slack 通知
- Lambda Throttles > 10/min → 上限緩和検討

FAQ

Q: リトライしてもずっとスロットリングする
A: アカウント上限に到達している可能性大。Service Quotas で確認し、上限緩和申請してください。

Q: 並列度を 1 にしてもスロットリングする
A: 他のシステム(同じアカウントの別 Lambda 等)が API を使っていませんか? アカウント全体で共有する制限もあります。

Q: 429 と 503 の違いは?
A: 429 (Too Many Requests) はクライアント起因のレート超過、503 (Service Unavailable) はサービス側の過負荷。どちらもリトライ対象です。

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. Error 400 : Bad Request Parameter Operation is missing
  2. MissingParameter. The request must contain the parameter Signature.
  3. RequestThrottled. AWS Access Key ID: ... . You are submitting requests too quickly
  4. SignatureDoesNotMatch. The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.
  5. failed to open stream: HTTP request failed! HTTP/1.1 503 Service Unavailable