Lambdaのコンテナイメージサイズでスピンアップ速度はどれくらい変わるのか #awsreinvent

記事タイトルとURLをコピーする

こんにちは。てるいです。

AWS Lambdaでカスタムランタイムを利用する方法として、Docker(OCI)コンテナイメージがサポートされました。 aws.amazon.com

さて、ここでやはり気になるのはイメージサイズがLambdaのスピンアップ(初回起動・コールドスタート)速度にどの程度影響するのかですよね?ね?

では、検証していきましょう。

検証

検証にはus-west-2(Oregon)を利用しています。

まずは、サイズの異なる2つのカスタムランタイムAPIに対応したスクリプトを持つコンテナイメージを用意します。

どんな感じでコンテナを作れば良いかは、AWSが公開している各種ランタイムのベースイメージのこの辺を見るとなんとなくわかります。

hub.docker.com

実行するのは、こんな感じのただ"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からならできる可能性もある)

aws.amazon.com

コンテナイメージから作成を選びます。

f:id:swx-terui:20201202155728p:plain
関数作成

イメージを指定。

f:id:swx-terui:20201202155819p:plain
イメージ指定

これをコンソールのテスト実行機能から実行します。

f:id:swx-terui:20201202152757p:plain
テスト実行

CloudWatch Logsから結果を確認すると・・・

f:id:swx-terui:20201202163028p:plain
CWLogs

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はまだまだ続くので、この後も楽しみにしていきましょう!

virtual.awsevents.com