ENECHANGE Developer Blog

ENECHANGE開発者ブログ

Lambda関数URLを実戦投入してシンプルなリダイレクト処理を構築する(コスト編)

ENECHANGE所属のエンジニア id:tetsushi_fukabori こと深堀です。
東京の我が家で飼っているバーニーズマウンテンドッグは暑さでバターのように溶けて伏しています。
涼しい土地に広い庭付き一戸建てで健やかに過ごさせてあげたいですね。

今回は前回に引き続きLambda関数URLを実戦投入したときのコストについて考えます。

この記事の概略

  • AWS Lambdaの2022年4月の新機能「関数URL」を実戦投入しました
  • Route53 + CloudFront + Lambda関数URLでシンプルなリダイレクト処理を構成しました(前回実践編で紹介)
  • CloudFront functionやLambda@Edgeを使う場合と比較して小さいながらコストメリットがあることを整理しました

前回の内容

AWSから2022年4月6日に発表された新機能「Lambda関数URL」はLambda関数に直接URLを生やせます。
これをなんとか実戦投入できないか…ということで試行錯誤しました。

運良く「enechange.comへのリクエストをenechange.co.jp/en/に単純リダイレクトしてほしい」という開発テーマが手に入ったので、Route53 + CloudFront + Lambda関数URLという構成で本番環境に投入することに成功しました。
構成は以下の通りです。

CloudFront + Lambda関数URLでのシンプルなリダイレクト構成

コストについて

「関数URLを使いたい」という話がなければ「HTTP/HTTPSに応答できるシンプルなリダイレクト処理」の実現方法は他にもあります。
ぱっと思いつくのは

  • CloudFront + CloudFront function
  • CloudFront + Lambda@Edge

とかでしょうか。(API Gatewayを使う方法も考えられますが、リクエストあたりのコストが明らかに高いのでコスト比較からは除外します。)

上記に加えて今回実現したCloudFront + Lambda関数URLの方式をコスト比較してみます。
すべて共通でCloudFrontを使っているので、CloudFrontのリクエスト処理やデータ転送にかかるコストは除外し、関数の実行コストのみを計算対象とします。
なお、ここで言う「関数」というのは上記のLambdaやCloudFront functionのことを指します。
Lambdaの実行環境はx86_64の128MBメモリです。

方式 関数の実行タイミング 関数の処理コスト
CloudFront + Lambda関数URL キャッシュヒットしなかった場合 0.20USD/100万件(実行) + 0.0000000021USD/ミリ秒(期間) + 0.114USD/GB(転送アウト)
CloudFront + CloudFront function 常に 0.10USD/100万件
CloudFront + Lambda@Edge キャッシュヒットしなかった場合 0.60USD/100万件(実行) + 0.00000000625125USD/ミリ秒(期間)

CloudFront functionはviewer request/responseでの実行なので、キャッシュヒットに関係なく必ず実行されることになりますが、他の2つはキャッシュヒットしていれば関数の処理コストはかかりません。
Lambda関数URLはCloudFrontからのrequest/responseがインターネットとのデータ転送が発生すると考えられるためそのコストを乗せています。
Lambda@Edgeはキャッシュの後ろのorigin request/responseで実行することを想定しています。

上記を踏まえ、関数の実行時間は一回あたり0.01秒(10ms 実測)、Lambda関数の転送データ量300Byte(実測)を仮定して100万リクエスト時のコストを計算します。
表をみて分かる通りキャッシュヒット率次第でコストが変わるため、キャッシュヒット率毎に計算してグラフにしました。

キャッシュヒット率ごとのコスト

結果キャッシュヒット率で最安の方式が変わりました。

  • CloudFront functionはキャッシュヒット率60%まで最安
  • キャッシュヒット率60%以上ではLambda関数URLが最安
  • キャッシュヒット率によらずLambda@Edgeは最安にはならないが、85%程度からCloudFront functionより安くなる

今回のように固定的なレスポンスを返す場合はキャッシュ期間を長く設定してキャッシュヒット率を上げることで、Lambda関数URLを使うとコストメリットが出せそうです。 コストとしては小さなものですが、実行回数が多い場合は嬉しいですね。

他にもまだある単純リダイレクト構築法

すごく鋭い指摘

今回の記事を社内で回覧したところ有識者から鋭いレビューコメントを頂きました。
全然知らなかったのですがS3には静的ウェブサイトホスティングを設定している場合、リダイレクトの設定ができるんですね。

docs.aws.amazon.com

(勝ち筋を見つけたい一心で)コスト面で勝てる要素が無いか確認したところ、S3へのGETリクエストのコストが該当するようです。

方式 S3のリソース取得タイミング S3のリソース取得の処理コスト
CloudFront + S3リダイレクト キャッシュヒットしなかった場合 0.00037USD/1000件(GETリクエスト)

「/1000件」というところに勝ち筋があるような気がしなくもありません。
一縷の望みをかけてグラフにS3リダイレクトを追加します。
結果は…

キャッシュヒット率ごとのコスト(S3リダイレクト追加版)

………やったか…?
ギリギリ僅差で勝てた…もようです!!!
色々と試行錯誤した構成を即Revertしなくて済んだようで何よりです。いろんな実装方式が考えられる処理はコスト比較が大変ですね。

実際のキャッシュヒット率は?

今回の機能をリリースしてからのキャッシュヒット率はどの程度だったのでしょうか?
果たしてコストメリットが出るほどだったのでしょうか?

実現できたキャッシュヒット率

どうやら最低コストとなれる60%を上回るキャッシュヒット率を達成できているようです。
これで(執筆者がやりたいからで実装するだけでなく)意味のある機能を実現できました!

まとめ

様々な方法でシンプルなHTTP/HTTPS対応のリダイレクト処理を構成する方法を検討し、コストの比較検討をしました。
CloudFrontを前段に立てる方式ではキャッシュヒット率が大きくコストに影響します。
CloudFront functionは安価でコストが安定しています。キャッシュヒットしないような様々なリクエストをさばく場合には最安になれそうです。
一方である程度以上のキャッシュヒット率が見込める場合、今回の構成のような方式取ることでよりコストを抑え込むことができそうです。