大してアクセスないサイトにECSはオーバースペック
概要
私が業務で触ったシステムは全部ECSでホスティングされています。ECSは動いてる間中ずっと課金されます。しかしlambdaはリクエスト~レスポンス構築完了 の時間しか課金されません。よって大してアクセス数がないサイトや、CloudFrontのキャッシュが効きまくるサイトはECSが暇をしている時間が長いことになり、オーバーパワーです。その時間課金されないlambdaで作れば安いことになります。lambdaなんかで複雑なサイトが作れるかよという話になりますが、aws amplifyなどを使えばモダンなフレームワークで作ったアプリを勝手にlambdaでデプロイしてくれるため、そんなに遠い夢ではありません。そこで今回はaws lambdaとECSの料金を比較し、損益分岐点を探してみます。
想定するwebサービス
ニュースサイトのような、記事が読めて楽しいね、みたいなサイトを想定します。
3Dモデルや動画ファイルみたいな重いファイルはない、ルート検索や検索のような重い処理もない、ゲームのようなリアルタイム性もない、といった計算量的には楽なサイトです。もし例に挙げたようなきつめの要求があるなら、計算がそこそこ必要なのでlambdaとかは選択肢にも上げないほうがいいと思います。
それぞれの構成
lambda
lambda関数1個しか呼び出されないものとします。aws amplifyでデプロイしたときどのような形のlambdaがデプロイされるかはわかりませんが、以下の理由から1個だけということにします
- 私が業務で携わっているwebサービスではサブプロセスを使っていない
- 重いファイルも複雑な処理も必要ない
そのほかのパラメータは以下とします。
パラメータ | 値 | 理由 |
---|---|---|
CPUアーキテクチャ | Arm | x86より安いから |
実行秒数(s) | 3 | 先人の経験則。応答時間がこれ超えたら使ってくれる人が激減するらしいので、何としてもここまでに収めるとする。 |
メモリ(GB) | 2 | 今仕事で携わってるシステムの半分の量。そっちはFargateなので並列にレスポンスをさばいている。lambdaは複数呼び出されたら複数個立ち上がるので、1リクエスト処理するだけでいい=並列処理する分のメモリはいらない |
エフェメラルストレージ(GB) | 10 | lambdaに指定できる最大値。かなり余裕を持っている |
ECS
コンテナ1個で固定とします。
オートスケールするのがECSのいいところですが、オートスケールするほど負荷が高いシステムならlambdaと比較する必要はありません。どう考えてもECSをそのまま使ったほうがいいです。
そのほかのパラメータは以下とします。
パラメータ | 値 | 理由 |
---|---|---|
CPUアーキテクチャ | Arm | x86より安いから |
vCPU(単位なし) | 1 | 今仕事で携わってるシステムと同じ量 |
メモリ(GB) | 2 | 今仕事で携わってるシステムと同じ量 |
料金の計算
計算1:計算リソースの料金だけ比較
まず純粋に計算リソースを何で作るかだけ比較します。ECSならAPI GatewayとかNAT Gatewayとかいろいろ課金されるし、lambdaもapi gatewayに課金されます。簡単のためそれらを無視し、lambdaとecsの利用料金を比較します。
lambdaの料金は計算時間*(確保するメモリ*メモリあたりの料金+確保するストレージ*ストレージ当たりの料金)
で計算できます(リクエスト数に応じても課金されますが、月100万リクエストまで無料なので計算に含めません)。また、lambdaには無料枠があり、1 か月あたり 40 万 GB 秒のコンピューティング時間
が無料で使えます。よって確保するメモリ*計算時間 から40万GB秒を引いて料金を計算します。
上のパラメータで計算してみると以下のようになります。
アクセス数(アクセス/月) | 計算された料金(USD/月) |
---|---|
10000 | 0.01 |
100000 | 2.78 |
200000 | 10.89 |
300000 | 19.00 |
400000 | 27.11 |
500000 | 35.22 |
1000000 | 75.78 |
ECSの料金は起動時間*(確保するvCPU*vCPU当たりの料金+確保するメモリ*メモリあたりの料金)
で計算できます。こっちは初年度以外無料枠がありません。上のパラメータでこちらも計算すると以下のようになります。(aws pricing calcuratorで計算しました)
単位変換管理イベント
タスクまたはポッドの数: 1 /日 * (730 時間 (1 か月) / 24 1 日の時間数) = 30.42 /月
平均期間: 1 days = 24 hours
料金の計算
30.42 タスク x 1 vCPU x 24 時間 x 0.04045 USD /時間 = 29.53 USD vCPU 時間用
30.42 タスク x 2.00 GB x 24 時間 x 0.00442 USD/GB/時間 = 6.45 USD GB 時間用
20 GB - 20 GB (追加料金なし) = 0.00 タスクあたりの GB 請求可能エフェメラルストレージ
29.53 USD vCPU 時間用 + 6.45 USD GB 時間用 = 35.98 USD 合計
これを見ると、計算リソースへの課金だけなら50万アクセス/月程度が損益分岐点ということになります。さらにこれはキャッシュが一切効かない環境での話です。もしキャッシュヒット率が50%あるなら、損益分岐点は100万アクセス/月ということになります。ちなみに私の携わっているサービスのキャッシュヒット率はもっと高いです。
lambdaの料金の途中計算
1ドル160円としている(私の人生最大値付近で計算しやすい値)
アクセス数/月 | メモリ(GB/秒) | ストレージ(GB/秒) | 計算された料金(USD/月) | 計算された料金(円/月) | aws pricing calcuratorの回答(USD) |
---|---|---|---|---|---|
10000 | 60000 | 300000 | 0.01 | 2 | |
20000 | 120000 | 600000 | 0.02 | 4 | |
30000 | 180000 | 900000 | 0.03 | 5 | |
40000 | 240000 | 1200000 | 0.04 | 7 | |
50000 | 300000 | 1500000 | 0.06 | 9 | |
60000 | 360000 | 1800000 | 0.07 | 11 | |
70000 | 420000 | 2100000 | 0.34 | 55 | |
80000 | 480000 | 2400000 | 1.16 | 185 | |
90000 | 540000 | 2700000 | 1.97 | 315 | |
100000 | 600000 | 3000000 | 2.78 | 444 | |
200000 | 1200000 | 6000000 | 10.89 | 1742 | |
300000 | 1800000 | 9000000 | 19.00 | 3040 | |
400000 | 2400000 | 12000000 | 27.11 | 4338 | |
500000 | 3000000 | 15000000 | 35.22 | 5635 | |
600000 | 3600000 | 18000000 | 43.33 | 6933 | |
700000 | 4200000 | 21000000 | 51.44 | 8231 | |
800000 | 4800000 | 24000000 | 59.55 | 9529 | |
900000 | 5400000 | 27000000 | 67.67 | 10827 | |
1000000 | 6000000 | 30000000 | 75.78 | 12124 | 75.72 |
2000000 | 12000000 | 60000000 | 156.89 | 25102 | |
3000000 | 18000000 | 90000000 | 238.00 | 38080 | |
4000000 | 24000000 | 120000000 | 319.11 | 51057 | |
5000000 | 30000000 | 150000000 | 400.22 | 64035 | |
6000000 | 36000000 | 180000000 | 481.33 | 77013 | |
7000000 | 42000000 | 210000000 | 562.44 | 89990 | |
8000000 | 48000000 | 240000000 | 643.55 | 102968 | |
9000000 | 54000000 | 270000000 | 724.66 | 115946 | |
10000000 | 60000000 | 300000000 | 805.77 | 128923 | |
20000000 | 120000000 | 600000000 | 1616.87 | 258700 | |
30000000 | 180000000 | 900000000 | 2427.98 | 388477 | |
40000000 | 240000000 | 1200000000 | 3239.08 | 518253 | |
50000000 | 300000000 | 1500000000 | 4050.19 | 648030 | |
60000000 | 360000000 | 1800000000 | 4861.29 | 777807 | |
70000000 | 420000000 | 2100000000 | 5672.39 | 907583 | |
80000000 | 480000000 | 2400000000 | 6483.50 | 1037360 | |
90000000 | 540000000 | 2700000000 | 7294.60 | 1167136 | |
100000000 | 600000000 | 3000000000 | 8105.70664 | 1296913 |
計算2:付随するリソースの料金も含めて比較
しかし計算リソースだけではwebサイトをホスティングすることはできません。上では計算量のみを比較するためにコンテナを1つとしましたが、ECSならコンテナが複数あるのが普通であり、その場合ルーティングを行うALBを設置する必要があります。lambdaではapi gatewayがないとインターネット経由でlambdaを呼び出せません。これらの料金をシンプルに加算して比較してみましょう。
API Gatewayは100万アクセスでも月1.29USDくらいです。アクセス数が少なければもっと安いですが、簡単のために全部この金額がかかることにします。
512 KB/リクエスト / 512 KB リクエストの増分 = 1 リクエスト
RoundUp (1) = 1 請求可能なリクエスト
1 1 か月あたりのリクエスト x 1,000,000 単位乗数 x 1 請求可能なリクエスト = 1,000,000 請求可能なリクエストの合計
Tiered price for: 1,000,000 リクエスト
1,000,000 リクエスト x 0.00000129 USD = 1.29 USD
合計階層コスト = 1.29 USD (HTTP API リクエスト)
HTTP API リクエストのコスト (毎月): 1.29 USD
ALBは存在するだけでUSD 0.0243/Application Load Balancer/時 かかります。月に直すと17.74USDとなります。通信量に応じてもっとかかりますが、通信量は想像がつかないので一旦お金がかからないものとします。
これをシンプルに足してみると表は以下のようになります。
アクセス数(アクセス/月) | 料金(USD/月) |
---|---|
10000 | 1.30 |
100000 | 4.07 |
200000 | 12.18 |
300000 | 20.29 |
400000 | 28.40 |
500000 | 36.51 |
700000 | 52.73 |
1000000 | 77.07 |
ECS
35.98+17.74=53.72 USD
損益分岐点は70万アクセスくらいになりました。キャッシュヒット率0%での話です。かなりlambdaが安く見えますね。
結論
- (当然だけど)アクセス数が少ないうちはlambdaが安く、アクセス数が上がるとECSが安い
- 同じインスタンスサイズでさばければの話
- この設定だと損益分岐点は50万アクセス/月
- キャッシュヒット率が上がるほどさらにlambdaが安い
- 意外とそこそこの規模のサイトでもlambdaのほうが安いのではなかろうか
月100万アクセスあってもキャッシュヒット率50%でlambdaが勝ちます。月10万アクセスくらいならECS使うな。
じゃあ以後うちのプロジェクトは全部lambdaで作ろう
そういうわけにはいきません。これまでweb開発をやっていた人たちはサーバーにデプロイしてnginxやapacheでリクエストを受け付けていたものです。それがコンテナになるのはまだこれまでの延長線上にありますが、lambdaは理の外にあります。作り始めたらどんな問題が起きるかわかりません。私自身もlambdaで全部システムを構築したことがないエンジニアの一人です。lambdaでサービス全部作るなんてバカだぜという知見を持っている方は教えてください。
すぐ思いつく範囲でも以下のような問題があります。考えるよりやってみたほうが早そう。ちゃんと時間かけて個人サービス作ったよ~という人は教えてください。私もやる気が出たら実験します。
- 純粋にlambdaで作るときに美しくモジュール分割できなそう
- amplifyを信じていいのか?
- RDB使えない
- VPCにlamdba置いてRDS建てましょう。IG分余計にお金とられるけど
- RDSよりsqlite on efsのほうが安いらしいです
- できればDynamo使えると無料枠があるのでさらに安上がりです
Discussion
ここで Lambda Function URLs が最初から選択肢に入っていないのは何か理由があるのでしょうか?
(文脈を掴めていなかったらすみません…)