Lambda マネージドインスタンスのトラブルシューティング - AWS Lambda

Lambda マネージドインスタンスのトラブルシューティング

スロットリングとスケーリングの問題

スケールアップ中のエラー率が高い

問題: トラフィックが急速に増加すると、スロットリングエラー (HTTP 429) が発生する。

原因: Lambda マネージドインスタンスは、CPU リソース使用率と同時実行数の飽和度に基づいて非同期的にスケーリングされます。トラフィックが 5 分以内に 2 倍を超えると、Lambda が需要に合わせてインスタンスと実行環境をスケールアップするため、スロットリングが表示されることがあります。

解決策:

  • ターゲットリソース使用率の調整: ワークロードに予測可能なトラフィックパターンがある場合は、ターゲットリソース使用率を低く設定して、トラフィックバーストのヘッドルームを増やします。

  • 事前ウォーミングキャパシティ: 計画的なトラフィックの増加については、スケーリングが遅れないように、より長い期間にわたってトラフィックを徐々に増やします。

  • スケーリングメトリクスのモニタリング: スロットルエラーメトリクスを追跡して、スロットルとキャパシティスケーリングの問題の理由を理解します。

  • 関数設定の確認: 関数メモリと vCPU 設定が複数同時実行をサポートしていることを確認します。必要に応じて、関数メモリまたは vCPU 割り当てを増やします。

スケールダウンが遅い

問題: トラフィックが減少した後、インスタンスのスケールダウンに時間がかかる。

原因: Lambda マネージドインスタンスは、可用性を維持し、パフォーマンスに影響を与える可能性のある急速な容量変更を回避するために、徐々にスケールダウンします。

解決策:

これは想定される動作です。Lambda は、安定性を確保するためにインスタンスを控えめにスケールダウンします。CloudWatch メトリクスをモニタリングして、実行中のインスタンスの数を追跡します。

同時実行の問題

同時実行が低い実行環境でスロットリングが発生する

問題: 使用可能な容量があるにもかかわらず、関数にスロットリングが発生する。

原因: 最大同時実行数が非常に低い実行環境では、効果的なスケーリングが困難な場合があります。Lambda マネージドインスタンスは、複数同時実行アプリケーション用に設計されています。

解決策:

  • 最大同時実行数を増やす: 関数呼び出しで使用する CPU が非常に少ない場合は、vCPU あたりの最大同時実行数設定を最大 64 まで増やします。

  • 関数コードを最適化する: 関数コードを確認して、呼び出しあたりの CPU 消費量を減らし、同時実行数を増やします。

  • 関数のメモリと vCPU を調整する: 関数に複数の同時呼び出しを処理するのに十分なリソースがあることを確認します。

スレッドの安全性の問題 (Java ランタイム)

問題: 負荷がかかると、Java 関数が誤った結果を生成したり、競合状態が発生したりする。

原因: 複数のスレッドがハンドラーメソッドを同時に実行し、共有状態はスレッドセーフではありません。

解決策:

  • プリミティブ型の代わりにカウンターに AtomicInteger または AtomicLong を使用する

  • HashMapConcurrentHashMap に置き換える

  • Collections.synchronizedList() を使用して ArrayList をラップする

  • リクエスト固有の状態に ThreadLocal を使用する

  • 環境変数ではなく Lambda Context オブジェクトからトレース ID にアクセスする

詳細なガイダンスについては、「Lambda マネージドインスタンスの Java ランタイム」ドキュメントを参照してください。

状態分離の問題 (Node.js ランタイム)

問題: Node.js 関数がさまざまなリクエストからのデータを返すか、データ破損が発生する。

原因: グローバル変数が、同じワーカースレッド上の同時呼び出し間で共有されています。非同期オペレーションが制御する場合、他の呼び出しは共有状態を変更できます。

解決策:

  • すべてのリクエスト固有の状態に @aws/lambda-invoke-store をインストールして使用する

  • グローバル変数を InvokeStore.set() および InvokeStore.get() に置き換える

  • /tmp でリクエスト ID を含む一意のファイル名を使用する

  • 環境変数の代わりに InvokeStore.getXRayTraceId() を使用してトレース ID にアクセスする

詳細なガイダンスについては、「Lambda マネージドインスタンスの Node.js ランタイム」ドキュメントを参照してください。

ファイル競合 (Python ランタイム)

問題: Python 関数が /tmp のファイルから誤ったデータを読み取る。

原因: 複数のプロセスが /tmp ディレクトリを共有しています。同じファイルに同時に書き込むと、データが破損する可能性があります。

解決策:

  • リクエスト ID を含む一意のファイル名を使用する: /tmp/request_{context.request_id}.txt

  • fcntl.flock() で共有ファイルにファイルロックを使用する

  • 使用後に os.remove() で一時ファイルをクリーンアップする

詳細なガイダンスについては、「Lambda マネージドインスタンスの Python ランタイム」ドキュメントを参照してください。

パフォーマンスの問題

メモリ使用率が高い

問題: 関数でメモリ使用率が高いかメモリー不足のエラーが発生する。

原因: Python の同時リクエストは、それぞれ独自のメモリ容量を持つ個別のプロセスで実行されています。合計メモリ使用量は、プロセスあたりのメモリに同時処理を乗じたものと等しくなります。

解決策:

  • CloudWatch で MemoryUtilization メトリクスをモニタリングする

  • メモリ使用量が関数のメモリ制限に近づいた場合は、MaxConcurrency 設定を減らす

  • 関数のメモリ割り当てを増やして同時実行数を増やす

  • 初期化中ではなくオンデマンドでデータをロードしてメモリ使用量を最適化する

パフォーマンスの不整合

問題: 関数のパフォーマンスが呼び出し間で大きく異なる。

原因: Lambda が可用性に基づいて異なるインスタンスタイプを選択しているか、リソースの可用性が異なるインスタンスで関数が実行されている可能性があります。

解決策:

  • 許可されるインスタンスタイプを指定する: 特定のパフォーマンス要件がある場合は、Lambda が選択できるインスタンスタイプを制限するようにキャパシティープロバイダーで許可されるインスタンスタイプを設定します。

  • インスタンスレベルのメトリクスをモニタリングする: キャパシティープロバイダーレベルで CPUUtilizationMemoryUtilization を追跡して、リソースの制約を特定します。

  • キャパシティメトリクスを確認する: vCPUAvailableMemoryAvailable を確認して、インスタンスで十分なリソースが使用可能であることを確認します。

キャパシティープロバイダーの問題

関数バージョンが ACTIVE にならない

問題: 関数のバージョンが公開後も保留状態のままです。

原因: Lambda がマネージドインスタンスを起動し、実行環境を開始しています。このプロセスは時間がかかります。特に新しいキャパシティープロバイダーの最初の関数バージョンの場合はなおさらです。

解決策:

Lambda が初期化プロセスを完了するまで待ちます。Lambda は、AZ の回復性のためにデフォルトで 3 つのインスタンスを起動し、実行環境を 3 つ開始すると、関数バージョンが ACTIVE にマークされます。これには通常数分かかります。

キャパシティープロバイダーを削除できない

問題: キャパシティープロバイダーを削除しようとするとエラーが発生する。

原因: 関数バージョンがアタッチされているキャパシティープロバイダーは削除できません。

解決策:

  1. ListFunctionVersionsByCapacityProvider API でキャパシティープロバイダーを使用して、すべての関数バージョンを特定します。

  2. これらの関数バージョンを削除または更新して、キャパシティープロバイダーの関連付けを削除します。

  3. キャパシティープロバイダーの削除を再試行します。

関数の公開中の一般的なエラーメッセージ

問題: 関数の公開時に「公開中に内部エラーが発生しました」などの一般的なエラーメッセージが表示される。

解決策:

  • IAM アクセス許可を確認する: 使用しようとしているキャパシティープロバイダーの lambda:PassCapacityProvider アクセス許可があることを確認します。

  • キャパシティープロバイダーの設定を確認する: GetCapacityProvider API を使用して、キャパシティープロバイダーが ACTIVE 状態であることを確認します。

  • VPC 設定を確認する: キャパシティープロバイダーで指定されたサブネットとセキュリティグループが正しく設定され、アクセス可能であることを確認します。

  • AWS CloudTrail ログを確認する: CloudTrail ログで、失敗したオペレーションに関する詳細なエラー情報を確認します。

モニタリングとオブザーバビリティの問題

CloudWatch メトリクスがない

問題: キャパシティープロバイダーまたは関数について、予想されるメトリクスが CloudWatch に表示されない。

原因: メトリクスは 5 分間隔で発行されます。新しいキャパシティープロバイダーまたは関数では、メトリクスがすぐに利用できない場合があります。

解決策:

メトリクスが CloudWatch に表示されるまで、関数バージョンを公開してから少なくとも 5~10 分待ちます。正しい名前空間 (AWS/Lambda) とディメンション (CapacityProviderNameFunctionName、または InstanceType) を表示していることを確認します。

CloudWatch ログが見つからない

問題: 関数は正常に実行されますが、CloudWatch Logs でログを見つけることができない。

原因: Lambda マネージドインスタンスは VPC で実行され、CloudWatch Logs にログを送信するためにネットワーク接続が必要です。適切な VPC 接続設定がないと、関数は CloudWatch Logs サービスエンドポイントに到達できません。

解決策:

関数が CloudWatch Logs にログを送信できるように VPC 接続を設定します。次の 3 つの選択肢があります。

オプション 1: CloudWatch Logs の VPC エンドポイント (本番環境に推奨)

  1. Amazon VPC コンソールを console.aws.amazon.com/vpc/) で開きます。

  2. ナビゲーションペインで、[エンドポイント] を選択します。

  3. [エンドポイントの作成] を選択します。

  4. [Service category] (サービスカテゴリ) で、[AWS services] (のサービス) を選択します。

  5. [サービス名] には、com.amazonaws.region.logs を選択します (region を AWS リージョンに置き換えます)。

  6. [VPC] には、キャパシティープロバイダーが使用する VPC を選択します。

  7. [サブネット] には、エンドポイントネットワークインターフェイスの作成先となるサブネットを選択します。可用性を高めるには、複数のアベイラビリティーゾーンにサブネットを選択します。

  8. [セキュリティグループ] には、関数のセキュリティグループからのインバウンド HTTPS トラフィック (ポート 443) を許可するセキュリティグループを選択します。

  9. エンドポイントで [プライベート DNS] を有効にします。

  10. エンドポイントの作成 を選択します。

オプション 2: インターネットゲートウェイを備えたパブリックサブネット

キャパシティープロバイダーがパブリックサブネットを使用している場合は、以下を確認してください。

  1. インターネットゲートウェイが VPC にアタッチされている

  2. ルートテーブルが 0.0.0.0/0 トラフィックをインターネットゲートウェイにルーティングしている

  3. セキュリティグループがポート 443 でアウトバウンド HTTPS トラフィックを許可している

オプション 3: NAT ゲートウェイを使用するプライベートサブネット

キャパシティープロバイダーがプライベートサブネットを使用している場合は、以下を確認してください。

  1. NAT ゲートウェイがパブリックサブネット内に存在している

  2. プライベートサブネットのルートテーブルが 0.0.0.0/0 トラフィックを NAT ゲートウェイにルーティングしている

  3. パブリックサブネットのルートテーブルが 0.0.0.0/0 トラフィックをインターネットゲートウェイにルーティングしている

  4. セキュリティグループがポート 443 でアウトバウンド HTTPS トラフィックを許可している

VPC 接続オプションの詳細については、「VPC connectivity for Lambda Managed Instances」を参照してください。

同時リクエストからのログの相関付けが困難

問題: さまざまなリクエストからのログがインターリーブされるため、個々のリクエストを追跡するのが困難である。

原因: ログインターリーブは、複数同時実行システムで想定される標準的な動作です。

解決策:

  • JSON 形式で構造化ログ記録を使用する: すべてのログステートメントにリクエスト ID を含める

  • Java: ThreadContext で Log4j を使用してリクエスト ID を自動的に含める

  • Node.js: JSON フォーマットで console.log() を使用して、InvokeStore.getRequestId() を含める

  • Python: JSON フォーマットで標準ログ記録モジュールを使用して、context.request_id を含める

詳細なガイダンスについては、ランタイム固有のドキュメントページを参照してください。

追加のヘルプの取得

これらのソリューションを試した後も問題が続く場合:

  1. CloudWatch メトリクスを確認する: キャパシティープロバイダーと実行環境メトリクスをチェックして、リソースの制約やスケーリングの問題を特定します。

  2. AWS CloudTrail ログを確認する: API コールとエラーに関する詳細情報については、CloudTrail ログを確認します。

  3. AWS サポートに問い合わせる: 問題を解決できない場合は、キャパシティープロバイダーの設定、関数の設定、発生した特定のエラーメッセージの詳細について AWS サポートにお問い合わせください。

次のステップ