AWS ECS で実行するバッチ処理を Cluster Auto Scaling を使ってコスト最適化する

システムプラットフォームチームで SRE をしている id:chaya2z です。

この記事は、はてなの SRE が毎月交代で書いている SRE 連載の6月号です。先月は id:MysticDoll さんの Postfixのログ監視で注意すべきSMTPのステータス仕様について でした。

ECS で実行するバッチ処理を、インスタンス数を最適化する仕組みである ECS Cluster Auto Scaling を使ってコスト最適化した取り組みを紹介します。

ECS の起動タイプに EC2 を使う背景

はてなでは、ECS の起動タイプとして Fargate ではなく EC2 を使用しているサービスがあります。そのサービス例として、バッチ処理があります。バッチ処理のジョブには数秒・数分で終わるものもあれば、数時間かかるものがあります。

EC2 起動タイプを選ぶ理由は、タスク終了までのタイムアウト待機時間にあります。Fargate 起動タイプでは「コンテナが正常に終了しなかった場合にコンテナが強制終了されるまでの待機時間 (秒)。」は最大で120秒1です。一方、EC2 起動タイプでは無制限 (実際は48時間以下が推奨2) に設定できます。

長時間のジョブの実行完了を待ってからタスクを終了したい (Graceful Shutdown したい) のが EC2 起動タイプを選ぶ理由です。

問題

プロダクトの機能追加の影響で、バッチ処理で大量のジョブを実行することになりました。

そこで次の問題が明らかになりました。

費用コストの増加

必要なリソースを見積もると、決まった時間帯にそれまでと比べて2倍の EC2 インスタンス数が必要なことがわかりました。それまでは5台の EC2 インスタンスで ECS タスクを動かしていたので、10台必要になります。

これまで負荷は一定だったためタスク数・インスタンス数のスケーリングは設定しておらず、愚直に EC2 インスタンス数を2倍にすると料金も2倍になってしまいます。

問題解決の方針

上記の問題について、EC2 インスタンスのスケーリングができるか調べたところ、ECS Cluster Auto Scaling が使えそうだとわかりました。

ECS Cluster Auto Scaling とは

ECS Cluster Auto Scaling とは、ECS の EC2 起動タイプにおいて、ECS が EC2 インスタンスの Auto Scaling を管理する機能です。

Auto Scaling Group を使用する Capacity Provider を作成し、サービスに設定することで利用できます。

docs.aws.amazon.com

ECS Cluster Auto Scaling の使いどころ

EC2 インスタンスがまだ準備されていない状態でスケールアウトするとき、EC2 インスタンスが起動するのを待ってからコンテナが起動します。EC2 インスタンスの起動からコンテナの開始までは5~10分ほどかかるので、ワークロードの需要の増減が激しいサービスには向かないと考えています。

予め負荷を予想できる今回のバッチ処理の場合、起動時間を考慮したスケジュールに基づいてスケーリングができるので問題ありませんでした。

スポットインスタンスは導入しなかった

EC2 のコスト削減の方法にスポットインスタンスの使用があります。スポットインスタンスはオンデマンドインスタンスに対して最大90%の節約ができますが、インスタンスが中断されることがあります。

今回の場合、数時間かかるバッチ処理のジョブでは中断の影響が大きいためスポットインスタンスの導入は見送ることにしました。

結果

結果として、スケーリングせず単純に EC2 インスタンスを増やすのと比較して、ECS Cluster Auto Scaling を使いスケーリングすることにより 毎月912USD (約140,000円) 最適化できました。

次の条件を前提に料金を見積もった結果が以下になります。

  • インスタンスタイプ: r6i.xlarge
  • 料金モデル: オンデマンド
  • リージョン: アジアパシフィック (東京) (ap-northeast-1)
  • 1日のうち大量のジョブを捌きたい時間は4時間
USD/30days
スケーリングする場合 1276.8 (USD)
スケーリングしない場合 2188.8 (USD)

終わりに

以上のように、ECS で実行するバッチ処理を ECS Cluster Auto Scaling を使ってコスト最適化の取り組みを進めました。

ECS Cluster Auto Scaling 自体は2019年発表3と最近発表されたものではありませんが、社内にナレッジがなかったため調査・検証から行わなければならず苦労しました。

今後の課題として、インスタンスタイプやネットワークなど、他に改善できる箇所を検討し、ナレッジを蓄積していきたいです。

参考


  1. The maximum value is 120 seconds. https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html#container_definitions

  2. Amazon ECS のタスクの停止タイムアウトは、希望すれば何年も待機するように設定できますが、EC2 のドレイン期間は 48 時間を超えることはできません。したがって、タスク停止タイムアウトを 48 時間以上に設定することはお勧めできません。 https://aws.amazon.com/jp/blogs/news/amazon-ecs-enables-easier-ec2-capacity-management-with-managed-instance-draining/

  3. Amazon ECS Cluster Auto Scaling が利用可能に