Skip to main content

Lambda

Lambdaが台頭した理由
AWSのLambdaを色々暴く

Overview

イベントの発生に応じてプログラムを実行する(AWSが提供するイベントドリブンなプログラム)環境を提供する、クラウドコンピューティングサービス。
マルチAZ構成もできる。

Image from Gyazo

Lambdaを採用する方針

  • 非同期な通信処理
    • イベント駆動で処理をするサービスにはLambdaを採用する。
  • 同期的な通信処理
    • APIなどを提供するサービスにはECSを採用する。

Lambdaを採用する例文

すでにユーザー数が増加してアプリケーション全体のパフォーマンスが劣化していることに加えて、アプリケーションの運用業務の比率も高まっています。 また開発期間が長くなることも懸念しています。さらに、今後もユーザー数、そして購入数が増えることを考えたときに、領収書を作る機能をSampleBookStoreの中心的な機能から切り離すことにより、負荷の軽減ができると考えました。要件として購入と同期的に実行する必要がなく、「なるべく早く」で十分な点もポイントです。筆者自身の実体験としても、購入後にすぐ領収書が必要だとしても数分間は待てますし、場合によっては月末の経費精算時にまとめてダウンロードすることもあります。また、セール時期など、大量に購入が行われる時期には領収書を作る機能にもより負荷がかかります。こういった背景から、非同期処理として実装することが望ましいと考えました

Lambdaコスト

  • functionに対する合計リクエスト数 リクエスト数は、Amazon SNSやAmazon EventBridgeなどのイベント通知トリガーや、Amazon API Gateway、AWSコンソールからのテスト呼び出しを含むAWS SDKなどのAPIコールに応じて実行を開始するたびに、リクエストをカウントする。
  • functionの合計実行時間 実行時間は、コードの実行が開始された瞬間からその処理が返される、もしくは中止されるまでの時間で計算され、値は1ミリ秒単位で切り上げられる。 また単位課金額はLambda関数に当てられたメモリー量により異なる。 Lambdaのリソースモデルでは、利用者が関数に必要なメモリー量を指定すると、それに比例したCPUパワー(x86とArm)とその他のリソースが割り当てられる。

Image from Gyazo

note

毎月100万リクエストまで無料

Lambda パフォーマンスチューニング

Lambda パフォーマンスチューニング

  1. コールドスタートの解決 Lambdaを定期実行する方法があるが、これは根本的に解決にならない。
    メモリ量を上げてもコールドスタートの起動時間は解決されない。

  2. 依存ライブラリを減らす 外部モジュールの展開は非常にコストが高い。
    依存ライブラリを減らすことでコールドスタート時のオーバーヘッドを改善できる。

Lambdaの制限

  • 並行実行 1ユーザーが1000リクエストをほぼ同時に送った場合、AWS Lambdaは理論的には1000の異なるコンテナインスタンスを立ち上げることができる。 これにより、各リクエストが並行して高速に処理されることが保証される。
  • 同時実行数の制限 AWS Lambdaには同時実行数の制限がある。 デフォルトのリージョンあたりのリミットは1000だが、これはリクエストすることで増やすことができる。
  • スロットリング 上記の同時実行数の制限に達した場合、Lambdaは新しい関数の実行リクエストをスロットル(一時制限)する可能性がある
  • Lambda容量制限 zip圧縮後50MB zip圧縮前250MB また、Lambda deployに関してコンテナイメージのサポートが導入されておりその場合は10GBで良いとのこと。

Lambda コールドスタート

これまでの常識は間違っていた?!Lambdaのコールドスタート対策にはメモリ割り当てを減らすという選択肢が有効に働く場面も
参考URL

  • コールドスタート 最初のリクエストや、長時間アイドル状態だった後のリクエストでは、新しいコンテナを立ち上げるためレイテンシが少し高くなる。 この状態を「コールドスタート」と呼ぶ。
  • ウォームスタート 関数が続けて呼び出される場合、前回の実行のためにすでに起動しているコンテナを再利用される可能性がある。

グローバルな環境で変数を設定すると再利用される可能性がある。 これはAWS Lambdaには関数実行時に実行環境として起動したコンテナをある程度の期間再利用する動作仕様(ウォームスタート)があり、それに伴い/tmpディレクトリ上のデータも次回の処理で再利用される動作となる。

// 以下で始まるところに変数を宣言した方が良い得策
// グローバルに変数を定義するとウォームスタートで利用される可能性がある。
// 再利用される時間と可能性はブラックボックス
const global = new Date();
exports.handler = async (event) => {}
const local = new Date();

console.log(global); // global は再利用されるため時間が更新されない
console.log(local); // localは逐一時間が更新される

Lambdaに合わないアーキテクチャー

コスト効率の悪いLambdaアプリケーションの性質に関する考察

Lambda関数の呼び出しパターン

Lambda関数には同期呼び出し・非同期呼び出し・イベントソースマッピングの3つの呼び出しパターンがある。

同期呼び出し

Image from Gyazo

Lambdaが呼び出されたら、コードが実行されすぐにレスポンスが戻ってくる呼び出し方法。
実行するクライアントサイドとLambda処理するサーバーサイドが同じタイミングで同期している。
以下のパターンが同期呼び出しとなる。

  • AWS SDK
  • AWS CLI
  • ALB
  • API Gateway
  • テストイベントを使用した方法

非同期呼び出し

Image from Gyazo

呼び出してもすぐにはLambda関数を実行せずに実行結果もすぐには返ってこない呼び出し方法。
実行するタイミングと、Lambda処理するタイミングが異なるものは非同期呼び出しになる。
同期呼び出しと比べれば並列処理ができるという特徴があり、1回の実行ごとにレスポンスを待つ必要がないため、一度にたくさんの画像処理が行える。
Lambdaと連携して非同期実行が行えるサービスは以下の通り。

  • S3
  • Amazon SNS
  • Amazon SES
  • CloudFormation
  • CloudWatch Logs
  • EventBridge
  • CodeCommit
  • AWS Config

イベントソースマッピング

Image from Gyazo

イベントソースのマッピングは、イベントソースからデータを読み取り、Lambda関数を呼び出すLambdaリソースのことを指します。イベントソースマッピングは、直接Lambda関数を呼び出さないサービスのキューまたはストリームから項目を処理するときに使用できます。

Lambda 並列起動(同期・非同期)・再利用の動作検証

AWS Lambda+Node.jsのコンテナ並列起動(同期・非同期)・コンテナ再利用の動作検証

  • Lambdaは1実行で1プロセスを占有する。
  • 同期処理を実行しても他のLambda(プロセス)実行に影響しない。
  • 非同期処理を実行しても実行中のLambda(プロセス)で他のLambda実行が処理されることはない。
  • コンテナ同時実行数の上限に達すると実行中のコンテナが終了されるまで特定回数リトライされる。
  • コンテナ実行後、一定時間内に同じ関数を再実行するとコンテナが再利用される。
  • Lambda実行毎にプロセスが完全に分離しているため、コンテナ再利用+グローバル変数を変化させるコードを書いても問題なし。

Lambda Function URLs

2022年4月にLambda Function URLsの機能がサポートされた。
Lambda関数を他のAWSサービスと連携せずに、単純にHTTP(S)リクエストで使用したいケースがある。
その場合、従来はAPI Gateway経由でLambda関数を実行する必要があった。
Lambda Function URLsを利用することで、API Gatewayを経由せずに、専用のエンドポイントURLにHTTPリクエストするだけでLambda関数を実行できるようになった。

note

Lambdaをパブリックに公開したり、シンプルな認証でも問題ない場合は、Lambda関数URLは便利。

Lambdaのセキュリティ

Lambdaの落とし穴 - 脆弱なライブラリによる危険性とセキュリティ対策

LambdaにはEIP(Elastic IP)を割り当てられない

Lambda用 VPCネットワーク

Lambdaが実行されるところ

Lambda関数は常にLambdaサービスが所有するVPC内で実行される
LambdaはこのVPCにネットワークアクセスとセキュリティルールを適用し、VPCを自動的に維持および監視します。

LambdaをVPC外のリソースにアクセスさせる

参考URL

defaultではNATを使って対応する。
その場合はloggerなどの出力はインターネットを介して取得される。 そのため、セキュリティ的な懸念がある場合は VPC Endpoint を使用する。

Lambda関数に求められる実装

実装&キャッシュについてまとまっている

AWSの公式ドキュメントによると、AWS Lambdaの関数はステートレスな実装にする必要がある。
一方でステートレスな実装を追求すると、外部サーバからのデータ取得処理が増え、結果として処理パフォーマンス悪化を引き起こす場合が多い。

ステートレスな実装を謳っているが /tmp ファルダの提供があるため少なからずキャッシュの利用は可能そう。

Lambda関数はあらゆる状態を持たない実装にすべき」ことを示すのではなく、「外部にマスタがある静的なデータはLambda関数上のキャッシュとして保持し、次回リクエスト時に再利用して良い」

Lambda Layers

Lambda Layersを作成(GUI版)

Lambda Layersでライブラリを共通化(GUI版)

Lambda Layersとは、複数のLambda関数で外部ライブラリやビジネスロジックを共有できる仕組み。 使用するライブラリや共通のビジネスロジックをZIPアーカイブしLayerに追加できる。

制限

1つのLambda関数では5つのLayerのみ使用できる。 また、Lambda関数とLayerの解凍後の合計サイズが250MB以下となる必要がある。

Lambda Layersの配置先

作成したLayerは、Lambdaの実行環境の /opt ディレクトリに展開されます。 /optディレクトリ以下に、ランタイムの言語ごとのディレクトリが構成されているので、ランタイムに合わせてLayerを構築する必要があります。

Pythonを例にとると、Lambdaの実行環境は/opt/python/とディレクトリが構成されているため、作成するLayerは展開される構成が/opt/python/"作成したLayer"となる必要があります

Lambda Layersを作成(Serverless版)

参考URL

Lambdaでenvを管理しない方がいい理由

Lambdaには、サードパーティーライブラリをアップロードして組み込むことができる。
しかし、導入したライブラリやそのライブラリが依存する他のライブラリに対してセキュリティ的に問題ある脆弱性含まれる可能性が常に付きまとう。

Tips

LambdaのJest Test
Lambdaを最低限ローカルで実行しテストする(簡単)
Lambda TypeScript middy:middyについて
Lambdaをexpressでdeployする

CLIから実行する方法

aws lambda invoke --function-name [function-name] --cli-binary-format raw-in-base64-out --payload '{"type": "show"}' a.json

--payload はLambdaがリクエストを受け取ったときにjsonとしてparseしてくれる。

export const handler: Handler<RequestSchema> = async (event, context) => {
console.log(event.type)
};

LambdaではAWS-SDKが必要ない

LambdaにはAWS SDKがインストールされている。

npm install で NPM パッケージをインストールするとき、実行時に必要なものは --save で、開発時のみ必要なものは --save-dev でインストールします。 この考え方からすると、AWS SDK (@aws-sdk) は --save オプションでインストールするのが自然なのですが、Lambda 関数用のプロジェクトではちょっと事情が違ってきます。 なぜなら、AWS の Lambda 実行環境にはデフォルトで AWS SDK がインストールされているからです。

Lambdaでディレクトリを使用したい場合

参考URL

/tmpディレクトリ Lambdaの公式ドキュメントに、/tmpディレクトリに対して以下の記述がある。

各実行環境は、/tmp ディレクトリ内のディスク領域を 512 MB に提供します。ディレクトリのコンテンツは、実行環境が停止された際に維持され、複数の呼び出しに使用できる一時的なキャッシュを提供します。キャッシュに保存したデータが存在するかどうかを確認するための追加コードを追加できます。デプロイのサイズ制限の詳細については、「Lambda のクォータ」を参照してください。

512MBの一時領域(/tmp ディレクトリ)が提供されている。そのためそちらを使用しファイルの出力と書き込みを行える。
Lambda上でAWS CLIを実行したいと思いました。 AWS CLIにはs3 syncコマンドのような、SDKには未実装の便利な機能があるためです。
Lambdaの実行環境にはAWS CLIはプリインストールされていないので、ひと工夫が必要になります。

Lambdaの前段に置くべきもの

AWS Lambda:API GatewayとApplication Load Balancerの違い