はじめに
現職のプロダクトにCMSシステムがございます。そのシステムではお客様毎のホームページを作成できます。ただ、お客様がホームページのページを誤って更新してしまったり、一部セクションを削除してしまった場合に戻すことができなかったため、以前の状態に復元できる仕組みを構築しました。
CMSの仕組みとして、ユーザがホームページを更新後、公開ボタンが存在しており、そのボタンを押すと外部に変更内容が表示されます。そのため、公開ボタンをユーザが押したタイミングで、DBにホームページのバックアップを保存します。そして、ユーザから以前の状態に戻して欲しいという依頼があった場合、エンジニア側でバックアップデータからホームページを復元するためのスクリプトを流すことをしておりました。
それによって、ホームページをお客様が誤って更新してしまっても戻すことができるようになりました。
問題点
ホームページを復元できるようになってすぐに問題は発生せず、数ヶ月後になって問題が明らかになりました。AWS RDSの金額が毎月5千円ずつ増えていることが発覚しました。年間で約30万円ほど増加する状況でした。
原因
復元機能のバックアップしたデータの保存期間は定めなかったため、公開ボタンを押すたびに無限にバックアップデータが残っている状態です。
大体1ヶ月でデータ量が600万件ほど増加している状態でした。
仕様変更
まずはデータの保存期間が定められていない状態でしたため、PDMと会話して3ヶ月間としました。
過去のお客様や社内メンバーからホームページの復元依頼の傾向を見てみると4ヶ月よりも前の状態まで戻してほしいという依頼は1年間ほどなかったため、3ヶ月間は保持するようにしました。3ヶ月よりも昔のデータは削除するようにしました。
対応
バックアップデータを3ヶ月よりも前のデータを削除するためにバッチ処理の実装が必要でした。
CMSはEC2インスタンスとRailsを使用しているため、最初はgemの'whenever'で実施しようかと思いましたが、CMSにはバッチサーバ用のインスタンスが存在しなかったことやバッチ処理を組む処理はサービスの特性上、今まで存在しない状態でした。
以下の方法を検討しました。
- 新しくバッチサーバを建てること
- WEBサーバにバッチ処理を入れること
- EventBridge + Lambda + SSM + EC2
結論として、「EventBridge + Lambda + SSM + EC2」を採用しました。
EventBridgeで毎日23時になったら、スケジュール起動して、Lambdaを呼び出します。
そして、LambdaからSSM経由でEC2上に作成したRakeタスクを呼び出すようにしております。そこでDBに格納されたデータを3ヶ月前まで削除するようにしております。
今までバッチサーバが存在しなかったことやサービスの特性上、バッチ処理を実装することはそこまで頻度に発生しないため、新しくバッチサーバを建てることはしませんでした。
また、WEBサーバにバッチ処理を入れることによって、バッチ処理で障害が発生した場合、WEBサーバの処理が巻き込まれて、障害になってしまうことを防ぎたかったため、WEBサーバにバッチ処理を組み込むことはしませんでした。
まとめ
結果として、インフラコストを大幅に削減できました。今までは毎月バックアップデータが日々、増えていくことによって、請求金額が増加していることに怯えていましたが、枕を高くして眠れるようになりました(笑)