Lambdaで次回実行まで値を保持する簡単な方法2つ
はじめに
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環境変数を更新できます。
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