背景
GCPのPub/SubをComposerで処理している際、以下の問題に直面しました。
- Pub/Subのバックログ(未処理メッセージ)が増えてしまう
- Composerの処理はエラーなく完了しているのに、Pub/Subのメッセージが減らない
- Oldest Unacknowledged Messageの経過時間がどんどん増えてしまう
Googleサポートからの回答によると、Pullリクエストの頻度が不足しているため、バックログが解消されない とのことでした。
課題の整理
現在の設定
- Composerの実行頻度: 30分に1回
- Pub/SubのPull方法: 単行Pull(Pull API)
- max_messages: 100
- ACKデッドライン: 10分
- 1回のComposer処理時間: 約10分
- 1回のPullで取得するメッセージ数: 5個程度(時々2個しか取得しないことも)
問題点
- 1回のPullで取得するメッセージ数が少なく、Pub/Subにメッセージが溜まる
- メッセージが取りきれずに次回のComposer実行まで待たされる(結果、レイテンシが発生)
- Pullリクエストの頻度が不足している
解決策
- 単行Pullを並列処理する(スレッドを増やす)
- Pub/SubのPull APIは単一リクエストでは取得できるメッセージ数にばらつきがあるため、並列で複数のPullリクエストを実行することでメッセージ取得量を増やす
並列Pullのメリット
- 1回のComposer実行でより多くのメッセージを取得できる
- Pullリクエストを複数並列実行することで、取得漏れを防ぐ
- Pub/Subのバックログ削減につながる
注意点
Composerのリソース消費に注意
- 並列PullによってCPU・メモリ使用量が増加する可能性があるため、Composerのリソース状況も確認
ACK処理を適切に行う
- ACKしないとメッセージが再送されるため、Pull後に確実にACKを実行
まとめ
- Pull APIを並列実行し、一度に多くのメッセージを取得する
- ACK処理を適切に行い、メッセージの再送を防ぐ