Amazon SQS の可視性タイムアウト - Amazon Simple Queue Service

Amazon SQS の可視性タイムアウト

Amazon SQS キューからメッセージを受信すると、メッセージはキューに残りますが、他のコンシューマーからは一時的に見えなくなります。この可視性は可視性タイムアウトによって制御されます。これにより、作業している間、他のコンシューマーは同じメッセージを処理することができません。Amazon SQS では、処理後にメッセージを削除するための 2 つのオプションを提供しています。

  • 手動削除DeleteMessage アクションを使用してメッセージを明示的に削除します。

  • 自動削除 – 特定の AWS SDK でサポートされ、処理が成功するとメッセージが自動的に削除され、ワークフローが簡素化されます。

可視性タイムアウト中のリクエストの処理方法を示すタイムライングラフ

可視性タイムアウトのユースケース

長時間実行されるタスクを管理する – 可視性タイムアウトを使用して、処理時間が長いタスクを処理します。処理時間が長くなるメッセージに、適切な可視性タイムアウトを設定します。これにより、他のコンシューマーが処理中に同じメッセージを取り上げないようにして作業の重複を防ぎ、システム効率を維持します。

再試行メカニズムを実装する – 初期タイムアウト内に完了しなかったタスクの可視性タイムアウトをプログラムで延長します。タスクが最初の可視性タイムアウト内に完了しなかった場合は、タイムアウトをプログラムで延長できます。これにより、システムは他のコンシューマーに表示されることなくメッセージ処理を再試行できるため、耐障害性と信頼性が向上します。デッドレターキュー (DLQ) と組み合わせて、永続的な障害を管理します。

分散システムを調整する – SQS 可視性タイムアウトを使用して、分散システム全体のタスクを調整します。さまざまなコンポーネントの予想される処理時間と一致する可視性タイムアウトを設定します。これにより、一貫性を維持し、複雑な分散アーキテクチャでの競合状態を防ぐことができます。

リソース使用率を最適化する – SQS 可視性タイムアウトを調整して、アプリケーションのリソース使用率を最適化します。適切なタイムアウトを設定することで、リソースを不必要に結び付けることなく、メッセージが効率的に処理されるようにできます。これにより、システム全体のパフォーマンスとコスト効率が向上します。

可視性タイムアウトの設定と調整

可視性タイムアウトは、メッセージが配信されるとすぐに開始されます。この期間中は、メッセージを処理および削除する必要があります。タイムアウトが期限切れになるメッセージを削除しなかった場合、メッセージはキューに再表示されて、別のコンシューマーが取得できるようになります。キューのデフォルトの可視性タイムアウトは 30 秒ですが、アプリケーションがメッセージを処理および削除するために必要な時間に合わせて調整できます。また、キュー全体の設定を変更することなく、個別のメッセージに特定の可視性タイムアウトを設定することもできます。ChangeMessageVisibility アクションを使用して、必要に応じてタイムアウトをプログラムで延長または短縮します。

処理中メッセージとクォータ

Amazon SQS の処理中メッセージとは、コンシューマーが受信したものの、まだ削除していないメッセージです。標準キューの場合、キュートラフィックとメッセージバックログに応じて、処理中メッセージ数の制限は最大約 120,000 となっています。この制限に達すると、Amazon SQS は OverLimit エラーを返し、一部の処理中メッセージを削除しない限り、追加のメッセージを受信できないことを示します。FIFO キューの場合、制限はアクティブなメッセージグループによって異なります。

  • ショートポーリングを使用する場合 – ショートポーリングの使用中にこの制限に達すると、Amazon SQS は OverLimit エラーを返し、一部の処理中メッセージを削除しない限り、追加のメッセージを受信できないことを示します。

  • ロングポーリングを使用する場合 – ロングポーリングを使用している場合、処理中メッセージ数が制限に達しても Amazon SQS はエラーを返しません。代わりに、インフライトメッセージ数が制限を下回るまで、新しいメッセージを返しません。

処理中メッセージを効果的に管理する方法:

  1. プロンプト削除 – 処理後にメッセージ (手動または自動で) を削除し、処理中の数を減らします。

  2. CloudWatch でモニタリングする – 制限に達しないように、処理中の数が多い場合のアラームを設定します。

  3. 負荷を分散する – 大量のメッセージを処理している場合は、追加のキューまたはコンシューマーを使用して負荷を分散し、ボトルネックを回避します。

  4. クォータの引き上げをリクエストする – より高い制限が必要な場合は、AWS サポートにリクエストを送信します。

標準キューと FIFO キューの可視性タイムアウトについて

標準キューでも FIFO (First-In-First-Out) キューでも、可視性タイムアウトを設定することで、複数のコンシューマーが同じメッセージを同時に処理しないようにできます。ただし、Amazon SQS の配信モデルでは 1 回以上の配信を行うため、可視性タイムアウト期間中にメッセージが複数回配信されないという絶対的な保証はありません。

  • 標準キュー – 標準キューで可視性タイムアウトを設定すると、複数のコンシューマーが同じメッセージを同時に処理しないようにします。ただし、1 回以上の配信を行う配信モデルのため、Amazon SQS では、可視性タイムアウト期間内にメッセージが複数回配信されないという絶対的な保証はありません。

  • FIFO キュー – FIFO キューの場合、同じメッセージグループ ID を持つメッセージは厳密な順序で処理されます。メッセージグループ ID を持つメッセージが処理中の場合、そのグループ内の後続のメッセージは、処理中のメッセージが削除されるか、可視性タイムアウトの有効期限が切れるまで使用できなくなります。ただし、これはグループを無期限に「ロック」するわけではありません。各メッセージは順番に処理され、各メッセージが削除されるか再び表示される場合にのみ、そのグループ内の次のメッセージがコンシューマーに対して利用可能になります。このアプローチにより、グループがメッセージの配信を不必要にロックすることなく、グループ内での順序通りの処理が保証されます。

障害の処理

アプリケーションエラー、クラッシュ、接続の問題などで可視性タイムアウトが期限切れになる前にメッセージを処理し、削除しなかった場合、メッセージはキューに再表示されます。そのため、同じコンシューマーまたは別のコンシューマーがメッセージを取得して、別の処理を実行できるようになります。これにより、最初の処理が失敗してもメッセージは失われません。ただし、可視性タイムアウトの設定が高すぎると、未処理のメッセージの再表示が遅延し、再試行が遅れる可能性があります。タイムリーなメッセージ処理には、処理の予想時間に基づいて適切な可視性タイムアウトを設定することが重要です。

可視性タイムアウトの変更と終了

ChangeMessageVisibility アクションを使用して、可視性タイムアウトを変更または終了できます。

  • タイムアウトの変更ChangeMessageVisibility を使用して可視性タイムアウトを動的に調整します。これにより、処理ニーズに合わせてタイムアウト期間を延長または短縮できます。

  • タイムアウトの終了 - 受信したメッセージを処理しないことに決めた場合は、ChangeMessageVisibility アクションを通じて VisibilityTimeout を 0 秒に設定することで、可視性タイムアウトを終了します。これに伴って、他のコンシューマーがメッセージをすぐに処理できるようになります。

ベストプラクティス

タイムアウトの設定、調整、延長、デッドレターキュー (DLQ) を使用した未処理メッセージへの対応など、Amazon SQS の可視性タイムアウトを管理するには、以下のベストプラクティスを使用します。

  • タイムアウトの設定と調整。まず、アプリケーションがメッセージを処理して削除するのに通常必要な最大時間に合わせて可視性タイムアウトを設定します。正確な処理時間について不明な場合は、短いタイムアウト (2 分など) で開始し、必要に応じて延長します。ハートビートメカニズムを実装して可視性タイムアウトを定期的に延長し、処理が完了するまでメッセージを非表示にします。これにより、未処理メッセージの再処理の遅れを最小限に抑えるとともに、再表示が早すぎないようにします。

  • タイムアウトの延長と 12 時間の制限の処理。処理時間が変わるか、最初に設定したタイムアウトを超えそうな場合は、メッセージの処理時に ChangeMessageVisibility アクションを使用して可視性タイムアウトを延長します。可視性タイムアウトの上限は、メッセージを最初に受信してから 12 時間であることに注意してください。タイムアウトを延長しても、この 12 時間の制限はリセットされません。この制限を超える時間が処理にかかる場合は、AWS Step Functions を使用するか、タスクを小さなステップに分割することを検討します。

  • 未処理メッセージへの対応。複数の処理試行に失敗したメッセージを管理するには、デッドレターキュー (DLQ) を設定します。これにより、複数回の再試行後に処理できないメッセージを、さらなる分析や対応のために別個にキャプチャし、メインキュー内をメッセージが繰り返し循環しないようにすることができます。