LambdaのベースイメージをslimイメージからAWSベースイメージに置き換えてコールドスタートを改善した話
こんにちは。株式会社GA technologies、Advanced Innovation Strategy Center(AISC)の三田です。
先日、Lambdaのコールドスタートについて実験してこのような記事を書きました。
このとき気になって実験してたことのひとつが、Lambdaに使うコンテナイメージのベースイメージ(DockerfileのFROMに指定するイメージ)を「AWSベースイメージとPython3-slimなどの軽量なイメージのどちらを使ったほうがコールドスタートが速くなるのか」でした。今回はこの点について触れていきます。
まず用語の定義をしていきます(正式な用語がよくわからず勝手に命名しているため)。
本記事におけるAWSベースイメージとはAWSが https://gallery.ecr.aws/lambda/ で公開しているイメージです。例えば「public.ecr.aws/lambda/python:3.12」です。Dockerfileで
FROM public.ecr.aws/lambda/python:3.12
というふうにAWSベースイメージをベースイメージに指定することで、Lambdaで動かすために必要な設定(ENTRYPOINTや環境変数の設定など)を自分でやらなくて済むのがメリットです。
slimイメージは軽量なベースイメージです。例えばpython:3.12-slimです。Dockerfileに
FROM python:3.12-slim
といったふうにslimイメージをベースにしてイメージをbuildすることで、AWSベースイメージを使うよりもファイルサイズが小さいコンテナイメージを作ることができます。
AWSベースイメージとslimイメージのどちらを使うほうがコールドスタートが速いのか
記事執筆時点で最新の両者のPython3.12イメージは
python:3.12-slim:40.97 MB
であり、Lambdaのコールドスタート時にイメージをダウンロードする処理を考えるとサイズの小さいpython:3.12-slimを使ったイメージのほうが有利に思えます。しかし、実際に両者を比較してみると、AWSベースイメージのほうがコールドスタートが短いケースが非常に多かったです。
次の画像はboto3パッケージのみを入れた簡単なPythonのイメージで、AWSベースイメージを使ったイメージとpython:3.12-slimを使ったイメージとで比較したものです。
slimイメージ(図中の"slim")のLambdaよりも、ファイルサイズが3倍以上大きいAWSベースイメージを用いたLambda(図中の"official")のほうが平均的に短いコールドスタート時間(init duration)であることがわかります。なお両者の平均はofficialが440.3msでslimが879.4msと、slimのほうがofficialより約440ms遅い状態でした。
なお、これは実験を始めてから気づいたのですが、AWSの過去のブログでもAWSベースイメージの優位性が解説されていました(カッコ内はGoogle翻訳です)。
実験的にもLambdaの内部のキャッシュシステム的にもAWSベースイメージを使うほうが望ましいことがわかりました。
LambdaのベースイメージをslimイメージからAWSベースイメージに置き換えてコールドスタートを改善した話
実際のサービスでslimイメージを使っていたものがあり、AWSベースイメージへの置き換えを行いましたのでご共有いたします。
AISCでは社内の業務効率化やtoC事業において賃料や価格の予測機能をAPIとして提供しております。例えば以下のサービスの「AI査定」機能の裏側でAPIが動いております。
こうした予測APIたちの一部のLambdaではPython3-slimベースのイメージを使っておりました。その背景としては
PythonのAWSベースイメージが長らくAmazon Linux 2のOSがベースであったため、対応しているC++のコンパイラやライブラリの関係でLightGBMが動かなかった
当時は「AWSベースイメージのほうが望ましい」ということを知らなかった(むしろ「軽量なイメージのほうがいいだろう」という思い込みすらあった)
といったことから、開発した当時はslimイメージを使うという選択をしたのでした。
しかし、AWSベースイメージのPython 3.12からはAmazon Linux 2023のOSがベースになりLightGBMが動くようになったため、ベースイメージのリプレイスを行いました。具体的には、Python3.12のAWSベースイメージ(public.ecr.aws/lambda/python:3.12)を使い、LightGBMで必要なOpenMPなどをインストールしたDockerfileを使いました。
このDockerfileを使うようにした結果、こちらも平均で約420msのコールドスタートの短縮が実現できました。
まとめ
まとめますと、
というのが今回の学びでした。
もし同様にLambdaでslimイメージや他の非AWSベースイメージを使っている方がいらっしゃいましたらAWSベースイメージへの乗り換えを検討されてみてはいかがでしょうか。