web-dev-qa-db-ja.com

AWS、Lambdaが失敗すると、LambdaへのSQSトリガーが自動的に無効になる

SQSキューによってトリガーされるLambdaがいくつかあります。 LambdaはDynamoDBテーブルへの集中的な挿入を行います。 DynamoDBテーブルには、自動スケーリング書き込み容量があります。

負荷がピークに達すると、多数のメッセージがLambdaに届き、ProvisionedThroughputExceededExceptionで失敗し始めます。 DynamoDBのスケールアップには数分かかります。

Lambdaが失敗すると、メッセージはSQSに戻り、可視性のタイムアウト後に再び処理されると予想されます。後のDynamoDBはスケールアップされ、増大した書き込みを処理できるはずなので、これは正しいように見えます。

しかし、奇妙なことがわかります。 Lambdaの実行エラーの数が増えると、SQSトリガーは自動的に無効になります。 Lambdaは実行を停止し、メッセージはキューに蓄積されます。

DynamoDBはまだスケールアップされていないため、トリガーを手動で有効にするとさらに多くのエラーが発生しますが、キューから処理するメッセージの数は劇的に増加しました。

DynamoDBの書き込み容量を手動で増やすだけが役立ちます。

SQSトリガーが無効になるのはなぜですか?この動作は文書化されていません。

トリガーが無効になるのを防ぐ方法は?

一般に、ラムダによるSQSからのメッセージのポーリング速度を制限するために「バックプレッシャー」を実行するための推奨される方法は何ですか?

3
gelin

AWSサポートによると、Lambda実行ロールの権限が不十分なため、トリガーを無効にできるとのことです。

私の質問:

Lambdaトリガーを自動的に無効にできる条件はどこに文書化されていますか?または、トリガーが無効にされた理由(ある種のLambdaサービスログ)はどこで確認できますか?

AWSサポートの回答:

現在、Lambdaトリガーが自動的に無効になる考えられる理由について言及しているそのような公開ドキュメントはありません。ただし、前述したように、SQS Lambdaトリガーが無効になる最も可能性の高い理由は、Lambda関数実行ロールに次の必要なアクセス許可が1つ以上含まれていないことです。

  • sqs:ChangeMes​​sageVisibility
  • sqs:DeleteMessage
  • sqs:GetQueueAttribute
  • sqs:ReceiveMessage
  • 関連するKMSキーへのアクセス
  • 該当するすべてのクロスアカウント権限
  • また、lambda関数がVPCにある場合、Lambda関数には、ENIを一覧表示、作成、削除するためのすべての権限が必要です

また、トリガーが無効になる理由は、Lambda関数ログには記載されません。そのため、Lambda関数実行ロールに必要なすべての権限があることを確認してください。 Lambda関数実行ロールに必要なすべての権限がある場合、SQSトリガーは自動的に無効になりません。

私の場合、VPC権限を完全に逃しました。つまり、AWSLambdaVPCAccessExecutionRoleポリシーをLambda実行ロールにアタッチしませんでした。 (ラムダがこのポリシーなしでどのように機能したかはわかりません)。役割を修正してから5日が経過しましたが、無効化されたトリガーはありません。それで、うまくいきます。


DynamoDBと「バックプレッシャー」については、 MLuのアイデア が正しいです。

各SQSメッセージごとにDynamoDBへの書き込みが1つしかない場合、書き込みが失敗した場合、Lambdaで失敗するだけです。メッセージはSQSにとどまり、可視性のタイムアウト後に再びLambdaによって受信されます。この場合、メッセージを1つずつ処理するには、バッチサイズ1を使用することをお勧めします。

SQSメッセージごとに複数のDynamoDBへの書き込みがある場合(書き込みの乗算)、LambdaでProvisionedThroughputExceededExceptionをキャッチし、失敗した書き込みを遅延して別のキューに入れて、後で別のLambdaで繰り返します。元のメッセージではなく、すべての書き込みを繰り返すことが重要です。

データフローは次のようになります。

dataflow with delay queue

書き込みの遅延繰り返しは、実際に遅延して繰り返すことができる場合にのみ許容されます。それらはべき等である必要があり、リアルタイムデータを含むべきではありません。それ以外の場合は、例外を黙って無視し、Lambdaの失敗を回避して、SQSからメッセージを削除して忘れることをお勧めします。

2
gelin

ラムダが機能しなくなった理由がわかりません。 Lambdaサービスが失敗し続けているため、一時的に一時停止しているようです。わからない。

いくつかの回避策を試すことができます。

  • DynamoDBオンデマンドキャパシティを使用-AWSは即座にスケーリングすると述べています。
  • または、プロビジョニングされた容量を使用してProvisioned Throughput Exceptionを取得した場合、実際にはLambdaの実行を中止せずに、メッセージをSQSキューに再挿入して正常に終了します。このようにして、Lambdaサービスは障害を検出せず、SQSメッセージも失われません。

これらの線に沿った何かが役立つかもしれません:)

3
MLu