ECS初心者の私が6年間使っていたHerokuのインフラを3ヶ月でAWSに移行させるまで
背景と動機
2023年11月に私は落とし物防止タグであるMAMORIOのインフラをHerokuからAWSへ移行しようと決断し、2024年2月5日にその移行作業を完了させることができました。
そして結果としてインフラコストを40%程度削減することに成功しました。
AWSのコストが25%増加する代わりに、それまでインフラコストの半分を占めていたHerokuのコストがゼロになりました。
HerokuはEnterpriseを利用しており、東京リージョンで動作させていたのでレスポンス速度などの品質には特に問題はなかったのですが、移行を検討した理由は主に2つありました。
1つ目はコストを下げることです。
Herokuでのコストダウンにはすでにかなりのところまで行っていたのですが、HerokuはAWSのインフラの上に構築されているため、それをなくすことでさらにコストを3分の1に圧縮できるのではないかと見積もっていました。 契約が1年単位の一括払いだったこともフレキシビリティに欠けているなという印象がありました。
また、もう1つはLLMであるChatGPTの登場によって私自身の作業スピードと学習能力が向上しており実現可能性が高まっていたことです。
そもそもHerokuを導入した理由は社内にインフラに精通したエンジニアがいなかったことが大きく、今回の作業者である私自身もメインの知識領域はiOSアプリとRailsとReactの開発だったのですが、技術顧問を雇わなくてもAIがAWSに関する質問の壁打ち相手になってくれたので自分の能力向上に自信を持つことができました。
環境の移行
移行前はHerokuにコードのデプロイを行っていましたが、新しい環境ではECSにコンテナにデプロイしFargateを採用することにしました。
また、データベースはロックインを避けてポータビリティを確保するためにAuroraではなくPostgreSQLを使用することにしました。
スケジューラーは無料のHeroku Schedulerに任せきりだったのでほとんど意識する必要はなかったのですが、移行後はECSのスケジュールされたタスクでcron形式の指定に置き換える必要がありました。
計測ツールはCloudWatchを活用し、独自のダッシュボードを作成することにしました。
移行前に使用していたHerokuのアドオンのNewRelicは優れたツールでしたが、最も重要なDBのパフォーマンスチューニングはRDS Insightsで行えるため、コストを勘案して利用を止めることにしました。
非同期処理キューの管理を行うRedisはElastiCacheに移行しました。
移行計画
移行計画では、まず事前にウェブサーバーと付随サービスをawsに構築しておき、最後にHerokuを一時的に停止してデータベースのバックアップをとってpg_restoreで移行することにしました。
aws内にherokuのDBをフォローする別のDBを作成して無停止で移行することも考えましたが、両方の環境に跨る形でその関係を構築するのが難しいことと現実的な停止時間で移行が可能なことが明らかになったため、すでにノウハウが確立されていて枯れた手法であるリストアの方式で行ったほうが手堅いという判断です。
その見立てを立てた上で、以下のようなスケジュールで移行を行う計画を立てました。
Heroku Enterpriseの一年契約を更新する期日の前に10日間のバッファを設けたのは、移行に失敗した際に引き続き現行環境での稼働を行える余地を残すためです。
負荷テスト
第一段階での負荷テストでは、まずaws内に環境を構築したのちに、本番環境にきているの中でもっとも処理コストが大きいものだけを流してみてパフォーマンスやコストが急増してしまわないかを確認しました。
MAMORIOの場合はユーザーのスマートフォンから送られるタグの発見情報のログがシステム全体の負荷の90%を占めていて最も重かったため、そちらを送ることにしました。
結果負荷テストは無事成功し、おおむね自分が想定しているインフラの構成で移行をしても大丈夫だという確信を持つことができました。
また、それまで半信半疑だったCEOからもゴーサインを得ることができました。
技術相談とリハーサル
負荷テストが成功したのちに、Amazon社のエンジニアの方からの技術相談とリハーサルを行うことにしました。
技術相談
Amazon社からの技術相談はherokuから移行する予定だと伝えることで無料で受けることができました。
いくらLLMがあるとはいえChatGPTの知識は最新のものではなく、現在のawsの全てのサービスや最新のインスタンスについて知っているわけではなかったためアドバイスをいただきたかったからです。
そして、その結果としてかなり貴重な助言をいただくことができました。
私は当初RDSのPostgresqlのインスタンスもWebサーバーのFargateと同じようなサーバレスにしたいと考えておりAurora Serverlessを検討していたのですが、アドバイザーの方から以下の記事を共有された上で頻繁にアクセスのスパイクがあるわけではないサービスをする上でAurora Serverlessはコストが見合わないという指摘をしていただけました。
DBは一度移行すると変更が効かないため、技術相談を受けていなければ危うくパフォーマンスに見合わないコストをずっと払い続けてしまうところでした。
また、AWS GuardDutyやWAFなどHerokuを利用していた際にはあまり手を加えてこなかったセキュリティ関連のサービスに関してもご教示をいただけたのは非常に助かりました。
リハーサル
リハーサルはherokuのデータベースのバックアップをダウンロードしてから移行先のDBにリストアするまでの手順の作成と時間の計測を行うために何度も行いました。
考慮守れを可能な限りなくし、移行にかかる時間を短くするのが目的で、理想は移行当日はなるべく何も考えずに自分が作成した手順書に従うだけで終えられるようにすることでした。
リハーサルを何度か行った結果、Herokuの東京リージョンにあるプライベートインスタンスとAWSの東京リージョンが同じネットワーク上にあることを利用してHeroku内のインスタンスにダウンロードしてからawsに直接アップロードしたほうが作業時間を7割以上削減できることがわかりました。
この短縮により、時間のかかるDBのリストアで失敗があってもサービスを停止する1時間以内にやり直すことができる余裕を得ることができました。
また、当初は想定していなかったスケジューラーの移行に手間がかかることがわかり、こちらも先手を打って対策することができました。
移行手順
リハーサルを何度か行い当日の作業の手順が確定してから、社内全体に移行プランを周知し、サポートチームにはユーザー向けの告知スケジュールを立ててもらいました。
移行作業は深夜0時から開始しました。
Herokuのメンテナンスモードをオンにし、すべてのタスクが完了していることを確認した上で、データベースのバックアップとリストアに取りかかりました。
作業完了後にドメインの向き先を変更し、無事に移行を終えることができました。
結果
移行をおこなう2ヶ月前からある程度のサイズの環境を構築して負荷テストとリハーサルを行なっていたためコストが発生してしまいましたが、その結果安心感を持って移行をおこなうことができ、また会社全体が支払う月額のコストが40%削減することができました。
まとめ
Herokuは決して悪いサービスではありません。
インフラの専門知識がないエンジニアでもコンパクトにまとまった管理コンソールから簡単な操作でスケールする環境を作れるのは人員に余裕がない組織にとっては大きなメリットであり、アドオンで簡単に様々な機能を追加でき、UIもAWSよりかなり洗練されています。
また「スタートアップや中小企業は頑張ったところで利幅のたかが知れているコスト最適化よりもより多くの顧客を獲得するための新規開発にリソースを割くべきだ」という一般論には今でも一理あると思います。
ただ、同じようにHerokuからAWSへの移行を考えている方に対して伝えたいのは、とにかくAmazon社の技術相談は必ず受けるべきだということとリハーサルは不安が全くなくなるまで何度も行うべきだということです。
まず、Amazon社の技術相談を受けることでパフォーマンスに見合わないコストのインフラを選択してしまう危険性をなくすことができます。
特にAWSのEC2やRDSなどは新しいインスタンスオプションが次々と登場しますのでAWSに熟達していると自認しているエンジニアでも知識が古びている可能性が高く、思い込み(例:Fargateがいい感じに安くてイケてるのだからAurora Servarlessもイケてそう)による誤解を解いてもらう上でもアドバイスは有益です。
また、リハーサルを繰り返し行うことで移行作業にかかる時間を短くし、負荷テストと技術相談の段階では気づくことができない移行のプロセスの問題を洗い出すことができます。
Discussion