はじめに
こんにちは。ニフティに新卒で入社して多分6年目の佐々木です。今回はAWSのサービスの一つであるEC2についてコスト削減を行う方法を紹介します。
以前ご紹介したコスト削減手法ついては、以下のブログ記事をご参考ください。
背景
ニフティではサービス基盤にAWSを活用しており、コスト削減のためにサービスのインフラ効率を追求する取り組みや、有志で取り組んでいる社内でのコスト削減勉強会なども実施しています。
今回は、EC2のコスト削減においてのポイントや注意点について簡単にご紹介したいと思います。
この記事の内容
- 触れること
- EC2のコスト削減方法
- EC2のコストを削減する上での注意点
- 実際に試した社内でのコスト削減事例とTips
- 触れないこと
- EC2自体の詳細の説明
- 詳細のインフラ構成(コスト削減が目的のため、今回は一般的なインフラ構成のご紹介に限らせていただきます)
EC2の基本
EC2(Amazon Elastic Compute Cloud)は言わずとしれたAWSの代表的なサービスです。
必要に応じて容易にサーバーの追加・削除が行える仮想サーバーの役割を果たしています。
EC2のコスト削減
課金形態
さっそくEC2のコストを確認していきましょう。
2024年4月現在では主に以下のようになっています。(ap-northeast-1の場合で無料利用枠は除きます)
EC2自体の主な課金要素は最低限この3つを押さえておけば問題ないかと思います。(他にも様々な細かい課金要素はあります)
インスタンスタイプ
- 利用するEC2のインスタンスタイプにより課金される金額が変わります
- 例えば、t3.microの場合は毎時0.0104USDの課金が発生します
データ転送
- 「送信(アウト)」に対して課金が発生します。受信(イン)には課金されません
- 例えば、最初の 10 TB/月の場合はUSD 0.114/GBの課金が発生します
料金プランによる課金形態
- 後述するEC2の料金プランを選択することで様々な割引を受けることができます
詳細はこちらのAWS公式の資料をご参考ください。
コスト削減方法
インスタンスタイプの見直し
当然ですが、どの場合においてもサービスの要件を満たす最低限のスペックのインスタンスであればコストを最小限に抑えることができます。
こちらは後述する「インスタンスサイズの見直し」の項で実際の削減例を交えて詳しく紹介しようと思います。
インスタンスのリソースの増減を考慮する
こちらは起動しているインスタンスの数を状況に応じて変更することでコストを抑える方法です。
実際の稼働しているサービスによっては、繁忙期の利用増加や時間帯ごとの需要の変化などが生じる場合があると思います。そのような場合はピークの時間帯に備えて常にフルでサーバーを稼働しておく必要がない場合もあります。
そのような場合は、Auto Scalingを組むことで正常なインスタンスの数を維持しつつトラフィックの増減に合わせてサーバー台数を自動で変化させることができます。また、時間台によって起動させるサーバーの台数を予め指定することもできます。
また別の要因として、開発環境であればそもそも利用する時間帯が限られているかと思います。そちらの場合には、夜間休日にインスタンスを自動停止するようなスクリプトを組むことで無駄なコストの発生を抑えることができます(塵も積もれば山となる…)。
EC2インスタンスの自動停止・起動方法については、Lambda関数を活用して組むことができます。
https://repost.aws/ja/knowledge-center/start-stop-lambda-eventbridge
EC2の料金プランによる費用最適化
課金形態の3つ目「料金プランによる課金形態」にあたります
EC2にはいくつか料金プランがあり、特定の条件下で利用することでサービスの料金が割引になる仕組みが存在します。
Amazon EC2 オンデマンド
- 従量課金制の料金形態
- デフォルトでインスタンスを立てると通常この費用が発生する
Amazon EC2 リザーブドインスタンス(RI)
- 「一定期間の継続」を契約することで大幅な割引(最大72%)ができる料金形態
- 1年間または3年間の期間存在する、当然3年間の方が割引率は高い
- 「キャパシティの予約」という形で契約を行うことで、任意のインスタンスタイプのEC2インスタンスを予約期間中は自由に起動できるようになる
- 2つのプランが提供されている
- スタンダードRI:
- 特定のインスタンスタイプについての割引が受けられるプラン
- 割引率は高いが原則途中で変更はできない
- コンバーチブルRI:
- インスタンスファミリー・インスタンスタイプ・プラットフォームなどの変更が可能なプラン
- 割引率はスタンダードRIに比べると低。
- ただし元のコンバーチブルRIと同等価格以上のインスタンスタイプでなければ交換することができない
- スタンダードRI:
- 1年間または3年間の期間存在する、当然3年間の方が割引率が高い
- 3種類の前払いの支払いオプションが提供されている
- 全額前払い
- 一部前払い
- 前払いなし
- 常に稼働させておく必要があるシステムの場合に有用
Savings Plans
- 「一定期間の継続、一定量の使用」を契約することで大幅な割引(最大72%)ができる料金形態
- 「コミットメント額 = SPの料金として支払う額」という形で契約を行うことで、使用量に対する割引が受けられるようになる
- リザーブドインスタンスと比較して高い柔軟性がある
- 2つのプランが提供されている
- Compute Savings Plans
- 割引率はやや低いが柔軟性があるプラン
- インスタンスファミリー、サイズ、アベイラビリティーゾーン、リージョン、OSに関わらずEC2インスタンスの使用に自動的に適用される
- EC2 Instance Savings Plans
- 割引率が高いがやや適用条件があるプラン
- アベイラビリティゾーン、インスタンスタイプ、OSに関わらずそのリージョン内で選択されたインスタンスファミリーのコストを削減できる
- Compute Savings Plans
Amazon EC2 スポットインスタンス
- AWS側の空いているキャパシティを活用することで大幅な割引(最大90%)ができる料金形態
- 空きがなくなると中断が発生する可能性があるので、処理が途中であっても中断可能なサービスや機能に適していると言える
結局どう選べば良いのか?
EC2の料金プランは種類も多く条件もやや複雑です…。
なので個人的にはまずはオンデマンドを利用し、実際に少し稼働させてみて想定したスペックで耐えられることが確認できたら、要件に合わせて割引可能なプランの選択を検討する、といった流れが良いのかなと思います。ひとまずは、実際のコンソール画面を見ながら料金プランのイメージを掴めると良さそうです。
また余談として、SP/RIはAWS Organizationの管理アカウント単位で買うこともできるのですが、こちらも残念ながら非常にややこしい仕様となっています…。ただ、上手く活用することで各プロダクトチーム単位で買うよりも大きなメリットがあるので、できれば検討したいところです。
管理アカウントでの購入について以下の記事で詳しく解説しているので、良ければ合わせてご参照ください。
実際に社内で試したこと
インスタンスサイズの見直し
開発環境にあるEC2インスタンスのスペックが過剰なものがあり、そちらの見直しを行いました。
方針
事前にインスタンスタイプについての知識があまりなかったので、いきなり作業に取り掛かる前に以下の方針を立てました。
- 使用量を調べて、全体的にインスタンスタイプを下げても問題ないかを把握する
- CPU使用率を見て上限に張り付いていないかを確認する
- メモリ使用率はCloudWatch Agentを導入しないと把握できないので考慮からは除外
- 同じインスタンスファミリー内で、ベースライン使用率を超えないと思われるスペックを選択する
- 世代が新しいほどコストパフォーマンスが向上する傾向があるため、なるべく最新のインスタンスファミリーを選ぶ
- ただし「汎用バースト型のT系」から「グラフィック処理に特化したG系」にするなどアーキテクチャそのものの変更なので、要件によってそもそも変更不可能な場合がありその点を考慮する
- アプリケーションやミドルウェアの要件によって世代が新しいインスタンスを利用できない可能性がある
- (詳細は割愛しますが、ミドルウェアのバージョンが古いとG系で扱うENAドライバに対応していない場合があり、今回それに該当しているものがありました…)
洗い出し
上記の方針を元に、各インスタンスで変更できそうなスペックの候補を洗い出していきます。
今回はNotion DBを使って以下のような表を作りました。
各インスタンスファミリーの特徴については公式ページを見ながら把握していきます
今回はほぼT系からT系への変更だったこともあるので、T系インスタンスが前提の話になります。
現行スペックと変更後のスペックの対比として今回は以下の項目を考慮に入れています
- 各インスタンスタイプの料金
- vCPU
- CPU使用率(%)
- ベースラインパフォーマンス(%)
前提として、T系インスタンスでは CPU クレジットを絶えず一定の割合で獲得しています。これによりある程度負荷が急増した際にも蓄積されたクレジットを消費することで、ベースラインレベルを超えてCPU使用率をバーストできるという仕様になっています。
「通常はベースラインまで性能を落として上で起動しておいて、緊急時には100%の性能で稼働する」というとっても便利な機能ですね。
また、公式ドキュメントにもありますが、EC2インスタンスではベースライン使用率(ベースラインパフォーマンス)というものが定義されています。「CPUクレジットの獲得数とCPUクレジットの使用率が一致する場合に、正味のクレジットの残高が0の状態でCUPを使用できるレベル」とのことです。つまり「このラインの使用率を超えるといずれクレジットが枯渇するよ、枯渇したらこのレベルまでしか性能を出せないよ」というのを数値化したものだと思われます。
今回のT系インスタンスの場合では、このベースライン使用率を超え始めるとクレジットを消化し始める(=パフォーマンスが悪化する可能性がある)ので、CPU使用率が常にこの値を下回るのであればスペックを下げても問題ないと考えました。
しかし、インスタンスタイプを変更するに当たってもう一つ罠があります…。
簡単に言うと、vCPUとCPU使用率(CloudWatchのコンソール上で見れる数値)には反比例の関係性があるようです。
CPUクレジットの概念の項にもありますが、1クレジットあたりの定義が以下になっています。
1 2 3 |
1 CPU クレジット = 1 vCPU × 100% 使用率 × 1 分 1 CPU クレジット = 1 vCPU × 50% 使用率 × 2 分 1 CPU クレジット = 2 vCPU × 25% 使用率 × 2 分 |
上記の計算式から、今回は「インスタンスタイプを変更してvCPUが半分の値になった場合はCloudWatchメトリクス上で表示されるCPU使用率は倍の値になる」と見積もって計算を行いました。
また、同じくCPUクレジット獲得の項では、「表内のベースライン使用率は vCPU 別の割合です。CloudWatch では、CPU 使用率は vCPU 別に表示されます」とあるので、そう読み取って良さそうです。
またここでは考慮していませんが、実際にはインスタンスの世代による差(新しい世代だとパフォーマンスの部分で改善されていたりする)もあるので、そちらも影響してくると思います。
変更
最後に先ほど決めた変更後のスペックに手動で変えていきます。
今回は開発環境なのでダウンタイムを考慮せずに簡単に変えることができました。
これで削減完了です。
徐々に見直しを行った結果以下のようにEC2の使用量を半分以下に減らすことができました!
Cost Explorer などで実際に削減されているのを見るとモチベーションが上がって嬉しいですね。
まとめ
今回インスタンスタイプの見直しやEC2の割引仕様を調べるにあたっては、ドキュメントから判別がつかない点も多く、実際の事例を参考に多分こういう仕様だろう、という推定をしながらとりあえずやってみる部分がそこそこありました。
一通り各インスタイプの特徴や割引プランを把握しておくことで、実際の運用にも役立てると思うので、まずはドキュメント化などをしつつチーム内での認知不可を下げて、少しずつ社内の共通知にしていきたいなと思っています。
検証環境とはいえ、初めてインスタンスタイプを変えたときはこれでよいのかな?と不安になったので、実際に変更したり買って学べる環境があると良いなと思います。