🐡

AWS Lambdaで次回実行まで値をキャッシュするシンプルな方法2つ

2024/04/03に公開

はじめに

AWS Lambdaで、次回のLambda実行でも参照できるように、実行時の変数の値を保持 (キャッシュ) しておきたいことがあると思います。
厳密にやるならDynamoDBなどを使うと思いますが、サクッと実装したいこともあります。

そんなときに使える簡単な方法を2つ見つけたのでご紹介します。

グローバル変数を使う

これは1番シンプルな方法です。Lambdaがウォームスタートされる場合、グローバル変数の値は保持されます。そのため、シンプルに保持したい値をグローバル変数として宣言するだけでOKです。

ただし、Lambdaがコールドスタートのときはグローバル変数の値もクリアされます。いつまでウォームスタートになるかは環境によるそうなので断言できませんが、私の環境では1時間を超えると保持されない感触でした。
そのため、数分など短い間隔でLambdaを実行する場合に向いていると思います。

例えばPythonだと以下のように書けます。

cached_value = None

def lambda_handler(event, context):
    # グローバル変数から前回の値を取得
    global cached_value

    if not cached_value:
        # コールドスタートのときは値が入っていないので入れ直す
        cached_value = YourClass()

    # 新しい値を代入 (次回ウォームスタートなら使える)
    cached_value = 'new value'

Pros

  • 実装が簡単

Cons

  • いつ値が消えるかわからない。1時間以上などは厳しそう

Lambda環境変数を使う

Lambda > Configuration にあるLambda環境変数を使う方法です。この方法だとコールドスタートでも値が保持されます。そのため実行間隔が1時間以上の場合などに向いていると思います。

boto3のLambda Clientの update_function_configuration methodで、Lambda環境変数を更新できます。
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/lambda/client/update_function_configuration.html
1つ注意なのは、 update_function_configuration で全環境変数の指定が必要なことです。update_function_configuration はLambda環境変数をまるごと置き換えるので、例えば3つ環境変数があるのに1つの環境変数しか更新指定しないと、それ以外の2つの環境変数自体が消えてしまいます。

例えばPythonだと以下のように書けます。

import os
import boto3

def lambda_handler(event, context):
    cached_value = get_cached_value()
    update_cached_value('new value')

# Lambda環境変数から前回の値を取得
def get_cached_value():
    return os.environ.get('CACHED_VALUE')

# Lambda環境変数を更新
def update_cached_value(new_value):
    lambda_client = boto3.client('lambda')
    # 環境変数全てを指定しないと消えてしまうので注意
    lambda_client.update_function_configuration(
        FunctionName='Lambdaの名前',
        Environment={
            'Variables': {
                'CACHED_VALUE': new_value,
                'OTHER_VALUE1': os.environ.get('OTHER_VALUE1'),
                'OTHER_VALUE2': os.environ.get('OTHER_VALUE2')
            }
        }
    )

このとき、Lambda実行IAMロールに lambda:UpdateFunctionConfiguration の権限が必要です。以下のようなポリシーをLambda実行ロールにアタッチしてください。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "lambda:UpdateFunctionConfiguration",
            "Resource": "LambdaのARN"
        }
    ]
}

Pros

  • コールドスタートでも値が消えない

Cons

  • グローバル変数よりは手順が多い

Discussion