クラウド使いなエンジニアの皆様、猛暑と円安の中いかがお過ごしですか。上層部からインフラコスト削減を突きつけられてはおりませんでしょうか。
今回はおそらく初めてコスト削減についてAWSを軸に書いていきますが、考え方はどこの環境でも似たりよったりなので何かしらの足しになればと思う次第であります。
目次
長いです。ひきかえしたほうがいいぞ!コミュニティに捧げます
以前、JAWS-UG (AWS Users Group – Japan) からイベントにお誘い頂いたのですが、ライトな内容と時間で話せそうにないことや、リモート生活が染み付いて単に出かけたくないというのもあり、お断りしてしまいました。面白そうなお話をありがとうございます。
— 外道父 | Noko (@GedowFather) November 12, 2022
コストカットについては内容が多すぎて時間内に全く話しきれそうにないのと、勉強会を引退した身として、お断りさせていただきたく思います。
運営、大変でしょうが頑張ってください
その代わりというわけでもないですが、最近またコスト削減をいくつか手掛けて書く気になったので、この記事の提出で単位をいただければと思います:-)
AWSの売上
とりあえず、俺らがどれだけAWSに- Amazon決算、増収黒字転換 AWSの成長は鈍化も生成AIで強化中 – ITmedia NEWS
- 直近四半期の総売上1343.83億ドル、営業利益率5.7%、AWSの総売上比16.48%…アマゾンドットコムの売上推移など(最新) – ガベージニュース
直近四半期で売上 221.40億ドル AWS凄い!って素直に感じてもいいんですけど、今回はそういう場じゃないんで。おまへら、垂れ流しすぎ!そういう方向でいきましょう。多分、全員が頑張ったら、売上3兆円のうち5千億円くらいは削れるっしょマジで。
コスト削減とは
会社の景気が良いときは、各コストにそこまで繊細に気を使われることがなかったりしますが、調子が悪くなったり急激な円安が起きたりすると、まず最初に目をつけられるのが人件費やITインフラ費用となります。売上を急に上げることは難しいですが、既存の実費を削る方が実現性としては確かで、その効果も100万円削れば売上300万円以上に相当するので、わりと定期的に降り掛かってくるミッションとなります。本当はこまめに絞れているといいんですけどね、その塩梅も難しいものです。
ITインフラのコストを下げる方法はいくつもあり、
- リソースの数量を減らす・削除する
- リソースの容量を減らす
- リソースの種類を変える
- リソースの構成を変える
- 課金形態を変える
- 環境を丸ごと引っ越す
- アプリケーションの負荷を減らす
三大使命
インフラエンジニア・SRE という職種における大きな使命は3つあると考え、そのうちの3つ目となります。コスト調整は負荷試験と似た知識を必要としますが、負荷試験は目標値に対して多少の超過を許容する必要リソース量の判断をすることに対し、コスト調整は既存の状態に対する調査と削減判断を求められることになります。システムを最適化し安定性を確保することは共通でも、コスト調整は自らリスクに寄せる性質があることもあり、より繊細な思考とコミュニケーションを要します。
組織内で進めてみると、思ったように進行しないもどかしさに遭遇したりもしますが、まずは実践するための方法論を身に着けないとお話になりません。以下、いっぱいある具体的な内容を可能な限りサクサク感をもって進行していきます(多分無理)
コスト状況整理
まずはどのサービス(EC2, RDSなど)に、どのくらいのコストがかかっているのかを整理していきます。確認は管理画面の Cost Explorer へ遷移し、月別・日別で費用データを表示します。必要があれば表部分を丸ごとコピーし、スプレッドシートや社内Wiki などにペーストして、コスト削減案と共に共有しやすくします。
表示データは『グループ化の条件』と『フィルター』でカスタムします。よく使う例としては、まず【グループ化 → ディメンション → サービス】で全体の費用割合を把握します。
EC2 などの詳細を見たい場合は、【グループ化 → ディメンション → 使用タイプ】と【フィルター → サービス → EC2-Other】でEBSやデータ転送を確認できますので、必要に応じて他サービスも同じように詳細を取得してください。
整理できたら、費用比率が高い箇所や、想定外に多くかかっている箇所に目をつけ、効果が高いもしくは手間が少ないところから手掛けていきます。
それでは以下、具体的な例をあげていきます。
Load Balancer
参考リンク
統合による削減
今は ALB + ACM に、Listener:443 + ListenerRule → TargetGroup が基本構成になっていると思います。他のリソースにも言えることですが、本番環境と、それ以外のステージングや開発環境などが複数存在する場合、放っておくと無駄と言える構成や残骸が増えていくことが多く、その最適化くらいがここでできることになります。
ListenerRule の例としては、HostHeader が xxx の場合に TargetGroup へ、条件一致しない場合 Default で Status 403 を返す。って感じだと思います。その仕組み上、ワイルドカード証明書にマッチする FQDN なら複数の環境を1つの ALB で賄うことができますが、本番以外が本番へ影響を与えたり、本番のメトリクス値とごちゃまぜになることはよろしくないため、普通は本番とそれ以外は分けるべきです。
しかし、開発者個々人が環境を構築する時に、1環境ずつALBを作成してしまうことがあり、気づけば5個10個とALBができていたりします。その場合、本番以外を混在させる1つの ALB を決め(もしくは新しく作り)、ListenerRule で分岐することで共有利用する方針に切り替えます。
ALB は1つあたり最低 $23/月 はかかるので、もし 5つの ALB を1つにまとめられたら、$23 * 4 = $92 は削減できることになります。
EC2 Autoscaling
ここではシンプルにEC2インスタンスを使うイメージで話しますが、コンテナ on EC2 でも、Fargate でも Autoscaling ならほとんど同じ考え方になるので、それらは省略します。参考リンク
- オンデマンドインスタンスの料金 – Amazon EC2 (仮想サーバー) | AWS
- これからはじめる AWS Auto Scaling 2019年版 | 外道父の匠
- AWS CPU C6i/C6a の性能検証 | 外道父の匠
情報整理
以前はいろんなデータを手作業で見に行って色々判断していましたが、そういう作業を何度もしていると自動化したくなるので、ポチるだけで以下のようなデータを出力するスクリプトを作成しました。データは実際に採取したものを公開用に適当に編集済みです。AutoscalingGroup としての基本的な設定、1週間の1時間毎のメトリクスを自動整理し、これを見て削減対象と費用効果をまとめていきます。
古いインスタンスタイプの変更
インスタンスタイプは基本的に新しいほど性能向上+費用減になっているので、同じ 2xlarge にしても c4 や c5 が使用されている場合、(SavingsPlans等の事情がなければ)c6i や c7g に変更してしまった方が安くなります。OS の x86 とarm64 の違いがあるので、イメージ生成を両対応にしてどちらにも切り替えられる方針で運用すると尚良しです。シンプルに新しい方が $/h が安くなる傾向と、そうでない場合でも性能が 20% 上がれば大雑把にその分は台数を 20% 減少できるので、合せ技になると結構なコスト削減となります。しかも、1処理あたりの速度も向上するので、ユーザー体感にまで好影響する可能性もあり、ガンガン最新に入れ替えるスタイルはクラウドならではと言えます。
スケジュールの調整
サービスの性質によって、正午やイベント開始時にトラフィックが集中することがあり、自動増加では追いつかないことを見越して、スケジュールで最低台数を設定して事前に十分な台数を準備することがあります。逆にそうではない時間帯は最低台数を下げて、自動増減に任せてコストを抑えます。自動増減の基準には ScalingPolicies で TargetTracking CPU >= 50% のように設定しますが、サービスを運用していると週・月単位でも盛り上がり下がりがあるので、スケジュールの最小台数を放置しているとCPUリソースが余りやすくなることがあります。平均CPU使用率 50% に遠く届かない状況、ということです。
CPU 50% の意味は、トラフィックが急に 100/50% = 2倍 になってもギリ大丈夫だろう、という数値です(※平均値なので実際はアウトな箇所も出てくる)。CPU 40% なら 2.5倍 までは大丈夫、とより安全圏になるわけですが、余力があるほど無駄なリソースを確保してコストを垂れ流していると言えます。
運用基準として 50% までは OK としたならば、できるだけその近くまでは無駄を絞るべきで、現状の使用リソースとメトリクスに対して最適化することで台数を削減します。さきほどのデータでは、その最適台数を OptimizedSize として自動計算していて、それを元にスケジュールを見直しています。
スポットインスタンスの適用
そもそもスポットの割合を有効にしていない場合は当然ですが、オンデマンドベース数を1以上にしている場合などに、スポット数がゼロになっている期間が存在したりします。例えば最小台数が5の場合はスポットが2つあるくらいでいいでしょう。しかしベース数が3で、スポット比率が40%だと、割合対象が2台になり、比率優先で2台ともオンデマンドになってしまい、結果的にスポットがゼロになってしまいます。
そういう期間があれば、常にスポット割合が 30~50% 程度になるようベース数と割合を調整します。よほど新しいインスタンスタイプでなければスポットはオンデマンドの 35% くらいの費用になるので、仮に比率が 5:5 になるならば、
(ondemand 50% * cost 100%) + (spot 50% * cost 35%) = 67.5%
と、全てオンデマンドに比べて 67.5% の費用に抑えることができます。
軽量インスタンスの統合・サーバーレス化
仮想環境という便利機能ができて以来、1OS 1機能 のような慣習が構築されてきました。それがクラウドにおいては 1インスタンス 1機能 となります。中には超軽量なリソースで動くものも多くあるはずで、おそらく CPU はほとんど使わず、少量のメモリを必要とする程度のモノになるでしょう。
そういった機能を、1インスタンスのOSの中に詰め込んでしまう、またはvCPUが少なくメモリ容量の大きいインスタンスにコンテナとして詰め込んでしまいます。そうすることで、nano ~ large あたりが複数あるよりも、かなり安くなる可能性があります。弱点としては、その統合作業コストと、1インスタンスあたりの障害・再起動による影響度が高まるといったところでしょうか。
他にジョブのような定期的にCPUリソースを多く使う系の場合、その処理期間以外は無風なはずなので、仮に1日に合計1時間しか動かないジョブなら 23時間分 は完全に無駄なコストになります。これはOSにミドルウェアとして起動する必要がある仕組みにしていたりするからで、Lambda のようなサーバーレスに処理を移行することでサーバーコストも管理コストも大きく削ることを見込めます。
アプリケーション処理の軽減
これは気の長い話かつ日々の熟練度的な話でもありますが、アプリケーションの処理量や使用メモリ容量を減らせれば、その分だけ稼働サーバーリソースを少なく済ませることができます。極端に言えば、CPU使用率が半減するほどのリファクタリングができれば、サーバー数も半減させられ、その箇所の費用を半分にできるわけです。
データ処理の無駄を減らしたり、ライブラリを変えたりなど色々考えられますが、現実的には頑張っても数%程度が関の山で、人的コスパと開発事情を踏まえると取り組むことは少ないでしょう。
どちらかというとプログラミング言語やフレームワーク、ミドルウェアあたりの初期の選択の方でその辺の大勢は決まるようなもので、次点で日々のコーディングとなるでしょうが、昨今のクラウドパワーに頼りがちな運用をたまにはこういった角度から見直すのも悪くないものです。
EC2 EBS
EBSは高い
そもそもの話として EBS って印象より結構高いんですよ。gp2 1TB で $120/月 ですからね、アタッチされてない EBS とか放置されてたら悪即斬ですよ。っていうのを周知した上で、できるだけ無駄のない容量を確保しつつ、必要に応じて容量延長して使うことを徹底するところが第一歩になります。
不要EBSを削除・スナップショット化
開発などで各個人が自由に使って良い環境があり、長くチェックしないでいると、不使用状態の EBS が散見されたりします。一時的に『念のため』残しておく場合もありますが、そのパターンはほとんど無いのが実情でしょう。利用形跡から要不要を確認し、基本的には削除することで垂れ流しコストを回避します。
もし、事情が深い『念のため』の場合、EBSスナップショット化することでスタンダードなら半額、アーカイブだと90日以上残す縛りはあるけど 1/8 程度に削減できるので、『念の』度合い次第で有用となります。
ボリュームタイプの変更
よく使われるEBSタイプである gp2 から gp3 へ変更することで 20% ほど安価になり、ほぼ全ての場合に性能も向上する結果となります。私見では、データベースのようなデータ蓄積・高スループットな更新系でない限り、ほとんどのリソースは 3000 IOPS, 125 MB/s 以上なんて必要にならないので gp3 一択です。なのに管理画面でのインスタンス作成ではいまだに gp2 がデフォルト選択になっているのが意味不明なくらいで、あえて gp2 にする機会は無いに等しいです。
他の選択肢として HDD な sc1 あたりは安価ですが、速度不要で容量だけ重視してローカルストレージを使うのはおそらくクラウドにおいてアンチパターンなので、超例外的な話になるでしょう。
gp2 から gp3 への変更も可能なので、gp2 じゃないとダメな箇所以外をゴリゴリ変更していけば、普通に 1TB あたり $24/月 削減できつつ、性能向上になるので、既存の変更と、今後のデフォルト選択の変更を計画するとよいです。
EC2 AMI
AMI も EBS と同じで、放っておくと増殖しまくる場合があります。無駄を探す前に、とりあえずサクッと状況を判断するには、イメージの件数はこう
1 2 |
$ aws ec2 describe-images --owners self | jq '.Images|length' 362 |
イメージの中に複数のEBSがある場合もあるので、EBS数ならこう
1 2 |
$ aws ec2 describe-images --owners self | jq '.Images[].BlockDeviceMappings[].Ebs.VolumeSize' | wc -l 380 |
容量合計を知るにはこう
1 2 |
$ aws ec2 describe-images --owners self | jq '.Images[].BlockDeviceMappings[].Ebs.VolumeSize' | awk 'BEGIN{SizeSum=0}{SizeSum+=$1}END{print SizeSum " GB"}' 9297 GB |
10 TB あれば $500/月 くらいはかかるので、悪即斬です。
この削減も自動化してあり、イメージ情報を取得し、任意の情報でフィルタリングし、その上で目で見て削除しない方がよいものを除外し、残ったものを全削除する仕組みを作りました。
フィルタリングの内容としては、下記条件をANDして、それだけで完璧なはずないので仕分け手作業を間に入れることにしました。
- 作成日が指定日数より経過している
- 最終使用日が指定日数より経過している
手作業でAMIを削除するとわかるのですが、EBSスナップショットが残ったりするので、そういうのも鬱陶しくて半自動化するに至りました。
NAT Gateway / IPv6対策
ちょうど書く機会がきたでやんす。AWS Public IP 有償化について、とりあえず社内に対応方針を共有した。この前の VPC Routing の記事の前だったら、IPv6 部分も一緒に書いたんだろうけど、これ単発だとそこまでオイシイ記事にはならなそうやなhttps://t.co/oS7WXiO5Ot
— 外道父 | Noko (@GedowFather) July 30, 2023
参考リンク
NAT GatewayIPv6対策
- 新着情報 – パブリック IPv4 アドレスの利用に対する新しい料金体系を発表 / Amazon VPC IP Address Manager が Public IP Insights の提供を開始 | Amazon Web Services ブログ
- 2024年2月1日以降、AWSサービスで利用するパブリックIPv4が課金対象となる
- エグレス専用インターネットゲートウェイを使用してアウトバウンド IPv6 トラフィックを有効にする – Amazon Virtual Private Cloud
- Amazon VPCでIPv6を使用する | ヤマムギ
- IPv6 をサポートする AWS サービス – Amazon Virtual Private Cloud
NAT Gateway 経由の最適化
PublicIP(EIP)を持つ EC2 への INPUT は無料で、OUTPUT が $0.114/GB、NAT G/W を経由すると IN/OUT 双方に $0.062/GB だったので、転送内容によってはどちらを通すかで費用に有利不利がありました。例えば、Private Subnet の EC2 自身が、外から大きなイメージファイルなどを頻繁にダウンロードする場合、NAT G/W 経由だと費用がかかりますが、もし PublicIP で扱った場合は無料になります。
そういった不利な箇所を見つけて、Public に移動することでコスト削減したり、もしかしたら逆にすることで安くなるパターンもあったかもですが、今となっては次の理由で不要な考えとなりかけています。
IPv6対策
来年から Public IPv4 の利用が有料になり、1 IPv4 あたり $0.005/h = $3.6/month、100 IPv4 で $360/月 と無視できなくもないけど、構成を変更するだけで回避できるならコスト増加を避けてしまった方が良い、そんな内容がやってきました。変更手順詳細は省きますが、VPC, EC2, RouteTable, SecurityGroup あたりを変更しつつ、Public Subnet は ::/0 → igw-id へ、Private Subnet から外へ出る必要があれば Egress-Only IGW を作って ::/0 → eigw-id へルーティングすることで実現できるはずです(まだやってない:-)
IPv4 を削除できた分だけコスト削減につながるわけですが、もし Private Subnet で扱う、外部アクセスが必要なリソースが IPv6 に全て対応していれば、NAT G/W が不要になるので削除でき、その分のリソース&転送費用もカットできます。また Egress-Only IGW 自体は無料ですが、転送費用については明記されていないようなので、おそらく EC2 と同じルールと費用と思われます。
この辺は全体から見ると少ない費用となり、Cost Explorer でザッと眺めても変化に気づきづらいため、変更後は詳細を見てコスト削減としての成果を確認しましょう。
S3
費用
課金パーツは色々ありますが、ストレージクラスと容量が基本で、クラス変更にも費用がかかる、ことが中心になります。リクエスト量やデータ転送量は、多い箇所は実際に使っている所であって、おいそれと最適化できないので初手からは省きます。- 料金 – Amazon S3 |AWS
- 6つのS3ストレージクラスの選択に迷った時みるチャートをつくってみた | DevelopersIO
- 新しい Amazon S3 Glacier Instant Retrieval ストレージクラスを発表 – ミリ秒単位で取り出し可能な最低コストのアーカイブストレージ
情報整理
さきほどと同じスプレッドシートで、シートが Storage に変わります。これも自動収集スクリプトでポチるだけにしてあります。S3 にはフォルダという概念は無い、とするのがツウかもですが、実際にはモロ作成できるし、フォルダ単位で区切って整理するようなものなので、有るってことにして続けます(フォルダ警察抑制)。
S3 はその名の通りただのシンプルなストレージではあるものの、容量が無制限であるがゆえに定期的な整理整頓を怠りがちです。クラウドにおけるダメなパワープレイの最たる例ですね。整理するには Linux コマンドの du のような機能があれば良いのですが、フォルダ単位で容量を計測する術はないので、全ファイルを精査すると何時間何日経っても終わらないようなファイル数状況になったりします。
そこで自動化では、ファイルキーに似たパターン部分が同階層にあった場合、一定数以降は実際に取得せずに個数で掛け算することでサンプリング概算のような形で算出しています。これで日付入りキーのタイプは格段に算出を早く完了させることができました。
あとは価格情報も自動取得して、各カテゴリごとにどれくらい費用がかかっているかと、ライフサイクルも整理して出力しています。そしてデータを見ながら、怪しい箇所を実際に管理画面でも確認しつつ、判断を下していきます。
不要・古すぎるデータの削除
データ状況さえわかれば、コスト削減としてやることは通常のストレージと同じです。まずは古いデータ、1ファイルが大きすぎるデータ等を対象に、使用者に確認を入れていきます。
- 日付がかなり経過していて絶対使用しない
- 解析済みデータ
- システム入れ替えなどで、一時的に念のため置いたバックアップ系
- テストデータ
100%と判断できるならば、ストレージクラスを移動するまでもなく、素直に削除することが最も効果的です。もしくは自動削除までの経過日数を短く調整する、という判断もアリです。
間引く
主にバックアップ系ですが、日々残しているバックアップ系データは、毎時・毎日・毎週 など定期的に残しているはずです。基本的にバックアップデータのほとんどは最新のモノ~せいぜい1週間分くらいしか価値がなく、それ以上の過去分は、稀に運用において、過去データの状況確認をするために使用しますが、データ容量が大きくなるほど復元にも時間がかかりますし、現実的にはあまり必要とすることはありません。
とはいえ、最新以外が全く無くなると、過去状況の確認も全くできなくなるので、ある程度を残しておく判断は普通ですし、そもそも組織として一定期間残すルールもモノによっては存在します。
例えば毎日保存するバックアップは、1年で365日分が残りますが、1ヶ月以上経過したデータは月初分しか残さないようにすると、
30日 + (11ヶ月 * 月初) = 41
となり、約 1/9 に削減することができます。
ただ、このような施策はS3ライフサイクルでは表現できないので(不可能ではないけど汚い)、定期自動処理を作成して、確保用コピー&削除を行う必要があります。
ストレージクラス変更
各ファイルとその経過時間ごとにアクセス頻度を考え、頻度が低い・ほぼ無い ファイルほど安いストレージタイプに移すことでコスト削減を狙えます。ちゃんとそれぞれの特徴は読むべきですが、安いほど品質が低かったり、取り出しに余計なお金がかかる感じです。Standard を 100% とすると、最小で 8% まで下げる選択肢があります。いきなり低めのタイプで保存するのもアリですが、基本的にはライフサイクルで自動的に変更する設定をします。ここで注意したいのは、今回はコスト削減として手掛けるので、ライフサイクルを設定すると条件を満たしたファイルに一気に変更処理が走るところです。
ライフサイクルのリクエストにも費用がかかり、タイプによって値段は異なりますが、数千万ファイルの変更に数百ドルかかるくらいです。設定済みライフサイクルで月々に費用がかかるのは問題ありませんが、この辺を甘く見て実行し、ふいに数千数万ドルが当月にかかったら目も当てられません。
やった方が長い目でみて安くなるにしても、変更にかかる費用と、その後の効果は整理・説明して承認を得た上で行うべきです。
ファイル数の削減
これは少し手間のかかる話ですが、上記ストレージクラス変更にかかる費用を含めた、ファイル数が多いことによる管理コストを下げようというものです。ファイル数が多くなることが仕方ない場合もありますが、多すぎるとデメリットが色濃くなります。ログファイルを例に出すと、最近はストリーミングで外部に転送して、ソース元ホスト名や時間をファイル名に含めて書き出していきます。
この時、サーバーが100台あれば、ホスト名を含めることで 100ファイル になりますが、含まないで1つに収集保存すれば 1ファイル になります。毎分ごとに保存するデータは、1時間で60ファイルになりますが、1時間毎にすると 1ファイル になります。
最初の保存時点で少なくできれば良し、もし最初は細かくても解析処理後にまとめなおして安価なクラスで保存するも良し。サービスに流れるトラフィック量に応じて1ファイルあたりの容量は変わりますし、1ファイルあたりが小さすぎても大きすぎても不都合・非効率だったりするので、全共通にできることではないかもですが、最適化するというのはそういうことでもあります。
RDS, Aurora
参考リンク
- 料金 – Amazon Aurora | AWS
- Aurora DB インスタンスクラス – Amazon Aurora
- Release notes for Amazon Aurora MySQL-Compatible Edition – Amazon Aurora
情報整理
同じスプレッドシートでシートが Database に変わります。もちろんワンポチ自動収集です。データベースは複雑な部品ではありますが、サーバーリソースとしてチェックすべき要素はそう多くありません。CPU使用率、StorageのWrite/Read IOPS、空きメモリ容量、Network Interface の転送量(MB/s or Mbps) あたりが基本項目です。
スケールダウン
RDS は高価なパーツなので、最適化によりインスタンスタイプを1つ下げるだけで Multi-AZ 分を含めて、かなりのコスト削減を期待できます。しかし Web/Appサーバーのように、いつでも増減可能な領域と異なり、キャパオーバーすると対応に時間がかかるため、最も余裕を持たせたいところでもあります。そして同時に、高いので無駄を多くしたくないというバランス感を求められます。
現在の最大CPU使用率が 20% だからと、安易に1つタイプを下げて CPU 40% で運用できるかというと、そういうわけでもありません。重要なメモリ容量も半減するので、Storage IOPS や tmp table 等が増加しやすくなるため、クエリの平均応答速度が下がる可能性があります。現在のデータ状況と、クエリの傾向から、最適なメモリ容量を導き出す、というのは非常に難しい行いのため、下げて大丈夫かどうかは負荷試験でもしない限り断言しづらいです。
とはいえコスト削減するぞという時期に、負荷試験をするぞという流れも生まれづらく、多くはデータベース運用経験が多いエンジニアのできる限りの調査と判断を元に、変更とその後の経過観察を怠らない、くらいが現実的な運用となるでしょう。
ビビりすぎないよう1つ有利な話をしておくと、Aurora はそのクエリ処理量(QPS)に CPU使用率 は比例しません。インスタンスタイプによりますが、0~10%あたりはそもそも常に使用され、80~100%あたりは使用率が伸びづらく、粘り強い性質を持ちます。
そのため、現状 MAX 40% だと 100% まで 2.5倍の猶予があるぞ、と思いきや実は 2.8~3.0倍 までレスポンス劣化を少なく捌ける場合が多いです。なので見た目上の数値を基本として計算しつつも、実はより粘るという+αを補足して気持ちの余裕も持たせましょう。
インスタンスタイプ世代更新
Aurora のT系を除くと、r4, r5, r6i, r6g, r7g(東京はまだ) とあり、新しいほど性能が向上し、Graviton な g系は価格が i系より若干安くなります。EC2 や ECS の場合、x86 / arm64 が変わるとイメージも変更しなくちゃですが、Aurora は気にせず使用できるので、Aurora バージョン条件を満たして MySQLバージョンの動作が許せば、できるだけ新しいモノに切り替えていくことで、スケールダウンしたり、逆に未来のスケールアップを不要としたりと実質のコスト削減にできます。
世代ごとの性能差は AWS CPU C6i/C6a の性能検証 | 外道父の匠 にまとめてあるので参考にしてください。
Single-AZ化
データベースは大事なので Multi-AZ 構成にして、障害時に素早くフェイルオーバーするようにしていると思いますが、モノによっては Single-AZ にして費用を半減することが可能かもしれません。これはそんなに乱暴なことを言っているわけではなく、そのDBが何に使われていて、どのくらいの稼働率を求められるかという話で、Multi-AZ ならDNSによって1分前後で復旧するのに対し、Single-AZ ならインスタンス起動が必要になるため 10分前後 かかるようになるので、それを許容できるかどうかということです。
外部向けのシステムなら難しいでしょうが、社内用システムで探せば、意外と無駄と判断できそうな Multi-AZ があるかもしれません。それまでにフェイルオーバーが発生した頻度を整理し、もし頻度が少なくて、実際に事故った時の復旧が 9分増加 したときの影響度を考察すると、案外コスト削減額との価値判断でカットできるかもしれません。
CloudWatchLogs
参考リンク
現状確認
CLI でサクッと現状の使用状態について確認します。Logs に蓄積される日別の容量を表示するにはこうで、これだと毎日 500MB 以上の増加。
1 2 3 4 5 6 7 8 9 10 |
START="2023-02-01T00:00:00" END="2023-03-01T00:00:00" PERIOD=86400 aws cloudwatch get-metric-statistics --namespace AWS/Logs --metric-name IncomingBytes --start-time "$START" --end-time "$END" --period $PERIOD --statistics Sum | jq -r ".Datapoints[] | [.Timestamp, .Sum] | @csv" | sort "2023-02-01T00:00:00Z",495767430 "2023-02-02T00:00:00Z",519793989 ... "2023-02-27T00:00:00Z",586809917 "2023-02-28T00:00:00Z",556286771 |
どのグループが多く容量を使っているのかを見るにはこうで、多い所で 224 GB という事例。
1 2 3 4 5 6 7 |
$ aws logs describe-log-groups | jq -r ".logGroups[] | [.logGroupName, .storedBytes] | @csv" | sort -t, -k2,2nr | awk -F, '{gsub(/"/,"",$1)} {printf "%16s %s\n",$2,$1}' 224031702351 /aws/***/xxxxxxxxxx 171897112383 /aws/***/xxxxxxxxxxxxxxxxxxx ... 214 /aws/******/xxxxxxxxxx/yyyyyyyyyy 0 /aws/*********/xxxxxxx |
全体の合計容量は
1 2 |
$ aws logs describe-log-groups | jq -r ".logGroups[] | [.logGroupName, .storedBytes] | @csv" | sort -t, -k2,2nr | awk -F, '{sum+=$2} END {print sum}' 409340975448 |
雑だけど、これで大枠は把握できるでしょう。
転送データの減少
Logs はデータを保存するための転送自体の方が高くて、100 GB で $76、アーカイブ保存として置いておく分には 100 GB で $3.3/月 って感じです。なので、まずは保存する内容自体に無駄がないか調査し、削るのが効果的です。本当に必要なデータはどうしようもないですが、Logs にはただの標準出力結果を丸っと保存したりもするので、大きめのデバッグ出力がされていると意外と1ヶ月でバカにならない容量になったりします。
保存量の大きいグループから、内容自体に無駄がないかをチェックし、地道に改善していく系統です。
保存期間の短縮
ロググループが作成される時、その保持期限がデフォルトで『失効しない』になっていることが多いです。この場所の性質上、無期限で保存するようなデータは少ないと思われるため、よほど少ないデータ容量と確信できるもの以外は期限を設定するべきです。私が好きな Lambda は実行するとその出力結果が /aws/lambda/*** に保存されますが、自動作成されるとやはり無期限なので、Lambda を Terraform で作る場合は必ずセットでロググループを有期限で作るようにしています。
もし無期限から有期限に変更した場合、そう長くない時間で期限切れデータは削除されるので、それでコスト削減としては完了となります。他と比べたら小さな成果かもしれませんが、本来やらなくていい垂れ流しを止めることには大きな意味があります。
課金形態
参考リンク
- Compute Savings Plans – アマゾン ウェブ サービス
- EC2 でリザーブドインスタンス(RI)と Savings Plans (SP)のどちらを選ぶべきか?基準とするための最強の比較表を作ってみた | DevelopersIO
Savings Plans とリザーブドインスタンス
昔はリザーブドだけでしたが、最近はコンピュート系は Savings Plans が推奨されています。RDS とかはリザーブドしかないですね。要は利用期間を確定したり、前払いをすることで安くしますよ、っていう仕組みなので、条件が当てはまれば適用したほうが当然コスト削減になります。
利用期間は1年 or 3年で、これについて私見を述べると、次世代インスタンスタイプの登場は2~3年スパンで行われることが多いため、少なくともなんとなく3年にすることは避けるべきです。よほど出たばかりならありえるかもですが、新しいタイプへの変更はイコール性能向上なので、その機会損失をどう捉えるかという話になります。
長く、できるだけ変化させたくない環境もあるでしょうから正解はないですが、私の場合は変化に追随しやすい仕組みと文化であることを正とするので、3年固定は許容したくない気持ちが強いです。
前払いの割合については、なし・一部・全部で、これは組織事情で選択が異なります。コストのかかり方が、1ヶ月に集中するのを嫌い、1年で平たくしたい場合もあるし、なにより安くすることを求めるなら全払いになりますので、その辺は費用管理をしている人や部署に相談して把握しておくとよいです。
クラウド引っ越し
参考リンク
vs オンプレミス
超大規模でない限りはクラウド一択なので、余計な選択肢に脳みそを使わないようにしましょう。クラウドできっちり最適化してコスト削減した状態なら、オンプレにかける情熱と手間を、全て新規・既存のサービスの品質を向上することに注いだほうが、遥かにメリットがあると思います:-)
AWS以外では
AWSは別にクソ高い、というわけではないですが、値段以外にそのシェア率からくる情報量や更新頻度に大きな価値があります。そういう意味では Azure, GCP も近いわけですが、三大クラウドで引っ越してもそこまで大きくコスト削減になるわけではない、と思ってよいと思います。大きく安くなるとしたら、国内クラウドや中華系クラウドです。機能や情報が十分だったり少なかったり、Terraform の provider があったりなかったりですが、使い勝手にそこまで困ることはないと思います。これらは三大クラウドよりは交渉の余地が多いかもという点で安くできる可能性があります。
ただしそれには、一定量・一定額以上の利用を前提としたボリュームディスカウント的な話か、もしくはある程度会社の知名度が高く、公な顧客リストに出すといった条件が入ってきたりします。
自分たちは今より安くしたい、クラウド側としては顧客を獲得したい、の狭間で、引っ越し自体にかかる費用とその後の運用安定度と、今より何%安くなればそれらを許容できるのか、で考えていく大きな計画となります。
体感では 10~20% 減程度なら、現行環境を最適化する方が良いと思いますし、30~50% 減となると前のめりに話を聞く姿勢になる気がします。
おわりに
……と、いう感じで、色んなコスト削減方法を知りつつ、上手いこと進行していけるよう頑張りましょう、というお話でした。今はサービスやリソースの種類が多すぎて代表的なところしか書いていないですけど、どんなパーツもそんなに考え方は変わらないと思います。正しい情報整理と、削減後の安定予測、を意識していればそう間違えないはずです。
時にはサービス・チーム事情によっては、削減案の価値に対して優先度が低くなったり、リソース削減=リスク上昇 と感じて躊躇い、なかなか進行が思うようにいかないこともありますが、計画や説明、関係者の納得を得てできるだけスムーズな進行とすることも、任務の一環です。
また、コスト削減できるということは、日々に無駄があるということです。最初の設計レベルが低かったかもしれないし、急激なサービスの変化や成長によって疎かになっていたかもしれません。
逆に言うと、設計レベルを上げる余地があったり、リソース調整を行う頻度を改める余地があるということなので、難しいところではありますが、コスト削減成果をただの費用削減だけに留めず、日々の地力底上げにも還元できると、より高い価値のある取り組みにできるのではないでしょうか:-)