🐕

大してアクセスないサイトにECSはオーバースペック

に公開1

概要

私が業務で触ったシステムは全部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でサービス全部作るなんてバカだぜという知見を持っている方は教えてください。
すぐ思いつく範囲でも以下のような問題があります。考えるよりやってみたほうが早そう。ちゃんと時間かけて個人サービス作ったよ~という人は教えてください。私もやる気が出たら実験します。

  1. 純粋にlambdaで作るときに美しくモジュール分割できなそう
    1. amplifyを信じていいのか?
  2. RDB使えない
    1. VPCにlamdba置いてRDS建てましょう。IG分余計にお金とられるけど
    2. RDSよりsqlite on efsのほうが安いらしいです
      1. https://qiita.com/aki366/items/f2d353948cebbbf9c94c
      2. https://zenn.dev/beenos_tech/articles/lambda-sqlite-application
    3. できればDynamo使えると無料枠があるのでさらに安上がりです

Discussion

kanaruskanarus

lambdaではapi gatewayがないとインターネット経由でlambdaを呼び出せません。これらの料金をシンプルに加算して比較してみましょう。

API Gatewayは100万アクセスでも月1.29USDくらいです。アクセス数が少なければもっと安いですが、簡単のために全部この金額がかかることにします。

ここで Lambda Function URLs が最初から選択肢に入っていないのは何か理由があるのでしょうか?

(文脈を掴めていなかったらすみません…)