AWSコストをいますぐ最適化しませんか?
キャッシュフロー、ユニットエコノミクス、改善しませんか?
この記事では、とにかくいますぐなんとかしたい方向けの方法を金額面で大きい傾向にあるサービスごとに26個紹介します。
以下各見出し内の💰はコスト削減度、⚡はおまけでパフォーマンス改善度を指します。
(1) 💰💰💰 CloudWatch Logs: とにかくログを出さないこと、まとめること
AWS料金のうち、CloudWatch Logsが上位を占める傾向にあります。保存期間が無期限だから費用がかかる...と見せかけて、実際はログ出力自体の料金が大半です。
レガシーWebアプリケーションのログは1リクエストにつき何回も何行も出力する傾向があります。フレームワーク特有の不要なログも付いてきます。勝手に出力されるログは放置せず整理して、リクエスト単位でイベントとしてまとめましょう。
参考記事
各種ジョブもログが多いですね。
特定のエラーに対するログが出しっぱなしなら、エラーを修正をするかログのほうを消しましょう。
Lambda実行時に必ず出るCloudWatch Logsの話
Lambda実行のたびにCloudWatch LogsにSTART / REPORT / ENDの3行が必ず出力されます。 このログはメトリクスを兼任していますが、あえてここの出力も削りたいなら、LambdaからCloudwatch LogsへのPUT権限を外すという大技があります。 Proxy的な、実行量が多いが何もしない処理にはありかもしれません。
Lambda
パフォーマンス改善 ≒ コスト改善です。パフォーマンスチューニングの観点は別稿に譲るとして、ポイントだけ解説します。
以下も参考にしてください。
(2) 💰💰⚡ Lambda: ARM化する
単純に20%落とせます。Node.jsはARM化しやすいものの、Pythonは利用ライブラリによっては工数がかかります。
(3) 💰⚡ Lambda: handlerの外で初期化する
Lambda実行のたびに初期化処理が実行されていることがあります。今一度確認しましょう。
(4) 💰 Lambda: Provisioned Concurrencyを削減する
本番環境でもLambda実行料金以上にかかっている事例が散見されます。精査しましょう。
(5) 💰 Lambda: ランタイムのバージョンを上げる
最近のプログラミング言語はパフォーマンスに気を使っています。
2023年2月現在ではまだ未対応ですが、Python 3.11はFaster CPythonプロジェクトにより高速化されていますし、 boto3 1.20.32からのkeepalive機能にも期待したいところです。
(6) 💰⚡ Lambda: Node.jsでのTCP Keep-alive追加
Lambda公式ドキュメントにもあるとおりです。なお、Node.js 18やAWS SDK for JavaScript v3、CDKのNodejsFunctionでは設定済みなので対応不要です。
(7) 💰⚡ Lambda: Preflight Requestに対応する
クラウド時代、アプリケーションまでOPTIONSメソッドが到達したら何かがおかしいでしょう。ルーティングをアプリではなくクラウドインフラに全部任せることをおすすめしています。API GatewayやCloudFrontなどのインフラで対応しましょう。
Access-Control-Max-Ageによるキャッシュも大事です。もちろんPreflight Requestが発行されないことが理想です。
(8) 💰⚡ Lambda: とにかく実行しないようにする
実行しなければ無料!コード負債もゼロ!ついでに障害もゼロ!
以下のような方法が考えられます。
- EventBridgeで直接外部APIを実行する
- Event Filteringで除外処理をLambdaの外に置く
- Lambda経由でのS3アクセスを避ける
- API Gatewayの固定レスポンスを活用する
DynamoDB
特にGSI関係がコストが嵩む要因です。
以下の記事も参考にしてください
(9) 💰💰 DynamoDB:GSIの不要な射影を減らす
なんとなく全部を射影にしてしまいがちですが、特に書き込みコストに跳ねるので控えましょう。新しい同一のテーブルにも複製して書き込むイメージです。
(10) 💰⚡⚡ DynamoDB: batchでget/writeする
たまにgetを連打するコードを見かけます。batchに書き換えてアクセスをまとめ、節約しましょう。
(11) 💰 DynamoDB: 保存する属性名、キー名を短くする
NoSQLであり型が決まっていない以上、レスポンス内で属性名やキー名を繰り返すコストが膨大になります。少しでも削りましょう。アプリケーションコード側でわかりやすい属性名にマッピングすると可読性とコスト、パフォーマンスを両立できます。
(12) 💰 DynamoDB: On-Demandにする
キャパシティをProvisionedにすると使っていない時間帯も料金が固定でかかります。ワークロードが1日を通して大きく動くならOn-Demandのほうが無難です。
一方リザーブドキャパシティによる事前予約を考えるとProvisionedも選択肢に上がりますね。
AWS Config Advanced Queryを使えば、キャパシティ種類を全テーブル全アカウント分一覧化できます。
Aurora RDS
いかにスペックを下げるか、負荷ピークを作らないかが勝負です。
(13) 💰💰 Aurora: インスタンスファミリーを最新化にする
2023年現在最新のr系インスタンスはr6gです。新しいバージョンが登場したときにスムーズにアップグレードする体制が整っているでしょうか?
(14) 💰💰⚡⚡ Aurora: インデックスを付与する
残念ながらテーブル作成時にインデックスを付与していない事例が散見されます。インデックスがないとDB負荷があがり、インスタンスサイズ増、料金増につながります。MySQLなら複合インデックスの理解が浅めの方が多めです。複合インデックスが1テーブルにおおよそ1つはないと不安を感じます。APMツールで確認しながらインデックスを追加しましょう
(15) 💰💰⚡ Aurora: N+1クエリを放置しない
DB負荷が大きく上がりますし、処理時間がかかることでアプリケーションレイヤーのコストもかかります。APMツールを入れているとモニタリングコストも大きくかかります。
(16) 💰💰 NAT Gateway: S3 / DynamoDBのGateway endpointを設定する
VPC内からNAT Gatewayを通さずにアクセスできます。NAT Gatewayの通信量が多いときは確認してみましょう。移行時のリスクはほぼありません。
(17) 💰 NAT Gateway: 通信量を減らす
アプリケーション起動時にイメージ取得や外部のリポジトリアクセスによる通信が時折発生します。キャッシュ可能ならキャッシュするか、インターフェイスエンドポイントでNAT Gatewayの迂回を検討しましょう。特にFargate + ECRが危険です。
(18) 💰💰💰 S3: バージョニングの再検討
AWSのベストプラクティスにもある通り、セキュリティや運用上はオブジェクトの過去バージョンを保持したいところです。一方、過去のオブジェクトをそのまま保持するため膨大な料金がかかります。
バージョニングの停止のほか、過去バージョンのストレージクラスを変更する、過去バージョンの世代数やTTLを設定するといった選択肢があります。
(19) 💰💰💰 S3: バージョニングの残骸を確実に消す
検討の結果バージョニングを停止しても、以前のバージョンは残ったままです。新しいバージョンの生成を停止しただけなので。過去バージョンが不要なら消去する必要があります。
S3 Storage Lensを使うとアカウント単位で旧バージョンの総サイズを確認できて便利です。
(20) 💰⚡ S3: list APIよりS3インベントリを使う
詳しく見るとListObjects APIが嵩んでいることが見受けられます。S3インベントリを駆使し、毎回listしなくてよくなるか検討してみましょう。
(21) 💰⚡ API Gateway:Authorizerのttlキャッシュを設定する
認可処理は呼び出し回数が多くなります。キャッシュしましょう
(22) API Gateway: gzip化する
たまに設定できていないので確認しましょう。圧縮サイズを設定するとonになる仕組みです。
(23) API Gateway: 固定レスポンスを活用する
バックエンドAPI呼び出しが不要ならこちらを。
(24) Glue: 既存記事をご確認ください
パフォーマンスはコストということで、カケハシでGlueを主力にしているチームの記事を参考にしてください
以下の記事も非常に参考になり、なにかあるたびに勧めています。ありがとうございます🥰
(25) KMS: マネージドキー+暗号化に注意
AWS所有のキー以外を利用すると、料金が大幅に上昇します。KMS自体もかかりますが、CloudTrailの費用が膨大になります。
(26) 💰💰💰⚡⚡⚡ とにかく不要なアクセスを減らす
一番最初にやることをおすすめしますが、若干時間がかかるので最後に持ってきました。
- そのフロントエンドからバックエンドの通信は本当に必要ですか?
- すでにあるキャッシュ機構は使えませんか?新しく導入するのは大変ですが既存なら現実的
- ポーリング、リフレッシュの間隔を延長できませんか?
フロントエンドのような前段側で改善すれば、後段側の料金も減るのでおすすめです。
参考記事
最後に
この記事ではすぐに成果を出したい人向けに比較的簡単な方法を解説しました。開発環境やRI/契約といった原価改善の本質からそれる話は除いています。
前回の記事では、サーバレスの優位性について説明しており、
次回は根本的にコスト構造を変化させる方法について記載する予定です。
文責:高木