KAKEHASHI Tech Blog

カケハシのEngineer Teamによるブログです。

安心してメンテナンスを行うためのメンテナンスモードの実現において考えたこと

こんにちは、カケハシでAI在庫管理のプロダクトのバックエンドエンジニアをしている松本です。
AI在庫管理でメンテナンスを行うための機能としてメンテナンスモードを開発しました。本エントリではメンテナンスモードを実現する際に考えたこと、気をつけたことを書きたいと思います。このメンテナンスモードは他のメンバーとも協力して開発していますが、代表して本エントリを書いています。

また、メンテナンスモードの実現には、当然Webアプリの画面側の対応も必要ですが、今回はバックエンド側の対応を中心に紹介したいと思います。

本エントリの要約

さて、忙しい人のために本エントリの内容をまとめたものをここに記載しておきます。

  • データベースのマイグレーションやバージョンアップを控え、チーム内に安心してメンテナンスしたい要望が強くなってきていました。
  • メンテナンスの要件を定義し、現時点でメンテナンスモードに必要なスコープを明確化することで現実的に実現可能なものにしました。
  • メンテナンスモード実現のために4つ+1つのポイントを検討しました。それにより安全にメンテナンスを行うことができるようになりました。

メンテナンスモードとは

メンテナンスモードとは、利用者に対してメンテナンス中ですと画面に出して、利用者が一時的にサービスを使えない状態にさせる機能のことを指しています。

メンテナンス中のWebアプリの画面イメージ

なぜAI在庫管理ではメンテナンスモードが必要だったのか

AI在庫管理では、メインのデータベースとしてAmazon Aurora MySQLを使用しています。データベースのマイグレーションなどでメンテナンスが必要になるのですが、AI在庫管理では、元々メンテナンスの時間やタイミングやその運用方法などは明確には定めておらず、利用者が少なくなる夜間のタイミングを狙って短時間のメンテナンスを実施していました。
これまでは短時間のメンテナンスがほとんどで問題は少なかったのですが、それでもデータベースのマイグレーションとAPIのアクセスやバッチ処理の実行が重なった場合にはエラーが発生することもあり、発生したエラー内容などからメンテナンス作業後に必要な復旧作業を都度行っていました。

しかし、機能の追加や利用者が増加するにつれてデータベースのテーブル数やレコード数が増えてきて、マイグレーション作業の時間が長くなってきていました。またさらに、Aurora v3へのアップデートも控えていました。データベースのバージョンアップやデータベースの長時間のマイグレーションでは、正常にデータベースが稼働できない期間が生じてしまいます。そうすると、利用者が使用するWebアプリは正常に使用できずエラーが表示され、定期実行などのバッチ処理も失敗してしまいます。利用者にも不満がたまり、メンテナンス作業者としても不安感が大きくなったり焦ってしまうことが考えらるため、いよいよ安全に安心してメンテナンスできるようにしたい要望が強くなってきました。

メンテナンスの課題

ここではメンテナンスモードによって、利用者がメンテナンス中は利用できないように止める前提で説明していますが、無停止でメンテナンスできるようにするという手段も考えられます。しかし、AI在庫管理のプロダクトは薬局向けのプロダクトであり利用が減る時間帯が存在することと、完全無停止でメンテナンスできるようにする設計コスト、インフラのランニングコストも見合わないと判断し、時間を決めて利用を止めてからメンテナンスするアプローチを採用しました。

メンテナンスの要件を明確化して、対応範囲を絞ることにしました

先に説明した通り、メンテナンスモードの実現には、利用者が直接使うWebアプリの画面を停止するだけではいけません。他システムからイベントとして連携されてくるものがあったり、定期実行のバッチ処理などもあり、それらがデータベースへアクセスすると同じようにエラーが発生してしまいます。そのため、安全にメンテナンスを実施するためには、メンテナンス作業に関わるすべての影響範囲を洗い出し、メンテナンス中は正しく止めて、メンテナンス中に止めていた処理をメンテナンス後に復旧させる必要があります。
AI在庫管理のプロダクトは他プロダクトや外部サービスとの連携もあり、定期実行のバッチ処理もたくさんあるため、メンテナンスモードの対象としてすべての処理を対象とするのは現実的には難しい状況でした。

そこで、改めてどんなメンテナンスができれば良いのかを整理することにしました。メンテナンスの種類を定義し、対象とするメンテナンス作業の種類も明確にすることで、現在必要なものだけにしぼることにしました。

メンテナンスの種類として下記のように3種類定義しました。

  • 定期メンテナンス:月1回や年1回など決まったスケジュールで行われるもの。
  • 計画メンテナンス:日時と作業内容を決めて、事前に告知した上で実施するメンテナンス。
  • 緊急メンテナンス:障害発生時などに実施する緊急的なメンテナンス。基本的に大規模メンテナンスになり対応時間も予測不可能なことが多い。

また、対象としたメンテナンス作業の内容としても、これまで話してきたようなデータベースのメンテナンスだけとしました。さらに、その中でも15分〜1時間程度のデータベースマイグレーションやAurora v3へのバージョンアップ作業のようにデータベースの再起動を伴うようなものを対象として検討しました。
とくに、24時を過ぎてしまうと、深夜バッチ処理まで考慮しないといけなくなるためそこは対象外としました。

この決定によって、影響範囲がデータベースに絞られ、さらに考慮すべきバッチ処理も時間によって絞ることができました。

メンテナンスの種類

4つの検討ポイントとアプローチ

検討ポイントとしては大まかに分類して下記の4つがありました。それぞれのアプローチを説明していきます。

  • メンテナンスモードをON/OFFする方法
  • API/アプリのメンテナンスモード時の方式
  • 他システムから連携されてくる処理のメンテナンスモード時の方式
  • 定期バッチ処理のメンテナンスモード時の方式

メンテナンスモードをON/OFFする方法

システムの各コンポーネントがメンテナンスモードがONになっているかOFFになっているかを知れるようにする必要があります。メンテナンス作業者がCLIやAWSのマネジメントコンソールでON/OFFを切り替えられること、各コンポーネントからのアクセス数に耐えられること、AWS費用が大きくかからないこと、などを考慮してAWS AppConfigを採用しています。実際はバックエンドとフロントエンドでは異なる仕組みを使っていますが、ここでは省略します。

また、メンテナンスのさまざまな細かいユースケースに柔軟に対応できるように、コンポーネントごとに細かくON/OFFできるようにしています。

メンテナンスモードのON/OFF

API/アプリのメンテナンスモード時の方式

API、Webアプリ、および、モバイルアプリは、メンテナンスモードのON/OFFのフラグを取得して動作を変えます。Webアプリはメンテナンス中の場合は、メンテナンス中の画面を利用者に表示するようにします。APIはメンテナンス中を示すエラーをフロントエンドに返却するようにしています。

API/アプリのメンテナンスモード時の方式

他システムから連携されてくる処理のメンテナンスモード時の方式

次に他システムから連携されてくる処理の対応の方針です。
連携先のシステムやサービスから自動でAI在庫管理に連携するような仕組みになっていて、どんどんデータが送られてきます。それらをメンテナンス中にエラーにするわけにはいきませんでした。そのため、メンテナンス中は別の場所にためるようにして、メンテナンスの作業終了後にそこから取り込みが行われるようにしました。幸いにも、取り込みの順序性はロジックで気にしなくてもいい状態になっていたので、メンテナンス中に連携されたデータの再取り込みと、新規に連携されたデータのイベント処理による取り込みを並行で取り込むことができました。

他システムから連携されてくる処理のメンテナンスモード時の方式

定期バッチ処理のメンテナンスモード時の方式

最後に定期バッチ処理のメンテナンスモード時の方式についてです。
AI在庫管理の中に定期バッチ処理は45本ほどあり、それぞれの処理内容によって対応を検討する必要がありました。

今回、すべてのバッチ処理を洗い出し、各バッチ処理で対応が必要かどうか、必要な場合はどのように対応すれば良いかを検討しました。ただ、先に説明したメンテナンスの要件によって作業時間などを明確化していたおかげで、ここで詳細のな検討が必要なバッチ処理は15本ほどに絞ることができていました。

バッチ処理の洗い出しとバッチ処理ごとの方針決め

検討した結果、基本的な方針としてはエラーにならないようにバッチ処理を空振りするようにし、メンテナンスモード解除後に必要に応じて実行する方針でほとんどの定期バッチ処理の対応が可能なことがわかりました。各バッチ処理でメンテナンスモードのON/OFFを確認して、処理を変えるようにしました。

定期バッチ処理のメンテナンスモード時の方式

さらにメンテナンス後の動作確認用に一部だけメンテナンスモードを解除できるようにしました

ここまで検討ポイントを説明してきましたが、最後に工夫したところをもう1つ紹介したいと思います。
AI在庫管理は普段の機能のリリースは心配にならないくらいの自動テストはありますが、もちろんすべてを網羅的にテストできているわけではありません。Aurora v3へのバージョンアップの大きな変更などは影響範囲も大きく、自動テストだけでは少し心配なところがありました。
そのため、メンテナンスモードに薬局を指定して一部の薬局だけをメンテナンスモードの解除をできるようにし、テスト用の薬局を使用してメンテナンス後に手動でもE2Eの動作確認を行えるようにしました。

一部の薬局のみメンテナンスモードの解除

おわりに

AI在庫管理のメンテナンスモードの開発を行いました。メンテナンス中の各コンポーネントの動作を検討したことにより、メンテナンスを利用者にもメンテナンス作業者にも安心と安全を提供することができたと思います。
そして、このメンテナンスモードを使用してAI在庫管理のAurora v3へのバージョンアップのメンテナンスも無事に完了させることができました。