👌

Lambdaメモ

2024/09/05に公開

Lambda入門のため学んだこと

Lambda

アップロードしておいた関数をイベント駆動で実行する仕組み。サーバレスでサーバーの管理が不要。
つまり、OSやソフトウェアのバージョンアップや障害対応などLambdaの稼働基盤について負荷がないということになる。この辺はAWSが管理してくれているので安心。
EC2もオンプレサーバーも触る機会があったが、従量課金で柔軟にキャパシティを変更できるEC2がとっても楽だった。
しかしLambdaに至っては、実行時間に対しての課金となるので物によっては結構なコストカットも見込めるという。

Lambdaの使いどころ、制約

・必要に応じたスケーリング
・マルチAZで稼働する
・実行時間課金
・基盤はAWSが管理
・ステートレス
・アップロードファイルのサイズ制約(50MB 展開後250MBまで)※コンテナイメージのLambdaはこの限りでなはない。
・最大実行時間は15分
・疎結合のアーキテクチャの実現

ここからわかることは、Lambdaは、軽量で常時稼働の必要がなく、イベントによって起動するような処理が適しているということ。
定期実行や障害時にのみ動くジョブのために常時起動しているようなサーバーがあればLambdaを検討するのも良いかも。

Lambdaの入力値と戻り値 eventとは?

Lambda関数(ハンドラー)の入力値、戻り値はJSONが基本。
使用言語ごとにJSONはパースされてからeventにはいるので実際は、
event['test']のようにJSON文字列は辞書型として格納される。

またlambdaハンドラの取れる引数はevent(トリガー元から渡されたイベントデータ)とcontext(Lambdaに関するメタデータが格納)の二つがサポートされている。(Lambdaによって決まっている)
Lambdaハンドラ以外にも関数の定義ができるのでメイン処理に組み込む関数は普通のプログラミング同様自由に作れる。

def lambda_handler (event, context):
    a = func_a(c,d)
    b = func_b()
    return

def func_a(c,d):
    e = c + d
    return e

def func_b():
    return xxx

Lambdaの設定項目 権限/使用メモリ/タイムアウト/リトライ/環境変数

Lambdaの実行権限

設定⇨アクセス権限よりアタッチされたIamRole確認できる

Lambdaは他のAWSサービスとやりとりをすることが多いので都度IamRoleに権限を追加する必要がある。デフォルトでCloudwatchLogsに書き込む権限が付与される。
具体的には、

Allow: logs:CreateLogStream
Allow: logs:CreateLogGroup
Allow: logs:PutLogEvents

この三つはそれぞれ
ロググループ:対象Lambda処理のログをまとめる大きな箱を作成
ログストリーム:時系列でLambdaログを吐き出す出力先を作成
ログへの書き込み権限
となる。

補足)ログの書き込み

pythonなら

import logging

def lambda_handler(event,context):
    # loggerの作成
    logger = logging.getLogger('my_logger')

    #ログレベルを設定 (DEBUG, INFO, WARNING, ERROR, CRITICAL)
    logger.setLevel(logging.INFO)
    a = "test"
    logger.info(a)

のような形でログをログストリームへ吐き出すことが簡単にできる。

使用メモリ

設定⇨一般設定より変更可能
基盤はAWSマネージドだが、Lambdaの使用できる上限が設定できる。

タイムアウト

設定⇨一般設定より変更可能
実行時間の設定ができる。最大15分。

※メモリの確保量と実行時間で料金は変動

[Lambdaベストプラクティス]
(https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/best-practices.html)

・接続エラーの解消

Lambda は、時間の経過とともにアイドル状態の接続を消去します。関数を呼び出すときにアイドル状態の接続を再利用しようとすると、接続エラーが発生します。永続的な接続を維持するには、ランタイムに関連付けられている keep-alive ディレクティブを使用します。例については、「Node.js で Keep-alive を使用して接続を再利用する」を参照してください。

・環境変数の利用(設定⇨環境変数より設定)

たとえば、Amazon S3 バケットに書き込む場合、書き込み先のバケット名はハードコーディングせずに、環境変数として設定します。

・意図しない料金増を防ぐ(制御を考慮せず再帰呼び出しを行わない)&対処
然るべき条件設定のもと再起呼び出しを設定する。
再帰無限ループが発生した(あるいはトリガーとLambda起動の無限ループ)
場合には

すぐに関数の予約済同時実行数を 0 に設定して、コードを更新している間のすべての関数の呼び出しをスロットリングします。

SQS,SNSに関連する再帰ループは検知と停止が可能!
デフォルトは再帰ループを終了が選択されている。
設定⇨同時実行と再起の検出⇨再帰ループ検出より設定

・Lambdaパフォーマンス調整
CloudWatchLogsのログストリームには使用されたメモリと最大値が記録されます。
この最大値を参照して適切なメモリ割り当てを変更します。

・実行環境の再利用を活用と注意点
実行環境はLinuxコンテナが実態として存在する。そのためコード中から/tmpなども活用できる。
一度コードを読み込ませたら実行環境が作られるため以降の実行ではこの環境が再利用されるため実行時間の短縮とコストが節約される。
その一方でコード中で実行環境中にデータを/tmpに置くなどする処理がある場合には、その環境は次回実行時にも再利用された際に意図しない挙動となる恐れがある。
実行環境関連で、関数内のイベントハンドラ関数(lambda_hanler())はイベントのたびに呼び出されるが、それ以外のプログラムは初回にプログラムファイルが呼ばれた際にだけ実行されることに注意が必要。
イベントごとに呼び出されることを保証したいコードはハンドラーかハンドラーから呼び出される箇所に書く。

Discussion