Lambda Version
Lambdaではコードを更新したあと、Versionを発行して特定状態の関数を固定できます。
例えば、
$LATEST
│
├─ publish
▼
Version 1
コード更新
$LATEST
│
├─ publish
▼
Version 2
Version 1とVersion 2は、それぞれ独立した状態として扱えます。
Lambda Alias
Versionを直接利用するだけでは、Version番号をアプリケーション側で管理する必要があります。
そこで使用するのがAliasです。
prod
↓
Version 1
というAliasを作成できます。
新しいVersion 2を本番にしたい場合は、
prod
↓
Version 2
へAliasの参照先を変更できます。
Weighted Alias
新しいVersionをいきなり100%公開するのではなく、
┌─ Version 1:90%
Request → prod
└─ Version 2:10%
のようにトラフィックを分割でき、新Versionへ少しずつトラフィックを流せます。
以下のような段階的な移行も可能です。
Version 1:90%
Version 2:10%
↓
Version 1:50%
Version 2:50%
↓
Version 2:100%
このように、新Versionへ一部のトラフィックだけを流して問題がないことを確認してから移行する方法をCanary Releaseと呼びます。
Weighted Aliasでトラフィックを分割できるのは公開済みの2つのVersion間であり、$LATESTは対象にできません。
ロールバック
新Versionで問題が発生した場合は、Aliasを旧Versionへ戻します。
prod
↓
Version 1
コードを再デプロイするよりも素早く切り戻せます。
Lambda Layers
複数のLambdaで同じライブラリを使用するとします。
Lambda A
├─ application.py
└─ common-library
Lambda B
├─ application.py
└─ common-library
Lambda C
├─ application.py
└─ common-library
これでは各Lambdaに同じライブラリを含める必要があります。
そこで利用できるのがLambda Layersです。
┌─ Lambda A
Layer ───────┼─ Lambda B
└─ Lambda C
ライブラリや共通コードを関数本体から分離できます。
ただし、ZIP形式のLambdaでは関数コードとLayersを合わせた展開後サイズが最大250MBという制限があります。
また、1つのLambda関数で利用できるLayerは最大5つです。
そのため、大容量のライブラリや機械学習モデルなどを利用する場合は、用途に応じてAmazon EFSやLambda Container Imageを検討します。
共通ライブラリ
→ Lambda Layers
大容量の共有ファイル
→ Amazon EFS
大容量の実行環境・依存関係
→ Container Image
Container ImageとしてデプロイするLambdaでは、Lambda Layersは利用できません。
Lambdaの一時ストレージ /tmp
Lambdaには一時ファイルを保存できるEphemeral Storageがあります。
Lambda内では、/tmpとして利用できます。
デフォルトでは512MBで、設定によって最大10,240MB(10GB)まで拡張できます。
画像や動画などの一時的なファイル処理であれば、Lambdaのローカル領域を利用できます。
S3
↓
Lambda
↓
/tmp で一時処理
↓
S3
Lambda MemoryとCPU
Lambdaでは、Memory設定が単純なメモリ容量だけを意味するわけではありません。
Memoryを増やすことで、CPUなどの計算リソースも増加します。
そのため、以下のようなCPU負荷の高い処理を高速化したい場合に効果的です。
動画変換
画像処理
大量計算
圧縮処理
Reserved Concurrency
Reserved Concurrencyは、特定のLambdaが使用できる同時実行数を確保しつつ、上限も設定する機能です。
Lambda A
Reserved Concurrency = 100
と設定すると、その関数用の同時実行枠を確保し、同時にその関数が利用できる同時実行数の上限にもなります。
予約したConcurrencyは他のLambdaから利用できないため、大きすぎる値を設定すると、他のLambdaが利用できる未予約のConcurrencyが減る点にも注意が必要です。
Provisioned Concurrency
Provisioned Concurrencyは、Lambdaの実行環境を事前に初期化しておく機能です。
これによって、初期化による遅延(Cold Start)を抑えられます。
事前に実行環境を準備
↓
Request
↓
Function実行
Provisioned Concurrencyは公開済みVersionまたはAliasに設定します。
$LATESTには設定できません。
SQS × Lambda Maximum Concurrency
SQS Event Source MappingのMaximum Concurrencyを使用することで、そのSQSキューからLambdaへ発生する同時実行数を制御できます。
SQS
↓
Event Source Mapping
Maximum Concurrency = 2
↓
Lambda
↓
External API
例えば外部APIへの同時リクエストを増やしすぎたくない場合などに利用できます。
SQS Event Source MappingのMaximum Concurrencyは2以上で設定します。
Batch Size
Batch Sizeは、1回のLambda呼び出しでSQSから取得するメッセージの最大件数を設定する機能です。
SQS
Message 1
Message 2
Message 3
Message 4
Message 5
↓
Batch Size = 5
↓
Lambda 1回呼び出し
Maximum Concurrencyとは制御する対象が異なります。
Batch Size
→ 1回のLambda呼び出しで何件処理するか
Maximum Concurrency
→ Lambdaを何個まで同時実行するか
そのため、Batch Sizeを小さくしてもLambda自体の同時実行数を制限できるわけではありません。
Event Source Mapping
LambdaとSQS、DynamoDB Streams、Kinesisなどのサービスを連携するときに、Event Source Mappingを使用します。
Event Source MappingがイベントソースをPolling(ポーリング)し、取得したレコードをLambdaへ渡します。
SQS / DynamoDB Streams / Kinesis
↑
Polling
│
Event Source Mapping
│
↓
Lambda
例えばDynamoDB Streamsを有効にしただけでは、Lambdaが自動的に接続されるわけではありません。
DynamoDB
↓
DynamoDB Streams
↓
Event Source Mapping
↓
Lambda
Event Source MappingによってLambdaとの関連付けが必要です。
Event Filtering
特定のイベントだけをLambdaで処理したい場合、Event Source Mapping側でEvent Filteringを設定できます。
INSERT → 処理する
MODIFY → 除外
REMOVE → 除外
のようにフィルタリングできます。
Lambdaを起動してから不要なイベントを捨てるのではなく、不要なInvocationそのものを減らせます。
LambdaからVPC内リソースへアクセス
Lambdaから、
Private EC2
RDS
Aurora
EFS
などVPC内のPrivate Resourceへアクセスする場合は、Lambdaを対象VPCへ接続します。
Lambda
│
│ VPC Configuration
▼
Private Subnet
│
├─ RDS
├─ EC2
└─ EFS
Security Groupの設定も必要になります。
また、VPCへ接続したLambdaのネットワークアクセスは、接続先VPCのネットワーク構成に依存します。
例えば、IPv4でインターネット上の外部APIへアクセスする場合は、一般的に以下のような構成を使用します。
Lambda
↓
Private Subnet
↓
NAT Gateway
↓
Internet Gateway
↓
Internet
LambdaをPublic Subnetへ接続しただけではPublic IPは付与されないため、それだけでインターネットへアクセスできるわけではありません。
一方、S3などの対応するAWSサービスへPrivateにアクセスする場合は、VPC Endpointも選択肢になります。
Lambda × RDS Proxy
Lambdaは短時間で大量にスケールできます。
Lambda ─┐
Lambda ─┤
Lambda ─┼→ RDS Proxy → RDS
Lambda ─┤
Lambda ─┘
各LambdaがRDSへ直接接続すると、大量のデータベース接続が発生する可能性があります。
そこでAmazon RDS Proxyを利用することで、データベース接続をプールして効率的に管理できます。
LambdaからRDSへ大量接続
↓
RDS Proxy
非同期LambdaとDLQ
Lambdaの非同期呼び出しでは、処理に失敗したイベントを**Dead Letter Queue(DLQ)**へ送信できます。
Event
↓
Lambda
↓
処理失敗
↓
Retry
↓
DLQ
関数がエラーを返した場合、非同期呼び出しではデフォルトで追加の再試行が2回行われます。
それでも処理できなかった場合、設定していればSQSやSNSのDLQへ失敗したイベントを送信できます。
DLQは失敗時のみを対象とし、基本的に元のイベントを保存します。
DLQは自動的に設定されるわけではないため、必要に応じて設定します。
Lambda Destinations
非同期Lambdaでは、Lambda Destinationsを使用して処理結果を別のサービスへ送信できます。
Lambda
├─ 成功 → Destination
│
└─ 失敗 → Destination
Destinationsでは、元のイベントだけでなく、実行結果などの情報を含むInvocation Recordを送信できます。
DLQとの違い
| 機能 | DLQ | Destinations |
|---|---|---|
| 対象 | 失敗 | 成功・失敗 |
| 送信内容 | 元のイベント | Invocation Record |
| 主な用途 | 失敗イベントの退避 | 実行結果に応じた後続処理 |
どちらもLambdaの非同期呼び出しにおけるエラー処理で重要になります。
Lambdaの冪等性
イベント駆動の処理では、同じイベントが複数回届く可能性を考慮する必要があります。
例えば注文処理で同じ注文IDが2回来ても、二重処理されないようにします。
単純に、
処理済み?
↓
未処理なら処理
↓
IDを保存
とすると、同じイベントがほぼ同時に到着した場合、両方が「未処理」と判定してしまう可能性があります。
そこで、DynamoDBの**Conditional Write(条件付き書き込み)**などを利用します。
Lambda
↓
DynamoDB
↓
注文IDを条件付きで登録
attribute_not_exists(注文ID)
↓
成功 → 初回なので処理
失敗 → すでに存在するため重複処理しない
このように、同じ処理を複数回実行しても結果が変わらないようにする性質を冪等性(Idempotency)と呼びます。
Lambda Function URL
Lambdaには、関数へ直接HTTPSエンドポイントを作成できるFunction URLがあります。
Client
↓ HTTPS
Function URL
↓
Lambda
認証方式として、主に以下があります。
NONE
→ IAM認証なし
AWS_IAM
→ IAMによる認証あり
IAMで認証されたユーザーやロールだけに実行させたい場合は、AWS_IAMを使用します。
NONEを利用して公開する場合でも、LambdaのResource-based Policyで適切な呼び出し権限を設定する必要があります。
API Gatewayの高度なAPI管理機能が不要で、LambdaをシンプルにHTTP公開したい場合に利用できます。