🌎

PSH (Personalized Service Health) を使った障害復旧パイプライン

2024/05/05に公開

はじめに

システムの信頼性を高めるために、障害発生時の対応はきちんと考えておきたいトピックの一つです。例えば、以下のような場合があると思います。

  • ディザスターリカバリジョブを起動したい
  • AP で参照している DB を別リージョンのものに切り替えたい
  • システムが受けた影響範囲・システムの稼働状況をエンドユーザに告知したい

上記のようなケースにおいて当然手動オペレーションを行うことも可能ですが、できることであれば障害発生時の対応は自動化し、属人化を避けながら人為的ミスなく迅速に遂行できるようにしておきたいです。ということで今回は Personalized Service Health を利用して、例としてディザスタリカバリジョブを自動起動するパイプラインを作成してみたいと思います。

シナリオ

今回シナリオとしては Google Cloud 公式で提供されているコレオグラフィーの例をもとに考えてみたいと思います。
https://cloud.google.com/architecture/transactional-workflows-microservices-architecture-google-cloud#architecture_overview

全体的なアーキテクチャとしては以下の図の通りで、 Order サービスがクライアントから購買リクエストを受け取り、それを Datastore にイベントとして永続化した上で(購買の状態を pending とする)、Customer サービスに Messaging を用いて非同期的に連携します。そして Customer サービスにおいても同様に永続化しながら、処理が終了した時点で非同期的に Order サービスに連携し、最終結果を Order サービス側の Datastore に書き込むことで(購買の状態を accepted とする)、サービス間の整合性を保つというものです。(詳しくは Transactional workflow をご覧ください。)

上記にて購買リクエストを Datastore にイベントとして永続化すると記述しましたが、本アーキテクチャでは transactional outbox を用いることで、データの更新とメッセージのパブリッシュをアトミックに実行できるようにしています。

そしてようやく本題ですが、今回は上記アーキテクチャにてメッセージング基盤として利用されている Pub/Sub に障害が発生することを考えます。Pub/Sub に障害が生じると Order サービスの Datastore に購買情報が永続化されクライアントにレスポンスが返ります。(このとき Pub/Sub にパブリッシュはできないので published は False として書き込まれます)

ここで実践的に以下のようなディザスタリカバリジョブを考えてみます。Pub/Sub障害によりパブリッシュできていないイベントを拾って再生してあげるような処理ですね。

上記ジョブを Pub/Sub の障害が close したことを契機にキックするようにしたいので、全体としては以下のような流れで考えてみます。PSH 用の Polling AP は書きたくなかったので、Cloud Logging, Alert Policy を用いて障害を検知するように、また、拡張性を考慮して Cloud Run Jobs は Cloud Workflows で起動するようにしました。(ジョブ間に順序性が必要になったり、エラーハンドリングが必要になったりした場合に、Workflow Engine であれば対応できます)

実装例

技術的にはなにもしていないので特に解説しませんが、以下ログフィルターにてプロジェクトに影響ある Pub/Sub の障害が Close したタイミングで Job が起動するようにしています。

(jsonPayload.relevance = "RELATED" OR jsonPayload.relevance = "IMPACTED" OR jsonPayload.relevance = "PARTIALLY_RELATED" OR jsonPayload.relevance = "UNKNOWN") AND jsonPayload.State = "CLOSED" AND jsonPayload.impactedProducts =~ "Google Cloud Pub/Sub"

https://github.com/ppluuums-jp/psh-recovery-pipeline

まとめ

以下ドキュメントにもある通り、Google Cloud は極めて信頼性の高いマネージドサービスを提供していますが、様々な要因 (自然災害やケーブルの切断など) によってインフラ障害が起こりえます。(今回取り扱ったPub/Subのようなグローバルサービスでさえも障害が起こりえます)

While Google Cloud provides extremely reliable service, disasters will ? strike - natural disasters, fiber cuts, and complex unpredictable infrastructure failures - and these disasters cause outages.

なので、各障害発生ポイントにおいて復旧シナリオを考えておくことは、信頼性の高いシステムを構築する上では必須になってきますし、それを考える上で関心のあるプロジェクト・サービスに絞って障害をキャプチャできる Personalized Service Health は積極的に活用していきたいと感じました。
https://cloud.google.com/architecture/disaster-recovery

Discussion