こんにちは。InflearnとRallitを運営しているInflabのDevOpsエンジニア、Jakeです。
AWS re:Invent 2023で、amazon.comのCTOであるWerner Vogels博士の基調講演がありました。
クラウドプロバイダーのCTOとしては異例なことに、倹約的な(Frugal)アーキテクチャについて言及されていました。
それだけ今は、企業の売上と並んで、コスト(あるいは売上原価)という制約条件を抜きにしては語れない時代になったということです。
特に、スタートアップがよく経験する冬の時代のような厳しい時期には、こうした悩みがさらに深くなります。
私のように、クラウドの利用明細書や請求書を見るたびに驚いている方のためにこの記事を用意しました。
本記事では、スタートアップを前提に、AWSを安く効率的に使うためのさまざまなコスト最適化のノウハウを共有します。
手軽な節約のコツから、それをチームの文化として根付かせるための取り組みまでをご紹介します。
結論から申し上げると、InflabのDevOpsチームは、以下のFinOps関連の取り組みを通じて
- 月間$25,000(ウォン換算で約3,325万ウォン)を節約できました。
- 年間では$300,000(ウォン換算で約3億9,900万ウォン)を節約したことになります。
概要
- チームとして継続的に関心を持つ
- まずTop 10のコストから分割統治する
- リソースのタグ付けが重要な理由
- コストのかさむマネージドサービスに注意する
- EC2スポットインスタンスを積極的に活用する
- MSPを積極的に活用する(そして残念な点)
- サーバーレスの落とし穴にはまらない
- 適正技術を選ぶ
- 速くて安いCDNを積極的に活用する
- 内部サービスの呼び出しには内部ネットワークを使う
チームとして継続的に関心を持つ
どんなコスト最適化も、一朝一夕でできるものではありません。たとえば、一度コストを最適化しても、その後も目を配り続けなければ、より多くの費用が請求されたり、サービス品質に悪影響が出たりすることがあります。
コスト最適化には、チーム全員の努力と継続的な関心が欠かせません。実験を重ねながら、サービスへの影響を最小限に抑えて取り組むよう心がける必要があります。
コスト最適化の状況表を作る
個人の努力だけでは達成が難しい目標なので、簡単なタイトルと節約したコスト、日付を記入したコスト最適化の状況表を作り、メンバー全員の協力を求めました。
コストを節約できる方法をJiraチケットにし、それをドキュメントに添付することで、次の担当者もそのノウハウを参考に改善できるようにしました。
作業が完了したら、節約したコストを試算して表に記入し、担当者を惜しみなく称賛する文化を作りました。また、こうした成果は指標として残り、次のような実績として語れるようになります。
例)2023年上半期の間に、年間1億4千万ウォンに達するAWSクラウドのコストを節約しました。
月別のコスト指標をレビューする
InflabのDevOpsチームでは、毎日ミーティングを行い、スケジュールを管理したり、優先順位に応じてタスクを調整したりしています。
毎月、月末が近づいたタイミングで一度、AWSやDatadogなどのクラウドのコスト指標をレビューする時間を設けました。
前月比で何%増減したのか、その理由は何か、どのような対策で改善できるかを議論し、それをJiraチケットにして担当者をアサインします。
担当者をアサインするのが難しい場合は、上のコスト最適化の状況表の下部に「対応予定の課題リスト」として追加します。
各メンバーは状況に応じて自分を担当者にアサインしたり、手が回らないメンバーのチケットをリバランスしたりします。
備考欄には今すぐ適用できない理由を記入し、次の担当者が優先順位を判断しやすいようにしています。
まずTop 10のコストから分割統治する
クラウドを使っていると、リソースが多すぎて複雑だと感じることがあるのではないでしょうか。
一度に多くのサービスを見ようとすると見落としが生じ、結局重要な手がかりを見逃してしまうことがあります。
そこで、クラウドサービスの中でもコストが最もかかっている上位10サービスから調査しました。
後述するMSPの利用契約を結ぶと、内部規定によりAWS Cost Explorerを使えなくなります。
MSPが提供する別のWebダッシュボードを使うか、Excelファイルをダウンロードして自分で分析する必要があります。
MSPが提供するWebダッシュボードのピボットテーブル機能を使って、簡単に分析してみました。
リソースごとの料金を整理して降順に並べ、使っていないリソースから削除していく形でコストを節約しました。
このときはSteampipeというツールを使い、AWSのリソースをPostgreSQLのクエリで手軽に参照できました。
-
不要なインスタンスを削除
-
オーバープロビジョニングされた(Over-provisioned、プロビジョニング過多)リソースをScale Down
プロビジョニングとは、ユーザーが要求したITリソースを使える状態に準備することを指します。
オーバープロビジョニングとは、必要以上のリソースを使える状態に準備してしまっていることを指します。
Scale downは、リソースのサイズを縮小することです。例えば、「4vCPU 8GiB Memのサーバーを2vCPU 4GiB MemのサーバーにScale-downした」 のように表現できます。
上記の手順を繰り返しながら、段階的にコストを節約することができました。
Amazon Aurora PostgreSQLクラスターの場合
Amazon Auroraクラスターを使っていたため、Scale-Down作業は無停止でスムーズに行えました。
ただし、新しいインスタンスを起動するとクエリキャッシュを活用できないため、一時的にクエリの遅延が発生します。
ユーザーが比較的少ない午前7〜8時ごろに、rolling-out方式で少しずつ作業することで解決しました。
クエリの最適化
スロークエリを分析する方法は、大きく2つに分けられます。
-
スロークエリのSlack通知を送る
-
Datadog Database Monitoring(DBM)を導入する
スロークエリのSlack通知を送る
CloudWatchにRDSのクエリログを蓄積し、Lambda関数でスロークエリを検出したらSlack通知を送ります。
比較的簡単に構成できるので、おすすめの方法です。
Lambda関数は、次のようなクエリを検知するとSlackチャンネルに通知を送るように構成しました。
- 3秒以上実行されたクエリ
- エラーになったクエリ
詳しくは、HyangLoさんが書いた以下の記事が参考になると思います。
Datadog Database Monitoring (DBM)
このほかにも、Datadog DBM(Data Base Monitoring)を構成して、アプリケーションごとによく使われるクエリを分析できます。
こうしたツールを使ってバックエンドチームが定期的にスロークエリを最適化してくれていたおかげで、DBのScale Downもスムーズに行えました。
RDSのRI期間が残っている場合
コスト節約のために以前からRI(Reserved Instances)を購入しており、まだ期間が残っていました。
悩んだ末に、小さいサイズのインスタンスを複数台起動する戦略を取りました。
Aurora PostgreSQLのRIは、インスタンスのサイズ・台数に関係なく、使用する容量を予約するという考え方だからです。
例: r6i.4xlargeインスタンス1台の1年契約 -> r6i.2xlargeインスタンス2台で代替可能
今後、RIの契約期間が満了したら、1台ずつ減らしながらScale-In作業を進める予定です。
リソースのタグ付けが重要な理由
リソースのタグ付けをきちんとしていなくても、基本的なリソースのコストは把握できます。
では、会社で運営しているサービスごと、プロダクトごと、部署ごとにコストを把握するにはどうすればよいでしょうか?
アカウントを複数に分け、アカウント単位でコストを把握している方も多いと思います。
それでも、1つのアカウントで複数のプロダクトやサービスを運営することもあるので、それぞれにきちんとタグ付けしておくことが重要です。
一部のMSPでは、独自のコストダッシュボードで確認できるタグの名前があらかじめ決められている場合があります。
リソースのタグ付けポリシーの策定を計画している方は、事前にMSP側に問い合わせておくことをおすすめします。
そうしないと、もう一度変更しなければならなくなることがあります。(涙)
コストのかさむマネージドサービスに注意する
事例1)AWS Elemental MediaConvert
Inflabは学習プラットフォームInflearnを運営しており、講師の方々の動画のトランスコードには、マネージドサービスであるAWS Elemental MediaConvertを使っていました。
画像出典: AWS
-
AWS Elemental MediaConvertとは?
- マネージド型の動画トランスコーダーサービス
- 複雑な設定やインフラを管理する必要なく、S3とLambdaを使ってトランスコーディングパイプラインを構築可能
サービス初期は、講座のストリーミングサービスを短期間で構築することが最大の目標でした。MediaConvertを使うことで、速く堅牢に構築でき、AWSのノウハウも得られました。
AWS Solutions Libraryで紹介されているVideo on Demand on AWSの事例をもとに、CloudFormationとAWS CDKを活用してVODストリーミングサービスを安定して運用してきました。
幸いなことにサービスが急速に成長し、毎月より多くの講座がリリースされるようになりました。
講座が増えるほどエンコードすべき動画が増え、コストが無視できないほど大きくなりました。
講座の提出が多い月には、すべてのEC2サーバーの費用を合計した金額に匹敵するほどのコストがかかったことも(!!)ありました。
また、MediaConvertでコストを抑えるには、最低1年単位でReserved QueueやReserved Transcode Slotsの料金を支払う必要があり、これが負担でした。Inflearnというプラットフォームの性質上、講座の提出がいつ増え、いつ減るのかを予測しにくいからです。
さらに、AI音声認識モデルを使った自動字幕生成が新機能の要件として検討されるようになり、動画のトランスコーディングとSTTの処理を柔軟に連携させる必要が出てきました。
そこで悩んだ末に、既存の動画トランスコーディングパイプラインを改修し、MediaConvertを使わずに自前で構築することにしました。
この作業は同僚のDevOpsエンジニアであるSunBさんが担当してくれました。ここではコスト節約の観点から簡単にご紹介します。
-
AS-IS(既存): Amazon S3, Lambda, Elemental MediaConvert -
TO-BE(変更後): Amazon S3, Lambda, Batch, ECS, EC2, Go + ffmpeg
AWS Batchを使うと、トランスコーディングや字幕生成のジョブが始まったときに、必要な分だけサーバーを割り当てられます。設定次第で、CPUコアの多いサーバーでトランスコーディングをできるだけ速く終わらせることも、コスト効率の良いサーバーで最適なコストに抑えることもできます。
AWS Batchでは、Amazon ECSと同様に、バッチジョブの実行で発生したコンピューティングコストのみが請求されます。
動画のトランスコーディングには ffmpeg を使い、最適なコマンドを見つけるために試行錯誤しました。また、コマンドを実行するGoのコードを書いてコンテナ化し、ECSで実行するように構成しました。
さらに、複数のジョブをつなぎ、音声抽出のステップでは比較的低スペックのサーバーを使います。
STT(Speech-To-Text)モデルの実行には、GPUを搭載したサーバーを使います。
そして、動画トランスコーディングのステップでは、CPUコア数の多いCクラスのEC2インスタンスタイプを使うように指定しました。
その結果、適切なサイズのインスタンスを必要な分だけ、要件に合わせてカスタマイズして使えるようになりました。
字幕生成機能が加わり、高価なことで知られるGPUサーバーを使っているにもかかわらず、従来比で15〜20倍近くのコストを節約できました。
バッチジョブの場合、後述するEC2スポットインスタンスを活用すると、オンデマンドインスタンスと比べて最大70%〜90%のコストを節約できます。上記の数値は、スポットインスタンスを使って達成できたものです。
サービスを素早くリリースするためにコア機能をマネージドサービスで運用してきたのであれば、self-hostedに移行した場合にどれだけコストを節約できるか、検討してみてはいかがでしょうか?
事例2)CircleCIの代わりにJenkins
Inflabでは、CI/CDパイプラインの代表的なSaaSとしてよく知られているCircleCIを使ってきました。
ただ、SaaSという性質上、実行環境をカスタマイズしにくいうえに、機密情報の流出問題や頻繁な障害がサービスの開発サイクルに影響していました。
CircleCIで障害が発生すると開発チーム全体のビルドが動かなくなり、リリースサイクルに影響が出ていました。
また、問題が起きたときに自分たちの手で直せたらいいのに、という声もチーム内にありました。
原因を自分たちでコントロールでき、解決する過程でノウハウも蓄積できますからね。
そこで、JenkinsのMaster-SlaveアーキテクチャをEC2上に自前で構築して使っています。
先に結論を申し上げると、CircleCIからJenkinsに移行したことで、最大4.5倍のコストを節約できました。
オフィスに開発チーム共用のビルドマシンを置いて使う方法もありますが、なぜAWSクラウド上にJenkinsのパイプラインを構築したのでしょうか?
それは、業務時間やリリースサイクルに応じてビルドが集中するピークタイムに柔軟に対応するためです。
EC2インスタンスが必要になれば、1〜2分以内に必要なサーバーを増やしてビルドを実行できます。
ビルドが終わったあとは15分ほど次のビルドを待ってからインスタンスを終了するようにし、ビルドキャッシュを最大限活用できるようにしました。
Jenkins EC2 Fleet Pluginを使うと、EC2スポットインスタンスを簡単にJenkinsのビルドエージェントとして活用できます。
オンデマンド(On-Demand)インスタンスでJenkinsを構築している方がいれば、このプラグインの導入をおすすめします。CI/CDに使うEC2のコストを最大70%〜90%まで節約できます。
ビルド中にスポットインスタンスの中断通知(Spot Instance Interruption Notice)が発生すると、自動的にビルドを再実行する機能もあります。ぜひ一度使ってみてください。
EC2スポットインスタンスを積極的に活用する
上の2つの事例は、SaaSやマネージドサービスを自前で構築・管理することで、それぞれ最大20倍、4.5倍のコストを節約したケースです。
どちらもコンピューティングリソースを使うバッチ的な処理だったため、EC2スポットインスタンスを導入してさらにコストを節約できました。
EC2スポットインスタンスは、オンデマンドインスタンスと対になる概念です。
オンデマンドインスタンスは好きなタイミングで起動・終了できます。一方、スポットインスタンスは需要に応じてリソースが回収されることがある代わりに、オンデマンドインスタンスと比べてコストを最大70%〜90%まで節約できます。
この特性をうまく活かせば、CI/CDパイプラインや動画トランスコーディングのようなバッチ処理から、ステートレスなWebアプリケーションまで幅広く適用してコストを節約できます。
MSPを積極的に活用する
皆さんは、AWSアカウントの支払いをどのような方法で行っていますか?
私は学生のころ、無料利用枠を使うためにAWSアカウントに直接デビットカードを登録して使っていたことがあります。
個人で使うのであれば、AWSアカウントの支払い手段を自分で管理するのもよいと思いますが、MSPの担当者の方によると、アーリーステージのスタートアップの多くが支払いアカウントを自分で管理しているそうです。
以前は、税金計算書を発行してくれることがMSPのメリットの1つでした。ただし2020年12月からは、税金設定のページで事業者登録番号を入力すれば付加価値税が請求されず、税金計算書またはクレジットカードの売上伝票を発行してもらえるそうです。参考にしてください。リンク
2020年12月1日以降、AWS Koreaは韓国のアカウントのすべてのクラウドサービスについて、税金計算書またはクレジットカードの売上伝票を発行します。
MSP(Managed Service Provider)と利用契約を結ぶと、さまざまなメリットがあります。
- さまざまな料金割引の特典
-
税金計算書の発行(一般の顧客にもAWSが提供) - PoC(Proof of Concept)のためのクレジットの付与
- スタートアップ向けのクレジットを提供
- (Google Cloud Platformにも、スタートアップを支援する同様のプログラムがあります。)
- コンサルティング、インフラ管理の委託など
- AWSサポートプラン(support plan)を購入すると、Amazonのソリューションアーキテクト(solutions architect)の方々と技術的な議論をしたり、フィードバックを受けたりできます。
- 追加の技術サポート
- AWSサポートセンターとは別にMSP独自の技術サポート部門がある場合は、そちらからも追加のサポートを受けられます。
- MSPによっては、AWSサポートプランとは別に独自のMSPサポートプランを販売していることもあります。
よく知られている企業としては、Megazone Cloud、Bespin Global、SK Telecom、GS Neotekなどがあります。
スタートアップを対象としたプロモーションを積極的に行っている企業もあるので、よく調べてみることをおすすめします。
AWS以外にも、GCP、Azure、Datadogなど複数のサービスを扱っているMSPが多くあります。
コミットメント割引の特典やPoCクレジットの付与など、さまざまな特典があります。
RI/SPの購入を検討する
MSPと利用契約を結ぶメリットの1つは、顧客の立場でコスト節約を支援するために、追加の割引特典を用意してくれることです。
そのために、今使っているリソースのコストを最適化する方法を提案してくれることもあります。
Reserved Instances(リザーブドインスタンス)
-
RDS、EC2、ElastiCache(Redis)など
-
インスタンス単位で利用期間(1年、3年)をコミット
-
全額前払い、一部前払い、前払いなしなど、支払い方法によって適用される割引率が変わります。
-
EC2、Fargateなど
-
例)毎月最低$1,000〜$2,000程度は使います!というコミット契約
-
RIと同程度か、やや低い割引率
-
インスタンスタイプの変更時に制約を受けないため、柔軟にインフラを構成可能
本来は、直近の使用量やワークロード、利用パターンを自分で分析して、コスト節約のための最善の戦略を立てる必要があります。ただ、MSPの担当者の方々に依頼すれば、各組織に合った方法を提案してくれるでしょう。
これをうまく活用すれば、需要が安定しているEC2インスタンスを1年単位でコミットして追加の割引を受けたり、リソースの制約なしに金額単位でコミットできるSavings Plansについて、適正な金額を提案してもらったりできます。
コスト最適化の提案はいずれも直近の使用量を分析したうえで出してくれるので、ぜひ依頼してみてください。
RI/SPの契約によって、固定的なサーバーコストを約10%〜30%まで節約できます。
CFRC契約を利用したトラフィックコストの節約
Amazon CloudFrontを使っている方なら、CFRC(CloudFront Reserved Capacity)について聞いたことがあるでしょう。
EC2、RDSのRI(リザーブドインスタンス)と同じように、一種の割引契約によってトラフィックコストを節約できます。
月間10TB以上のトラフィックを使用している場合は、CFRC契約を結ぶことができます。
CFRCを契約したうえでデータトラフィックをCloudFrontに寄せれば、AWS Data Transferで発生する料金を最小限に抑えられ、トラフィックコストをさらに節約できます。
なお、Bespin GlobalのOpsNowでCFRCについて詳しく説明している記事があるので、あわせて参考にしてみてください。
MSPを使う際に考慮すべき点
MSPを使うとメリットもありますが、明確なデメリットもあります。
先ほど、MSPを使うとAWS Cost Explorerの機能を使えなくなるとお伝えしました。
そのため、コストダッシュボードの機能が充実しているMSPを選ぶことをおすすめします。
十分な期間PoCを行って実際に使い、皆さんの仕事の進め方や組織が求める情報を、必要なタイミングで必要な場所に届けてくれるかを確かめてみてください。
特に、超過コストの発生や異常検知の機能が提供されているかを確認してみてください。
- 大量のデータ分析などの作業でコンピューティングリソースを使ったあと、停止し忘れた場合
- ハッキングなどでアカウントが乗っ取られ、急激にコストが発生した場合
こうした場合にメールなどで知らせてくれる機能は、AWS Cost Explorerでは標準で提供されていますが、MSPのコストダッシュボードにはない場合があるので注意が必要です。
すでにMSPを使っている方も、この通知機能があるか、オフになっていないかを確認してみてください。作業が終わったのにうっかりリソースを停止し忘れて、余計なコストが発生するのを防げます。
サーバーレスの落とし穴にはまらない
David Heinemeier Hansson氏が書いた「サーバーレスに騙されないで」という記事がGeekNewsで紹介されました。#1
内容をまとめると、次のとおりです。
- たまに実行されるいくつかの機能だけが必要なら、サーバーレスを使うのも悪くない。
- ただし、24時間実行し続ける必要があり、フルのコンピューティング機能を必要とするワークロードには、サーバーレスは適していない。
- サーバーレスでクラウドネイティブなサービスを使えば使うほど、ベンダーロックイン(vendor-lock-in)に陥りやすい。
この記事のとおり、サーバーレスはメリットが大きい場合に限って導入することをおすすめします。
私たちの事例もいくつかあるので、簡単にご紹介します。
Amazon Aurora Serverless v2
Amazon Aurora Serverless v2は、データベースを毎秒数十万件のトランザクションをサポートする規模まで即座にスケールでき、マルチAZ配置、読み取り専用レプリカ、Global DatabaseといったAuroraのすべての機能をサポートします。
テスト環境や社内向けのDBには、t3.mediumタイプのインスタンスを使ってきました。
普段は使用量が少ないものの、ときどきユーザーが増えるとCPU使用率がスパイクすることがありました。そこで、当時リリースされて間もなかったAurora Serverless v2に置き換えました。
結論から言うと、テスト環境や社内ツールの用途には、Aurora Serverlessよりもt3.mediumやt4g.mediumのほうが適しています。
テスト環境などにAurora Serverless v2を適用した結果、1台あたり$70〜$220ほどの料金がかかりました。
これを見て、あえてAZ間のレプリケーションをする必要がない場合は、Aurora ServerlessよりもRDS PostgreSQLのt4g.mediumタイプのほうが適していると判断しました。
Aurora Serverlessは、事実上サーバーレスではありません。最小容量が0.5 ACUに固定されているため、使っていないときにも最低料金が発生するからです。
クエリが急増するような負荷が予測できない場合には、Aurora Serverlessを導入するのがよいでしょう。
テスト環境や社内ツール用のデータベースの場合、クエリ数が一定の水準を超えないのであれば、tシリーズのインスタンスを使ってRI(リザーブドインスタンス)を購入するのが合理的です。
AWS Fargate
Inflabはサービス初期にWordPressで始まり、2019年からはAWSのサーバーレスコンテナプラットフォームであるFargateを、ECS(Elastic Container Service)上で使ってきました。
次のようなメリットがあるため、アーリーステージのスタートアップに適したソリューションとしてよく挙げられます。
- インフラではなくアプリケーションを管理
- アプリケーションをモニタリングして指標とインサイトを得る
- マネージドサービス
- Amazonのセキュリティ技術のノウハウをそのまま適用
- Amazonのコンテナ管理のノウハウをそのまま適用
おかげで、エンジニア1人でも会員数が数十万人になるまで、安定してサービスを運用することができました。
EC2インスタンスやLinux環境の設定から解放され、空いた時間でアプリケーションコードの実装に集中できました。
しかし、DevOpsエンジニア4名とインターン2名がいる現在では、Fargateのメリットよりもデメリットのほうが目立つようになってきました。
エンジニアが増え、サーバーを自分たちで十分に管理できる体制が整いました。
サービスの規模もともに成長し、以前より多くのトラフィックを処理しなければならない状況になりました。
Fargateにはいくつかの制約があります。
-
コンテナにアクセスできない
- ときどき、実行中のコンテナにアクセスして原因を調べなければならないことがあります。
- AWS Systems Managerを事前に設定しておかないと、コンテナにアクセスできません。(SSH非対応)
-
provisioned権限が使えない
- セキュリティ上の理由から、AmazonはHostのprovisioned権限を付与していません。
- そのため、Fargate上でDockerのビルドを実行したり、s3fsのような仮想ドライブをマウントしたりといった特殊な作業を行うことができません。
-
カーネルパラメータを変更できない
- Linuxカーネルのパラメータチューニングなどによるパフォーマンス最適化を行うことができません。
- 2023年8月からカーネルパラメータの設定をサポートしています。
- ただ、このオプションを設定しても、アプリケーションでソケット不足が起きてしまうのは残念でした。
-
EC2との性能差
- 外部の資料では、Fargateは同じスペックのEC2インスタンスと比べて演算性能が劣るという結果が出ています。
-
デプロイにかかる時間
- EC2を使う場合と比べると、コンテナのプロビジョニングにかかる時間が少し長くなります。
- Fargate: 1分15秒
- EC2: 39秒
- 再デプロイが必要な場合、EC2はサーバーに残っているイメージキャッシュを活用できますが、Fargateはそうではありません。コンテナのプロビジョニングをやり直す必要があるため、より長い時間がかかります。
FargateのコストをEC2と比べてみると(2vCPU、4GiB Memの場合)
- Fargate: 81.76 USD
- EC2(
c7i.large): 73.584 USD - Fargateは同じサイズのEC2と比べて、10%多くコストがかかります。
c7i系のEC2インスタンスのほうがスペックが高いうえ、1台のEC2インスタンスで複数のコンテナを動かすことも考えると、EC2のほうがコストパフォーマンスに優れています。
チームが十分にサーバーを管理できる場合は、コスト面でも性能面でも、EC2で構成したクラスターを自分たちで運用するほうが合理的だと判断しました。
その後、FargateのコンテナをすべてEC2で動かす作業に取り組んでおり、これによってコストも最適化できました。
Fargateを使っていたころは、月3000ドルほどのコストがかかっていました。
オーバープロビジョニングされたコンテナに割り当てるリソースを減らすScale-Down作業と、Fargate -> EC2への移行作業を同時に進めました。
その結果、月間約1500ドルのコストを節約しながら、安定してサービスを運用することができました。
機会があれば、稼働中のECS + Fargateのサービスを無停止でEC2に移行する方法について、技術ブログに書いてみたいと思います。
もちろんこれは、組織が成長してチームが大きくなり、サービスの利用規模も拡大した段階での話です。
小規模なチームや、サーバーを自分たちで管理するのが難しい場合には、ECS + Fargateは本当に良い組み合わせだと思います。
適正技術を選ぶ
皆さんは、適正なアーキテクチャと聞いて何が最初に思い浮かびますか?
私たちの場合は、まずマイクロサービスアーキテクチャが思い浮かびます。
これを構築しようとすると、サービスディスカバリーやIstioプロキシから、Prometheus、Kubernetesクラスター、詳細な分析ができるAPMまで、扱うツールが一気に増えます。
サービスが複数に分かれることで、追加のサーバーリソースが必要になることもあります。
これらを使いこなすには、かなり高い技術力と、時間的・金銭的なコストが必要です。
日々増えるトラフィックに既存のアーキテクチャがもう耐えられない、という状況でないのなら、今のビジネスに集中することをおすすめします。
私たちの組織では、次のように適正技術を選んできました。
- 韓国語の検索エンジンとして、Elasticsearchの代わりにMongoDB Atlasを選択(運用・管理コストの削減)
- すぐにマイクロサービスを導入する代わりに、複数のモノリスアプリケーションを運用(インフラの運用・管理コストを削減)
組織に合った適正技術を見つけ、それをうまく活用することから始めれば、より効果的にコストを節約できると考えています。
速くて安いCDNを積極的に活用する
画像や動画のような静的なメディアコンテンツを配信するスタートアップであれば、CDN(Content Delivery Network)の活用は必須です。
キャッシュによってS3やWebサーバーなどのオリジン(origin)への繰り返しのリクエストを減らせるので、コストを節約しつつサービス品質も改善できます。
Inflabでは、CDNとしてAmazon CloudFrontを使い、S3やApplication Load Balancer、Lambda Function URLなどのリソースと連携させています。
最近は、ユーザー詳細ページや受講レビューのページ、OG画像のような動的コンテンツにもCDNキャッシュを適用しています。
Next.jsのSSR(Server-Side Rendering)のレスポンスをCDNで短時間キャッシュして、トラフィックのスパイクを最小限に抑えることもあります。
例えば、レスポンスに1秒かかるユーザー詳細ページがあると仮定してみましょう。ユーザー詳細ページの情報が頻繁に変わらないのであれば、動的キャッシュ(Dynamic Caching)の導入を検討できます。
サーバーの Cache-Control レスポンスヘッダーを次のように変更します。
動的に変わるページは、private, no-cache などのオプションでCDNにキャッシュさせないように設定するのが一般的ですが、上の画像のように Cache-Control レスポンスヘッダーを変更して、動的キャッシュを有効にしました。
すると、最初にCDNにキャッシュがないときだけサーバーにリクエストが送られ、1秒かかることになります。
CDNではそのレスポンスをキャッシュするので、それ以降のリクエストには0.01〜0.1秒前後で応答できます。
この状態は、CDNのキャッシュが期限切れになるまで続きます。
実際のサーバーのスペックが低かったり、コードの処理性能が良くなかったりしても、CDNでキャッシュされたレスポンスを受け取るユーザーは、快適にサービスを利用できるでしょう。
ただし、ユーザーごとに異なる情報を表示する必要があるページでは、動的キャッシュを使う際に注意が必要です。
セッションCookieやJWTトークンごとに区別してキャッシュするようにキャッシュキー(Cache Key)を設定すれば、パーソナライズされたコンテンツも動的にキャッシュできます。
また、データの変更が頻繁で、常に最新のレスポンスを返す必要がある場合は、動的コンテンツのキャッシュを適用するのが難しいこともあります。
public, s-maxage=60, stale-while-revalidate=59オプションについて、ChatGPTに説明してもらいました。
- このレスポンスはパブリックにキャッシュでき、共有キャッシュ(s-maxage)では60秒間有効です。
- 上記の時間が過ぎたあとも、最大59秒間は、再検証(revalidation)が行われている間も既存のキャッシュされた内容を提供できます。
- これにより、ユーザーはコンテンツをより速く読み込めるようになり、同時にサーバーは新しいコンテンツへの更新を準備する時間を確保できます。
動的キャッシュを利用してCDNで一定時間データを保持することで、サーバーへの負荷を減らし、ユーザーにはページを速く表示できます。
コスト面でも、サーバーの負荷が下がれば必要なサーバーリソースが少なくて済むため、コスト効率が高まります。
例えば、Next.jsのサーバーが1秒に100件のリクエストを処理できるとしても、CDNでキャッシュすれば、ほぼ無限大に近いスループットでユーザーのリクエストに応答できます。頻繁にリクエストされるページがあるはずですからね。
CDNサービスは規模の経済によって数多くのEdgeキャッシュサーバーを運用し、使った分だけ課金します。
CDNを最大限うまく活用することが、サーバーコストを節約する近道です。
グローバルなユーザーを対象にサービスを提供する場合、CDNを活用すれば地域によるレイテンシー(latency)を大きく減らせます。
各地域に分散したCDNノードがユーザーに最も近い場所からコンテンツを提供するため、ユーザーは世界中どこからでも、地域的なネットワーク遅延なしに高速でWebサイトにアクセスできるようになります。
実装時の細かい点をいくつか補足すると、キャッシュポリシーの設定には注意が必要です。(上で説明した cache-control オプション、CloudFront Cache Policyなど)
コンテンツの更新サイクルや重要度に応じて、適切なキャッシュの有効期限(TTL、Time To Live)を設定する必要があります。
ユーザーのリクエストに応じてキャッシュを無効化したり更新したりする仕組みも考慮する必要があります。
セキュリティの面でも、CDNのメリットは大きいです。
ほとんどのCDNサービスは、DDoS攻撃の防御やSSL/TLSのような暗号化プロトコルなどのセキュリティ機能を提供しており、データの安全性を高め、セキュリティ上の脅威からWebサイトを守ることができます。
このようにさまざまなメリットを考えると、CDNは単なるコンテンツ配信ネットワークにとどまらず、ユーザー体験を向上させ、ビジネスのコストを削減するうえで重要な役割を果たします。
Webサービスのパフォーマンスを向上させ、コストを削減したいのであれば、積極的なCDNの導入と最適化の戦略を検討してみるとよいでしょう。
本当に使わない理由がありません。ぜひ一度導入してみてください。
内部サービスの呼び出しには内部ネットワークを使う
ユーザーのリクエストにサーバーが応答する際には、サーバー同士の通信も必要になります。
サービスの規模が大きくなるほど、サーバー間の呼び出しに使われるトラフィックの規模も比例して大きくなるでしょう。
AWS Well-Architected FrameworkやAWS VPCガイドでは、内部のサーバー間の通信はできるだけプライベートサブネット(Private Subnet)で行うことが推奨されています。
もし開発者のミスで、内部IPを指すドメインではなく、パブリックIPを指すドメインを使って通信したらどうなるでしょうか?
-
ルーティングポリシーに従って、パブリックサブネットにあるNAT(Network Address Translation、ネットワークアドレス変換)ゲートウェイまたはインターネットゲートウェイを通り、外部のルーターを経由することになります。
-
送信元IPがNATゲートウェイのIPになり、外部のルーターを経由するためレイテンシーが大きくなります。
-
コストもより多く支払う必要があります。外部ネットワークへの送信トラフィックとして、追加料金がかかります。
AWSでは同じアベイラビリティーゾーン(AZ)内のトラフィックには料金がかからないため、内部IPを指すドメインにリクエストを送ることでネットワークコストを節約できます。
まとめると、次のとおりです。
-
内部サービス間の呼び出しには、内部IP(プライベートサブネットのIP帯域)を使う
-
internet-facingではなくinternalのLoad Balancerを使う - ALB、S3、PrivateLinkを使った内部用(internal)HTTPS静的Webサイトのホスティング
-
-
-> 不要なレイテンシー & トラフィックコストの削減
パブリックネットワークに公開しつつ、プライベートサブネット(private subnet)からもアクセスする必要がある場合は、次のように2つのロードバランサーを構築することをおすすめします。
Amazon ECSの複数ロードバランサー接続機能を使って、内部(internal)・外部(external)のサービスエンドポイントを同じDNS名で使う方法(AWSブログ)も参考になると思います。
S3、SNSなどのAWSサービスを呼び出すときも例外ではありません。
別途VPCエンドポイントを設定しないと、AWSサービスを呼び出す際にNATやインターネットゲートウェイを経由します。パブリックネットワークを経由するため、追加のトラフィックコストが発生してしまいます。
インターフェイスVPCエンドポイントを使用してAWSサービスにアクセスするのドキュメントを参考に、VPCエンドポイントを作成できます。
これにより、AWSサービスをプライベートIPで呼び出せるようになり、トラフィックコストを削減できます。
ただし、1時間あたりの料金やデータ処理料金が請求される場合があるので、導入するかどうかはよく検討してください。
-
Amazon S3用のゲートウェイエンドポイントは無料で利用できます。
-
同じAWSリージョン内で、Amazon S3、DynamoDB、SES、SNS、SQS、Kinesis、ECR、SimpleDBとEC2インスタンスの間で直接転送されるデータは無料です。
-
ほかのAWSサービスがデータ転送経路上にある場合は、関連するデータ処理料金がかかります。
同じAWSリージョン内のデータ転送について詳しくは、AWSのドキュメントを参照してください。
おわりに
ここまで、スタートアップのDevOpsエンジニアの立場から、AWSクラウドのコストを節約した経験についてご紹介しました。
InflabのDevOpsチームは、月間$25,000(ウォン換算で約3,325万ウォン)を節約できました。
年間では$300,000(ウォン換算で約3億9,900万ウォン)を節約したことになります。
AWSクラウドのコスト最適化は、スタートアップや中小企業だけでなく、すべてのAWSユーザーにとって重要な課題です。
上で共有したさまざまな戦略はあくまで出発点にすぎず、各組織の具体的な状況や要件に合わせて微調整する必要があります。
AWSのコスト最適化は、一度で終わるものではありません。継続的な関心と改善によって、コスト効率とサービスのパフォーマンスのバランスを取りながら成長していけるはずです。
こうしたノウハウが、皆さんのAWSコスト最適化の取り組みに役立てば幸いです。
長い記事を読んでいただき、ありがとうございました。
※この記事は2024年2月27日に執筆されたものです。


















