システム変更が反映しないトラブルの備忘録~キャッシュクリア編~
大変ベタな話題で恐縮ですが、システムの更新が上手くいかずに小一時間ほど嵌ってしまったので、自戒も意味も込めて文章に残しておこうと思います。
原因について
勿体ぶるような内容でもないので先にトラブルの原因を明かしてしまいますが、今回上手くいかなかった原因は冗長化したサーバーのキャッシュクリア漏れでした。
まぁありがちな話だと思いますが、繰り返さないように、恥を忍んで共有します。
原因が分かった時は、ガックリと力が抜けました…orz
環境について
まず本番の稼働環境としては、
- AWS上にLAMPで構築したウェブシステム
- MVCモデルでシステム開発
- ウェブサーバはEC2で冗長化(2台構成、指定フォルダを同期)
- データベースはRDSを使用
- セッション保持のためにElastic Cacheを使用
- 一部ファイル、画像などの実ファイル置き場としてS3をマウント
と、比較的シンプルな構成のウェブシステム環境です。
システム自体としても、業務上のデータを登録して、それらを一覧表示・検索・詳細閲覧ができるといったシンプルなものです。
本番環境の他には、社内ネットワーク上の検証環境(AWSへシステム移行する前は本番の稼働環境だった)と個別の業務PC上に開発環境がある、といった状況です。
現象について
今回のシステム変更の内容としては、
- データベースの既存テーブルへ新規カラムを追加
- 業務データの更新時に、上記カラムへシステム側で自動的に書き込みを行う
といったものです。
ローカルの開発環境にて開発とテストを行い、社内ネットワーク上の検証環境にて動作確認を実施した後、特に問題はなかったので本番環境へリリースを行いました。
ただ、本番環境でも何度か動作確認していたところ、新規カラムへ書き込みが出来ている場合と、書き込みが出来ていない場合があることが判明しました。
しかも、書き込みできていない場合でも特にエラーは発生せずに、空が登録されて正常完了となっていたのです。
原因の絞り込み
トラブルの調査を行う際に厄介なのが、現象が起きる場合と起きない場合があり、パッと見でその切り分け条件が分からない時ですね。
特定の手順で必ず問題が発生してくれれば、即解決はできなくとも、原因箇所の絞り込みは比較的簡単なのですが…。
また今回は、特にエラーが発生しているわけでもなかったので、なかなか原因の絞り込みが出来ません。
ただ、開発環境や検証環境では問題がなく、本番環境でも正常にいく場合もある、となるとプログラム側ではなく環境に依存する問題である可能性が高く、つまりは冗長構成に関するどこかに何かしらの問題があるのでは?と考えられます。
プログラムのソースコードなど、冗長化しているサーバー間で同期が必要なデータについては、フォルダ単位での同期設定を行っており、通常プログラムを更新する際はプライマリーとしているサーバーに対して更新作業を行っています。
今回は画面上の変更がなかったため見た目には分からないものの、もしかしたら、この同期処理が上手くいかずに片方のサーバーでは古いソースコードで動作しているのかも?と考えましたが、結局両サーバー間でのソースに差異は無く、同期もキチンとされていました。
ここで何か抜け漏れが無いかとリリース手順を見直していた時に、ふとキャッシュクリア(削除)の手順が目に留まりました。
原因について
今回のシステムはMVCモデルで開発を行っていたので、データベースの既存テーブルに新規カラムを追加するにあたってデータモデルの更新も行っていました。
この時、サーバー上にはモデルのキャッシュファイルもあるので、キャッシュも更新されないと変更が反映されません。
手順上は、このキャッシュファイルを削除することで変更を反映させていたのですが、キャッシュファイルのあるフォルダは冗長化しているサーバー間での同期対象ではなかったため、プライマリーサーバーだけ削除してもセカンダリーサーバーには古いモデルのキャッシュが残ってしまっていました。
結果として、冗長化しているプライマリー側で処理されていた時は正常に動作して、セカンダリー側で処理されていた時は古いモデルのキャッシュにより追加カラムが無いものとして動作していた、という状況でした。
最終的にはセカンダリーサーバーのキャッシュもクリアすることで、正常に動作するようになりました。
環境の違いには気を付けましょう
今回トラブルとなった要因は細分化すれば幾つかありますが、結局のところ、検証環境と本番環境のサーバー構成の違いについて、考慮が不足していたというのが大きいでしょう。
検証環境はプログラムの動作確認的な意味合いが強いので、リリース手順の確認に対する検証精度を求めるには条件を満たせていないのが、今回のトラブルにつながったのだと思います。
とは言え、そのために検証環境を本番同様に冗長化するかと言えば、それは費用対効果を考えてもあまり意味がありません。
なので今回の場合は、このトラブルを教訓にして今後のリリース手順でどういった点を考慮するべきか、手順書のフォーマットに盛り込んでおくなどして、同じ抜け漏れを起こさないようにする、といった形に落ち着きました。
トラブルの原因としては「キャッシュのクリア漏れ」という非常に初歩的なものでお恥ずかしい限りなのですが、この話題が誰かのお役に立てれば、この気恥ずかしさも浮かばれるというものです…。