🧙

魔改造 Lambdaの250MB制限を突破してみる in Python

に公開

lambdaの 250MB制限とは?

Lambdaのコード、またライブラリ、そのライブラリが参照するファイルを全て含めてlambdaに乗せられるファイル容量は250MBまでとなっています。
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/gettingstarted-limits.html
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/creating-deleting-layers.html
これは lambda layerにおいてもそうですし、一度zipにまとめてS3経由でlambdaの codeをdownloadする時にも同様です。(zipfile自体は50MB、解凍後は250MBが制限になります)。

今回Pythonで必要なライブラリがあったもののサイズ上限に引っかかりました。
ECR式のlambdaを立てるのも面倒ですし、EC2で代替するのも面倒だと感じたのでなんとか打開する方法はないのかと探しました。

魔改造注意事項

  • AWSの公式ドキュメント等探しても一切の記載を見つけられなかったので、推奨できる方法ではありません。また、lambdaのupdate等に伴い不具合が発生する可能性もあります。
  • S3との通信が毎回発生するため、zipしたとしても相当量の通信コストが発生します。1日数回ならまだしも1日に数千、それ以上になっていくと、S3のIOコストが発生するため、それをご理解の上実装を検討してください。
  • AWSの公式ドキュメント等探しても一切の記載を見つけられなかったので、推奨できる方法ではありません。また、lambdaのupdate等に伴い不具合が発生する可能性もあります。
  • S3との通信が毎回発生するため、zipしたとしても相当量の通信コストが発生します。1日数回ならまだしも1日に数千、それ以上になっていくと、S3のIOコストが発生するため、それをご理解の上実装を検討してください。
  • AWSの公式ドキュメント等探しても一切の記載を見つけられなかったので、推奨できる方法ではありません。また、lambdaのupdate等に伴い不具合が発生する可能性もあります。
  • S3との通信が毎回発生するため、zipしたとしても相当量の通信コストが発生します。1日数回ならまだしも1日に数千、それ以上になっていくと、S3のIOコストが発生するため、それをご理解の上実装を検討してください。

大事なことなので3回言いました

結論: zipファイルにしてS3に置いておき、毎回/tmpに展開してpathを通す

という感じです。順を追って実装します。

pip による libraryの install

まずご存知の通りPythonライブラリは pip install hoge -t ./で、current directoryにlibraryをinstallできます。
lambda layerはこれをzip fileにしてlayerに保存しますし、lambdaの codeの横に置く場合においてもこのinstallしたものを lambda_function.pyと同じdirectoryに置けば(置けるのであれば)それでライブラリは機能します。

今回はこのコード群および設定ファイルをS3に置きます

上記の画像の例ではtqdmをcurrent directoryにinstall しました。
これをzipにしてS3におきます。

zipファイルを tmpに展開し pathを通す

hiradev という S3 bucketに tmp.zipという名前で保存したlibraryの圧縮ファイルを /tmpというfolderに置いています。

import json
import zipfile
import boto3

s3_bucket = 'hiradev'
s3_key = 'tmp/tmp.zip'
local_zip_path = "/tmp/tmp.zip"
lib_dir = "/tmp/"

s3 = boto3.client('s3')
s3.download_file(s3_bucket, s3_key, local_zip_path)
with zipfile.ZipFile(local_zip_path, 'r') as zip_ref:
    zip_ref.extractall(lib_dir)
import sys
sys.path.append(lib_dir)


def lambda_handler(event, context):
    import tqdm
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }

あとは上記のコードでtqdmを呼び出すことができます。
(tqdmは一例です。250MB以下ですので、この方法は無駄です。)

また、細かい検証は省いたのですが、lambdaのstorage size, memory sizeは それぞれ10GBまで拡張可能であり、libraryのサイズによってこちらの調整も必要になると思われます。

最後に、この方法はかなり無理やり行なっていますので「魔改造注意事項」を再度ご確認ください。

いいねいただけると励みになります。お読みいただきありがとうございました。

Discussion