こんにちは。てるいです。
AWS Lambdaでカスタムランタイムを利用する方法として、Docker(OCI)コンテナイメージがサポートされました。 aws.amazon.com
さて、ここでやはり気になるのはイメージサイズがLambdaのスピンアップ(初回起動・コールドスタート)速度にどの程度影響するのかですよね?ね?
では、検証していきましょう。
検証
検証にはus-west-2(Oregon)を利用しています。
まずは、サイズの異なる2つのカスタムランタイムAPIに対応したスクリプトを持つコンテナイメージを用意します。
どんな感じでコンテナを作れば良いかは、AWSが公開している各種ランタイムのベースイメージのこの辺を見るとなんとなくわかります。
実行するのは、こんな感じのただ"Hello world"を返すだけのシェルスクリプトにします。
#!/bin/sh set -euo pipefail # Processing while true do HEADERS="$(mktemp)" # Get an event. The HTTP request will block until one is received EVENT_DATA=$(curl -sS -LD "$HEADERS" -X GET "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/next") # Extract request ID by scraping response headers received above REQUEST_ID=$(grep -Fi Lambda-Runtime-Aws-Request-Id "$HEADERS" | tr -d '[:space:]' | cut -d: -f2) # Run the handler (dummy) RESPONSE="Hello world" # Send the response curl -X POST "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/$REQUEST_ID/response" -d "$RESPONSE" done
イメージその1(軽量級イメージ)
軽量級イメージは軽量なAlpine Linuxをベースに上記スクリプトを実行するために必要なパッケージだけをインストールしたものとします。
Dockerfileはこんな感じ。
FROM alpine:3.12.1 RUN apk add --no-cache curl grep coreutils ADD bootstrap /var/task/ RUN chmod +x /var/task/bootstrap CMD [ "/var/task/bootstrap" ]
気になるサイズは?
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE minimum-lambda-alipine latest 05b183b55ec7 8 minutes ago 8.62MB
8.62MB
になりました。
これをECRにpush(手順は普通のDocker Imageのpushを一緒なので省略)して、Lambda Functionを作成します。
ちなみにここで他人に見られても問題ないイメージなので、試しに新しいPublicリポジトリを利用してみようとしましたが、Lambdaにはまだ対応していないようでLambda Functionの作成時にPublicリポジトリは選択できませんでした(CLI, APIからならできる可能性もある)
コンテナイメージから作成を選びます。
イメージを指定。
これをコンソールのテスト実行機能から実行します。
CloudWatch Logsから結果を確認すると・・・
REPORT RequestId: 49b3f7b5-ba3e-4c54-9a40-daa982cfa3cb Duration: 208.01 ms Billed Duration: 649 ms Memory Size: 128 MB Max Memory Used: 18 MB Init Duration: 440.25 ms
Init Duration
がスピンアップにかかった時間で、今回は 440.25ms
でした。何度か試したら100ms台のこともあったので、公式ランタイムの速いものと比べると若干物足りなさはありますが、まあ許容範囲かなという感じですね。
イメージその2(重量級イメージ)
重量級イメージはなんとなくCentOS7のイメージで。
FROM centos:7 ADD bootstrap /var/task/ RUN chmod +x /var/task/bootstrap CMD [ "/var/task/bootstrap" ]
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE minimum-lambda-centos7 latest 6f41c6b64715 3 minutes ago 204MB
204MB
、なかなか良い感じの重量感になりましたね。
実行してみます。
REPORT RequestId: 54f2d341-f6ae-406b-b521-a246e6f12011 Duration: 303.35 ms Billed Duration: 2632 ms Memory Size: 128 MB Max Memory Used: 34 MB Init Duration: 2328.37 ms
Init Duration: 2328.37 ms
これはちょっとオンライン処理では正直厳しいかな・・・
一番初回だけが遅い(初回だけECRから落として、以降はもっとNW的に近い場所に置いておくとか)のかもしれないので、コールドスタートとなるようにしばらく間を置きつつなんどか試しましたが、500~600ms程度のばらつきはあるものの明らかに軽量イメージとは有意な差が確認できました。
まとめ
イメージサイズによってスピンアップ速度に有意な差が確認できました。特にオンライン・リアルタイムな処理では注意しましょう。
ちなみにウォームスタート、つまり起動済みコンテナが破棄される前に実行する場合においてのDurationはどちらも100ms程度だったので、コールドスタートの遅さに目を瞑ることができる(バッチ処理など)場合や、オンラインでもProvisioned Concurrencyを利用する前提においては十分に利用できます。
また、今回はLambdaのメモリサイズは最小の128MBで検証しています。Lambdaはメモリサイズを上げるとNW帯域も向上するので、今回の差はより小さいものとなるはずなので、実際に利用できるかどうかはメモリサイズもチューニングした上でご自身で検証してみていただければと思います。
以上です。AWS re:Invent 2020はまだまだ続くので、この後も楽しみにしていきましょう!