AWSコストを65%削減したお話とその先に見えたこと
この記事は KINTOテクノロジーズアドベントカレンダー2024 の23日目の記事です🎅🎄
1. はじめに
こんにちは、KINTO FACTORY でバックエンドエンジニアをしている西田です。
今回はAWSコスト削減をテーマにお話をしたいと思います。
2. コスト削減に取り組んだきっかけ
KINTO テクノロジーズでは AWS のサービス利用料を Amazon QuickSight を使って可視化しており、プロダクト単位で利用料を確認することができます。
KINTO FACTORY をローンチしてしばらく経った頃、何気なくプロジェクトのコストを確認してみたところ、なんと社内全プロダクトの中で2番目にコストがかかっていることが分かりました。まだサービスを開始して間もない段階でここまでのコストが発生しているのは想定外でした。この「えっ!?」という発見をきっかけに、アプリケーションチームを主体に私たちのコスト削減への取り組みが始まります。
3. 具体的にやったこと
それでは、私たちが実際に取り組んだコスト削減施策について詳しくご紹介していきます。
ECS Fargate のインスタンス数と起動タイプの見直し
コストの内訳を眺めてみると、ECS Fargateの利用料が断トツ1位でした。KINTO FACTORYのアプリケーションがECS Fargate上で動いているため当然といえば当然なのですが、このコストを何とか最適化できないか検討することにしました。
まず最初に気づいたのが、「あれ?開発環境のインスタンス数、本番と同じになってない?」という点。開発環境ってそんなにガッツリしたスペックはいらないはず。そこで、開発環境のインスタンス数を必要最低限まで減らすことにしました。
さらに調べてみると、Fargate の起動タイプには通常とは別の Fargate Spot というものがあることがわかりました。Fargate Spot は AWS 上にある未使用のリソースを利用する仕組みで、通常の Fargate に比べて最大70%の割引が適用されます。使わない手はないですね。
Fargate Spot を使用すると、割り込み許容のある Amazon ECS タスクを、Fargate 料金と比較して割引料金で実行できます。Fargate Spot は、予備のコンピュートキャパシティーでタスクを実行します。AWS がキャパシティを戻す必要がある場合、タスクは中断され、2 分間の警告が表示されます。
-- https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/fargate-capacity-providers.html
ただ、ドキュメントにもある通り Fargate Spot は予備のコンピュートキャパシティーでタスクを実行している仕組みとなるため、AWS 側のリソース調整でタスクが途中で中断される可能性があります。本番環境への適用は難しいので中断されても問題ない開発環境を対象に設定を変更しました。
開発環境の起動・停止の自動化
本番環境だけでなく開発環境も24/365稼働していたため、深夜帯や休日といった利用しない期間は開発環境を停止させるようにしました。
構成としては Step Functions を使って、Application、DB の起動停止を自動化しました。
前段に EventBridge を使い、cron で指定した日時に Step Functions に対して起動・停止のトリガーを送信します。
ポイントとしては DB の起動には時間がかかり起動直後に ECS を起動するとコネクションエラーになってしまうため、DB のステータスを確認してから ECS を起動するようにしています。
参考のため、以下にStep Functionsのワークフローを記述するサンプルコード(YAMLファイル)を示します。
"DB起動": {
"Type": "Task",
"Parameters": {
"DbClusterIdentifier": "${db_cluster_identifier}"
},
"Resource": "arn:aws:states:::aws-sdk:rds:startDBCluster",
"Next": "Wait"
},
"Wait": {
"Type": "Wait",
"Seconds": 300,
"Next": "起動後のDBの状態取得"
},
"起動後のDBの状態取得": {
"Type": "Task",
"Parameters": {
"DbClusterIdentifier": "${db_cluster_identifier}"
},
"Resource": "arn:aws:states:::aws-sdk:rds:describeDBClusters",
"Next": "起動完了しているかチェック"
},
"起動完了しているかチェック": {
"Type": "Choice",
"Choices": [
{
"Variable": "$.DbClusters[0].Status",
"StringEquals": "available",
"Next": "各サービスの起動"
}
],
"Default": "Wait"
},
サーバーレスアーキテクチャへの移行
次に、ある機能のバッチ処理を見直していた時に処理自体は1分もかからないのにECSを使った常駐サービスで稼働させていることがわかりました。
こちらもコスト的に効率が悪いと考え、Lambdaを用いたサーバーレスアーキテクチャへ移行しました。
Lambda はリクエスト数と実行時間に応じて課金されるため、短時間で終わる処理や常時起動不要な処理を実行するには最適なサービスです。
4. コスト削減の結果
結果として、コスト削減に取り組んですぐに効果が現れ、ピーク時と比較すると 65% も削減となりました。まさかの半分以下です。
これだけ削減できる余地があったのは正直驚きでした。。。
5. さいごに
今回は私たちのコスト削減への取り組みについてお話しました。
実施したことはどれも簡単で特別なものではなかったですが、大きな成果を出すことができました。
また、取り組んでみて分かったことがあります。コスト削減って、単純に「お金を節約できた!」というだけじゃないんですよね。
- 無駄なリソースを見直すことで、システム全体の見える化ができた
- アーキテクチャを見直すきっかけになった
- 「本当にこのリソースいる?」を考える習慣が身についた
その先に得られるメリットも大きいので、改めて取り組みをして良かったなと感じます。
もし似たような課題をお持ちの方の参考になれば嬉しいです。
関連記事 | Related Posts
Bedrock Knowledge baseにTerraformで入門してみた
データ競合を気にしながらS3イベントを処理してみた 〜Rust・Lambda・DynamoDBを添えて〜
Exploring Edge Functions Available in CloudFront
OpenSearch Serverless を AWS Managed Grafana のデータソースとして使用する方法
How To Use OpenSearch Serverless As A Datasource In AWS Managed Grafana
When NotFound Errors are plenty in AWS CloudTrail! Exploring Solutions and Best Practices