最近の打ち合わせで、アプリで SQS の利用範囲を広げることになったので、インフラ側でも監視範囲を広げてほしいという要請がありました。
直前になって焦らないように、監視すべきメトリックスとその意味を事前に整理しておこうと思います。
監視必須のSQS関連メトリックス
各種解説や運用事例を調べてみると、以下のメトリックスは最低限監視対象に含めるのがよいとされているようです。
- ApproximateAgeOfOldestMessage
- ApproximateNumberOfMessagesVisible
- ApproximateNumberOfMessagesNotVisible
- NumberOfMessagesReceived
- NumberOfMessagesDeleted
- ApproximateNumberOfMessagesVisible(DLQ側)
以下、それぞれの意味を整理してみます。
ApproximateAgeOfOldestMessage
このメトリックスは、キュー内にある「一番古いメッセージが何秒待っているか」を示します。
多くの解説で、これは特に重要な指標とされています。 理由は、遅延の直接的な指標になるためです。
このメトリックスから読み取れそうなこと
- 処理が詰まっている
- コンシューマが停止している
- 処理性能が足りていない
といった状況が推測できそうです。
アラート例
- 300秒超 → Warning
- 900秒超 → Critical
具体的な閾値はシステム特性によると思いますが、 まずはこの値を中心に監視設計を組み立てるのが良さそうです。
ApproximateNumberOfMessagesVisible
現在キューに溜まっている未処理メッセージ数を示します。
このメトリックスから分かること
- バックログが増えているか
- トラフィックのスパイクが発生しているか
ただし、メッセージ数が増えているだけでは異常とは言えないケースもあります。
そのため、Age とあわせて見ることが基本になりそうです。
ApproximateNumberOfMessagesNotVisible
現在「処理中」とみなされているメッセージ数を示します。 正確には、Visibility Timeout 中のメッセージ数です。 (Visibility Timeout については後述)
このメトリックスから読み取れそうなこと
- 同時処理件数の目安
- 処理時間が長すぎないか
もしこの値が継続的に増え続ける場合は、
- 処理が遅い
- Visibility Timeout が長すぎる
- ワーカーがハングしている
といった可能性も考えられそうです。
NumberOfMessagesReceived
コンシューマがメッセージを受信した回数です。
主な用途
- 処理量の傾向把握
- 急にゼロになった場合の異常検知
ただし、これは単体でアラートを上げるというよりも、 ダッシュボードでの傾向監視向きの指標と考えたほうがよさそうです。
NumberOfMessagesDeleted
正常に処理が完了し、削除された件数を示します。
ここで見たいポイント
- Received は増えている
- しかし Deleted が増えていない
このような状態は、処理失敗やリトライが発生している可能性を示しているかもしれません。
地味ですが、意外と重要なチェックポイントになりそうです。
ApproximateNumberOfMessagesVisible(DLQ側)
DLQ(Dead Letter Queue)に溜まっているメッセージ数です。 (DLQ については後述)
DLQにメッセージが入るということは、
通常処理で複数回リトライしても処理できなかった
ということを意味します。
多くの事例では、DLQへの流入は即対応レベルとされているようです。 少なくともアラート対象には含めておいたほうがよさそうです。
運用監視のコツ
いろいろ調べていく中で見えてきたのは、
件数よりも「遅延(Age)」を重視する
という考え方です。
メッセージ数が増えていても、処理が追いついていれば問題は小さいかもしれません。 一方で、Age が伸び続けている場合は明確な処理遅延と考えられます。
SQS監視の本質は、「滞留の検知」にあるのではないかと感じました。
補足1: Visibility Timeoutとは何か?
SQSでは、コンシューマが ReceiveMessage を呼ぶと、そのメッセージは一定時間、他のコンシューマから見えなくなります。
この時間が Visibility Timeout です。
言い換えると、
メッセージは Receive された瞬間から、 Delete されるか Timeout が切れるまで NotVisible 状態になります。
なぜこの仕組みがあるのか?
SQSは at-least-once delivery(少なくとも1回は届ける) モデルです。
もしコンシューマが処理中にクラッシュした場合、
- メッセージを受信した
- しかし Delete する前に落ちた
という状況が起こり得ます。
この場合、メッセージは再び処理可能な状態に戻る必要があります。
そのため、
- Receiveしたら一時的に非表示にする
- 正常処理後にDeleteされたら完全削除
- Deleteされなければ、Timeout後に再表示
という仕組みになっています。
補足2: DLQ(Dead Letter Queue)とは
DLQとは、通常処理で一定回数リトライしても成功しなかったメッセージを退避させるためのキューです。
例えば、
- データ形式が壊れている
- 必須フィールドが欠落している
- 永続的なアプリケーションバグ
といったケースが考えられます。
DLQは「最後の保険」と言える存在です。
DLQにメッセージが入っている場合は、 アプリケーション側の修正が必要な可能性が高いと考えられます。
まとめ
今回整理してみた結果、SQS監視の基本は次の3点に集約できそうです。
- Age を中心に監視設計を組み立てる
- Visible / NotVisible で滞留状況を把握する
- DLQは必ず監視対象に含める
SQSは単純なキューに見えますが、 実際には非同期システム全体の健全性を映すコンポーネントです。
今回の整理をベースに、実際の環境に合わせてアラート設計を組み立てていこうと思います。