🍰

40以上のバッチ、アプリケーションに影響するElastiCacheのアップグレードを行ったんだぁ。がんばったんだぁ。

2022/08/29に公開

ある日の出来事

スターフェスティバルのDPontaroです。
GWに差し掛かる頃でしたでしょうか。社内slackでこんなやり取りがありました。

プリンシパル:ElastiCacheのバージョンがEOLみたいやわ。誰かやらん?
ワイ:はいはーい
  • やったことないけど、まぁコンソールからポチポチすりゃいけるやろ
  • 前職までのゲーム運営では、だいたいメンテいれてやってたし、今回も似たようなもんっしょ

甘かったです😇

まず何をすべきか

一旦上長と打ち合わせを行い

・大まかなスケジュール策定
・参照しているアプリケーションの抽出と、影響範囲の精査
・対応時間の見積もり
・対応日程の確定
・アップデート対応

といった流れで作業していくこととしました。

調査開始

関連アプリケーション

ひとまずアップデートを行うことで、どのアプリケーションに影響があるのか調査を行うこととなりました。

本番環境で対象となっていたElastiCacheインスタンスは2台。

ありがたいことに、使用状況のドキュメントが残されており
Redis上のどのdbが、どのアプリケーションで使用されているかまとめられていました。

ドキュメントによると、関連するアプリケーションは10ほどありましたが、
ほとんどがセッション情報や、クエリのキャッシュ情報なので
大きなリスクは無さそうだなと”この時は”思いました。

さて、えてしてドキュメントというのはメンテが追いついていない可能性もあるため
記載と実態が合致しているか、実データも参照して調査を継続していきました。

キュー監視バッチ

Amazon SQSのキューを監視し、メッセージ中の指定スクリプトを実行する。
このバッチが排他制御用にRedisを使用していました。
それは良いのですが、実行されるバッチ処理が40以上も存在していたため、
影響範囲の調査は、格段に膨れ上がることになりました(泣)

バッチの実行頻度の調査

影響範囲を探るため、1ヶ月分のログをあさり、実行時間を調べました。
hourly, daily, weekly, monthly, 不定期(注文時などのイベントがトリガー)
と見事にバラバラで、"n時台なら何も実行されていない"という完全に安全な時間帯は無いことが判明しました。

なるべく実行数が少ない深夜帯にノーメンテで行う必要が出てきました。

バッチの実行内容の調査

アップデートの対応遅れなどにより、バッチ実行が失敗、遅延などした場合に
どのような影響が起こりうるかを把握するため、各バッチ処理の詳細も調査しました。

結果として多少の遅延がクリティカルになることはない
とはいえ、商品の完売設定を行うようなバッチ処理もあったので、
なるべく遅延無く対応する必要がありそうでした。

事前にアップデート対応の概要相談

私の前職までの経験上、この手のインフラのアップデート時には
サービスをメンテナンス状態に入れて行っていたのもあり、
当初はメンテナンスを入れて、既存インスタンスを直接アップデートするようなイメージでした。

ですが関連するアプリケーション、バッチの数も多くあるため、
相談の結果、ローリングアップデートを行う方針となりました。

  • 現行インスタンス(ElastiCache ver 2.x)は残したまま、新規インスタンス(ver 6.x)を構築
  • 現行インスタンス → 新規インスタンスへデータ移行
  • Route53の向き先を新規インスタンスへ切り替え

という形をとります。

キュー監視バッチの影響を抑えるために

キュー監視バッチは、2台構成で稼働しており排他制御のためにElastiCacheを参照していました。
↑のアップデート手順では、Route53の切り替え時

  • 排他制御の書き込み→旧インスタンス
  • 排他制御の参照→新インスタンス

と、タイミングによっては排他制御が効かない可能性もありました。
このため、移行タイミングでは1台のみバッチを停止状態にするように対応することにしました。
バッチの処理数は半減しますが、なるべく実行数の少ない時間に行うため大きな問題にはならないだろうという想定です。

開発環境のアップデート対応の流れ

本番より先に開発環境向けのアップデート対応を行いました。

作業手順書の作成

事前に手順書を作成し、工程に問題が無いかを確認。
当初疎通確認用のEC2をいちから立てるつもりでしたが
AMIを使いましょう、と提案いただいたり
特にインフラ周りの工程でフォローいただけました。

アップデート対応

調査途中で判明したのですが、開発環境用はElastiCacheでなく
EC2上で稼働しているredis-serverを使用していました。
これも古いバージョンだったので、redis-serverもバージョン6へアップデートを行いました。

対応時は、slackのハドルで画面共有をして対応を行いました。
えてして予期しないトラブルは起こりうるので、
そういった際にフォローをもらえるのと、
こういった対応自体が貴重な機会なので、
どんな流れで作業しているのかをリアルに見れるのでシェアしておくのはオススメです。

本番対応

作業手順書の作成

開発と同様に作成し、工程に問題が無いか事前にチェックしてもらいます。

/images/aws-elasticache-upgrade/01-operation-document.png
添付のように
実施予定日時、対応内容、所用時間、対応詳細、担当者、作業状況
という項目を設けました。

作業手順

実際の切り替えは深夜に行いますが、
日中にインスタンス作成などは事前準備を行うようにしました。

  • ElastiCache ver6のインスタンス作成
  • 確認用のEC2を別途構築

サービスに影響が出る可能性もあるため、深夜対応を行うことを事前に全体周知。
作業者は私と上長の2人体制となります。

深夜

  • 旧インスタンス → 新インスタンスへデータ移行
  • Route53の切り替え
  • 関連アプリケーションの動作確認
    • セッションとして使用されているアプリケーションはログインできればOK
    • バッチ処理類は正常実行されたログが確認できればOK
  • 新インスタンス側にデータ作成されているかを確認
  • 旧インスタンスの接続が残っていないか確認

翌日以降

  • 各アプリケーションで問題が出ていないか監視
  • 影響なければ旧インスタンスを削除

予想外の出来事

旧インスタンスのマシンタイプが無くなっていた

旧インスタンスのマシンタイプが、cache.m3.mediumであったため、
新インスタンスも同様のものを選択しようと想定していたのですが
m3は既に旧世代となっており、m5を割り当てるにもmediumが無いという状態でした。
インフラ担当と相談し、コストはあがりそうですがm5.largeを選択するという方向で落ち着きました。
作業手順をテキストにまとめるだけでなく、事前に構築手順に触れておけば気づけたなと反省。

本番環境のアクセス方法(ssm)

こちらも事前に確認しておきましょうなんですが
開発環境は踏み台サーバ経由だったのですが、
STG,本番環境については、Session Managerが使われており
での接続となっていたため、急遽作業時に権限付与いただいたりしました。

DNSキャッシュ

Route53の切り替え後、ログインに失敗する箇所が出てきました。
DNSのキャッシュが残っていた関係かうまくセッションを維持できていなかったようで
数分で解消されました。

減らない接続数

新インスタンスに切り替え後、旧インスタンスの接続数をCloudWatchで確認していました。
NewConnectionsは旧インスタンスでは発生していないのですが、
CurrConnectionsの数字が0にならず、いくつかコネクションが残っている気配がありました。
redis-cli上で"CLIENT LIST"を実行し、接続元を確認。
コネクションを掴んだままのようなので、httpd再起動などを順次行うことで解消することができました。

初モノの苦労あれこれ

入社間もないためドメインの知識が不足しているのと、
自分の経験不足も合わさり、調査は結構な苦労がありました。

見つからない環境変数設定

このアプリケーション環境変数でRedis接続先参照してるけど
.envにそれらしい環境変数の設定が無い。どこ???
→ AWS Secrets Managerに設定があり、GithubActionsにて.envに追記されていました

キュー監視バッチの定期実行

自分の中でバッチを定期実行するにはcronを設定するのが定番でした。
ただキュー監視バッチのcronの設定がありません。
systemctlでサービス化されてるわけでもなく、
実行ログを見てると、10秒毎にSQSへ問い合わせをしているようでした。

よくよく資料を漁っていると、supervisorという初見の文字が。
http://supervisord.org/
プロセス監視をするツールのようで、こいつがキュー監視バッチを定期実行するよう設定されていました。
厳密にはiniファイルにautorestartの設定でプロセスが死んだら再起動するような設定でした。

autorestart=true

本番移行タイミングでは、下記手順にて設定適用し、一時的に停止させました。

# 再起動設定をoffに
autorestart=false
# 設定変更を読み込ませる
$ supervisorctl reread

# 設定変更の適用(バッチ動いてないタイミングで行う)
$ supervisorctl update

その他なんやかんや初モノ

  • Route53 プライベートホストゾーン
  • Elastic Container Service
  • TaskDefinition
  • terraform plan import
  • Amazon Machine Image

AWSは前職では、別会社を挟んで構築いただいてたのもあり
サービスの概要などは知っていても直接触ったことないものも多くあり
なかなかに苦労をしましたが、良い経験になりました。

教訓

ドキュメント残しておきましょう

初手でどのアプリケーションが関連しているか把握できたのと
キュー監視バッチにおいても、supervisorの存在を知れたなど
ドキュメントに助けられた部分は多々ありました。

変更があった際に更新行うメンテナンスコストはどうしてもかかりますが、
残しておくにこしたことなとはないでしょう。

私も今回対応した際の調査物や作業工程等は残しています。
(読みやすさが担保されてるかが怪しいところもありますが)

必要に応じて定期的にバージョンをあげておきましょう。

今回ver 2 -> 6への更新と数段飛びの更新となりました。
幸いにも現状の使用方法に影響のある破壊的変更はなかったですが、
アプリケーションの修正なども必要であった場合にはより多くの時間を取られたと想像できます。
定期的にキャッチアップを行い、余裕のあるとき(なかなか無い)にバージョンアップしておくと
こういった心配は最小限にできるのかなと思います。

依存先はなるべく減らしておきたい

多くのバッチ処理、アプリケーションに参照されていたため
アップデートの作業の影響範囲を把握するだけでも結構な時間を要しました。
※調査開始が5月、アップデートは7月になりました。

こういった際に影響範囲を抑えるためにも
なるべく依存先は減らしておくように設計をしていきたいところです。

※長年運用しているサービスが存在するため、当時の様々な事情があって選択された結果でしょうから
現状の構成を批判する意図はなく、先人には感謝しかないです。

そんなスターフェスティバルですが

絶賛エンジニア採用中でございます!
https://stafes.notion.site/stafes/d0996a00d77d418280982797c7e16001

嬉しいことに7月にも2名がジョイン!
ですが、まだまだエンジニアの力が必要な状況です!

良い環境整えてますので興味のある方、ご応募お待ちしております!
ウェルウェルカムカム!!

スタフェステックブログ

Discussion