今回も、Professional Cloud Data Engineer認定取得するために、私が勉強した内容をアウトプットしていきます。
今回は、Pub/Subの1回限りの配信、サブスクリプションの再試行ポリシー、Pub/Subのリクエストの再試行について説明します!
ぜひ、最後までご覧いただけると嬉しいです!
Pub/Subの1回限りの配信
Pub/Sub は、メッセージの重複処理を追跡・防止するための「1回限りの配信」機能を提供しています。この機能を有効にすることで、サブスクライバーはメッセージが 1回だけ処理されることを保証しやすくなります。
1回限りの配信が提供するセマンティクス
この機能を有効にすると、Pub/Sub は以下のセマンティクスを提供します。
- 確認応答の追跡:サブスクライバーは、メッセージの確認応答(ack)が正常に完了したかどうかを確実に確認できます。
- 確認応答後の再配信防止:メッセージの確認応答が正常に完了すると、そのメッセージは再配信されません。
- 処理中の再配信防止:メッセージが未処理(確認応答期限が切れるか、確認応答が行われるまで)の間は、再配信は発生しません。
- 最新の確認応答 ID のみ有効:複数の配信が並行して行われた場合(確認応答期限の経過などによる)、最新の確認応答 ID を持つリクエストのみが成功し、それ以前の ID でのリクエストは失敗します。
1回限りの処理を実現するためのサブスクライバーの役割
Pub/Sub が1回限りの「配信」セマンティクスを提供しても、1回限りの「処理」を実現するためには、サブスクライバー側で以下のガイドラインに従う必要があります。
- 期限内の確認応答:メッセージを受信したら、確認応答期限内に処理を完了し、確認応答を返す必要があります。
- 処理進行状況の保持:メッセージの処理状況に関する情報(例:データベースへの書き込みが完了したかなど)を、確認応答が Pub/Sub に正常に伝わるまで保持します。
- 重複作業の防止:万が一、確認応答が失敗してメッセージが再配信された場合に備え、保持している処理の進行状況に関する情報を使用して、重複した作業(例:データベースへの二重書き込み)を防ぎます。
主な制限事項と考慮点
- サポートされるサブスクリプションタイプ
- pull サブスクリプションと StreamingPull API を使用するサブスクリプションでのみサポートされます。
- push サブスクリプションとエクスポート サブスクリプション(BigQuery, Cloud Storage など)ではサポートされていません。
- リージョンに関する考慮事項
- Pub/Sub は、Pub/Sub が定義する一意のメッセージ ID に基づき、クラウドリージョン内で 1 回限りの配信をサポートします。
- クライアントライブラリ
- 最適なパフォーマンスを得るために、最新バージョンのクライアントライブラリの使用が推奨されています。
- 再配信と重複の違い
- 再配信:クライアントによる否定確認応答(nack)や、確認応答期限の超過によって発生する「意図された」動作です。
- 重複:確認応答が成功した後や、確認応答期限が切れる前にメッセージが再送信される「意図しない」動作を指します。1 回限りの配信機能は、この「重複」を防ぐことを目的としています。
Pub/Subの1回限りの配信のまとめ
Pub/Subの「1回限りの配信」機能は、メッセージの重複を防ぎ、信頼性の高いデータ処理を実現するための重要な仕組みです。この機能により、確認応答後の再配信や処理中の重複配信が防止されます。ただし、完全な「1回限りの処理」を達成するためには、サブスクライバー側の適切な実装が不可欠です。主に pull 型サブスクリプションで利用でき、再配信と重複の違いを理解することも重要です。これにより、Pub/Sub のメッセージ処理をより堅牢かつ効率的に運用できます。
サブスクリプションの再試行ポリシー
Pub/Subは、メッセージの配信に失敗した際の動作を柔軟に制御するため、「サブスクリプションの再試行ポリシー」機能を提供しています。これにより、サブスクライバー(メッセージ受信側)が一時的なエラーでメッセージを処理できない場合でも、システムの堅牢性を高めることができます。
メッセージ再試行の仕組み
サブスクライバーがメッセージの確認応答(ack)を返さない、または否定確認応答(nack)を返した場合、Pub/Sub はそのメッセージを再配信する必要があります。
再試行ポリシーを設定しない場合、Pub/Sub はメッセージをすぐに再配信しようとします。しかし、サブスクライバーが一時的な高負荷や外部リソースの問題で停止している場合、即時の再試行はサブスクライバーをさらに圧迫する可能性があります。
指数バックオフによる制御
サブスクリプションの再試行ポリシーは、この再配信のタイミングを指数バックオフアルゴリズムに基づいて制御します。これは、再試行の間隔を徐々に長くしていく仕組みです。
- 初期の再試行:最初の失敗後、設定された最小バックオフ期間(例:10 秒)待機してから再配信されます。
- 続く再試行:再度失敗すると、待機時間は指数関数的に増加します(例: 20 秒、40 秒、80 秒…)。
- 上限:この待機時間は、設定された最大バックオフ期間(例:600 秒)に達するまで増加し続けます。上限に達した後は、最大バックオフ期間の間隔で再試行が継続されます。
なぜ再試行ポリシーが重要か?
- サブスクライバーの保護:一時的な障害(データベース接続の瞬断、ネットワークの不安定など)が発生した場合、指数バックオフによってサブスクライバーが回復するための「時間」が確保され、即時の再試行による過負荷を防ぎます。
- 柔軟なエラー処理:すぐに再試行すべき軽いエラーと、時間を置いて再試行すべき重いエラーを区別して対応できます。
永続的なエラーへの対応:デッドレター トピック
再試行ポリシーは一時的なエラーには有効ですが、メッセージ自体に問題があり、何度試行しても処理できない「ポイズンピル」メッセージには対応できません。
このような永続的に失敗するメッセージを処理するため、再試行ポリシーはデッドレター トピック (DLT) と組み合わせて使用されることが一般的です。
設定された最大配信試行回数を超えてもメッセージの処理が成功しない場合、そのメッセージは自動的に指定されたデッドレター トピックに転送されます。これにより、問題のあるメッセージがメインのサブスクリプションに滞留し、他の正常なメッセージの処理を妨げるのを防ぐことができます。
サブスクリプションの再試行ポリシーのまとめ
Pub/Subの再試行ポリシーは、メッセージ配信失敗時の挙動を制御し、システム全体の安定性を高める重要な仕組みです。指数バックオフにより、再試行間隔を段階的に延ばすことで、サブスクライバーへの過負荷を防ぎます。また、一時的な障害と永続的な障害を区別し、適切な再試行戦略を実現します。さらに、処理できないメッセージはデッドレタートピックへ転送することで、システムの健全性を維持できます。これにより、Pub/Subのメッセージ処理をより堅牢に運用できます。
Pub/Subのリクエストの再試行
Pub/Sub でメッセージをトピックに送信(パブリッシュ)する際、一時的なネットワークの問題やクライアント側のリソース不足により、リクエストが失敗することがあります。Pub/Sub のクライアントライブラリは、このような事態に対応するため、堅牢な「リクエスト再試行」の仕組みを内蔵しています。
パブリッシュ障害の主な原因
メッセージのパブリッシュが失敗する主な原因は、パブリッシャー(送信側)のクライアント側にあることが多いです。
- クライアントサービス(例:アプリケーション)の CPU 不足
- スレッドの状態不良
- ネットワークの輻輳(ふくそう)
クライアント ライブラリによる自動再試行
一時的なエラーが発生した場合、Pub/Sub のクライアントライブラリは自動的にパブリッシュリクエストを再試行します。この動作は、主に以下の設定によって制御されます。
- 初期リクエスト タイムアウト:最初のパブリッシュリクエストが完了するのを待つ時間。
- 再試行遅延:リクエストがタイムアウトした後、次の再試行までに待機する時間。
- 合計タイムアウト:クライアントライブラリが再試行を停止するまでの総合的な時間。
クライアントライブラリは多くの場合、指数バックオフを採用しています。これは、再試行を繰り返すたびに、再試行の遅延時間(待機時間)を徐々に長くしていく方法です。これにより、一時的な障害からシステムが回復する時間を確保しつつ、Pub/Sub サービスに過度な負荷をかけるのを防ぎます。
注意点:再試行による重複の可能性
リクエストの再試行機能は信頼性を高めますが、稀にメッセージの重複を引き起こす可能性があります。
最も一般的なシナリオは、「パブリッシュ操作は Pub/Sub 側で成功したものの、その成功レスポンスがパブリッシャークライアントに届かなかった」場合です。
この場合、クライアントはリクエストが失敗したと誤解し、同じメッセージを再試行します。結果として、Pub/Sub は 2 つのメッセージ(内容は同じだがメッセージ ID は異なる)を受け取ることになります。
永続的なエラーへの対応
自動再試行は一時的なエラーを対象としています。エラーが継続的に発生する場合、クライアントライブラリは「合計タイムアウト」で設定された時間を超えると再試行を諦めます。
エラーが永続する場合、Pub/Sub サービスに過負荷をかけないよう、パブリッシュプロセスの外部で(例:アプリケーションコード側で)適切なエラーハンドリングを実装することが推奨されます。
Pub/Subのリクエストの再試行のまとめ
Pub/Subのリクエスト再試行機能は、一時的なネットワーク障害やクライアント側の問題に対して、メッセージ配信の信頼性を高める重要な仕組みです。クライアントライブラリは指数バックオフを用いて自動的に再試行を行い、システムへの過負荷を防ぎながら安定した送信を実現します。ただし、成功レスポンスが届かない場合などにメッセージが重複する可能性がある点には注意が必要です。永続的なエラーが発生する場合は、アプリケーション側での適切なエラーハンドリングが求められます。これにより、Pub/Subの信頼性と堅牢性を最大限に活用できます。
まとめ
今回は、下記3点について説明しました。
- Pub/Subの1 回限りの配信
- サブスクリプションの再試行ポリシー
- Pub/Subのリクエストの再試行
Cloud Pub/Subでは、信頼性の高いメッセージ配信を実現するために、1回限りの配信、再試行ポリシー、リクエスト再試行といった複数の仕組みが用意されています。1回限りの配信により、重複処理を防ぎつつ、堅牢なデータ処理が可能になります。再試行ポリシーはサブスクライバー側の一時的な障害に備え、指数バックオフで配信を調整します。また、リクエスト再試行はパブリッシュ時のネットワーク問題に対応し、安定した送信を支えます。これらを組み合わせることで、Pub/Subをより安心して運用できるメッセージ基盤として活用できます。
これからも、Macのシステムエンジニアとして、日々、習得した知識や経験を発信していきますので、是非、ブックマーク登録してくれると嬉しいです!
それでは、次回のブログで!
