スライド/Python LambdaのSnapStartとAWS Lambda Powertools version 26
:追加された部分
:削除された部分
(差分が大きい場合、文字単位では表示しません)
スライド/Python LambdaのSnapStartとAWS Lambda Powertools
## 自己紹介
- 夏目 祐樹 (ナツメ ユウタ)
- クラスメソッド
- 製造ビジネステクノロジー部
- 好きなAWS Service
- Lambda, DynamoDB, SQS, S3
- 近況
- FF7 Rebirthを100時間以上プレイするもクリアまで行かず
---
## Cold Start
---
## Cold Start
![[9005460307943389] perf-optimize-figure-1](https://mimemo.s3-ap-northeast-1.amazonaws.com/attachment/8c497cf2-dbeb-4943-9a69-3d9c33375fb9.png)
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/lambda-runtime-environment.html#cold-start-latency
- AWS公式の考え方ではMicro VMの作成までがコールドスタート
- 再実行時はハンドラの実行から
- 広義の考え方ではコードの初期化も含める
---
## Cold Start
- どうしてもコードの初期化で初回の実行は遅くなる
- Pythonのboto3の読み込みでも1秒くらいかかる
- Pandasとか重いライブラリを読めばもっとかかる
- GoやRustなどシングルバイナリを生成するような言語ではコールドスタートもウォームスタートも大した差にはならない
---
## ユーザーのくふう (1)
- 手動ウォームアップ
- 何らかの手段でLambdaを実行させCold Startを回避する
- ただし
- 手動ウォームアップの実行中にリクエストが来たらCold Startが起きる
- 事前に立ち上げた数よりも多いリクエストが来たらCold Startが起きる
---
## ユーザーのくふう (2)
- Lambdalith (Monolithic function)
- 1つのLambdaで複数のイベントを処理する
- 例えば、APIで複数のパスを一つのLambdaで処理する
- ただし、Cold Startを多少抑制できる程度
---
## AWSのくふう (1)
- Provisioned Concurrency
- AWSによる自動ウォームアップ
- ただし
- 設定した実行数よりも多いリクエストが来たらCold Startが起きる
- ウォームアップしている期間についても課金される
---
## AWSのくふう (2)
- Snap Start (Java)
- re:Invent 2022で発表された機能
- Java 11以降で使用可能
- コードの初期化済みの環境をキャッシュし、そこから実行することで広義のコールドスタートを高速化する
---
## Pythonと.NETでSnapStartのサポートを開始
---
## AWSのくふう (3)
- SnapStart (Python, .NET)
- 2024/11/18から利用できるようになった
- Python 3.12 以降と .NET 8以降で使用可能
---
## SnapStartの特徴
- 初期化された実行環境のメモリとディスク状態のFirecracker microVMのスナップショットを保存し、それを再利用することで初回実行を高速化する
- スナップショットの保存はLambda関数のバージョン発行時
- 使用できるリージョンは9つ
- バージニア北部, オハイオ, オレゴン, シンガポール, シドニー, 東京, フランクフルト, アイルランド, ストックホルム
---
## SnapStartの課金体系
- Pythonと.NETでは使用に料金がかかる (Javaは無料)
- Lambda関数のバージョン毎に課金される
- 課金体系は二つ
- キャッシュの保存期間
- 最低3時間, 以後ミリ秒単位で課金
- USD 0.0000015046/GB*秒
- USD 3.9540888/GB*月 (730h/月)
- キャッシュのレストア回数
- USD 0.0001397998/GB*回
- 7153.1回*GB/USD
---
## Python RuntimeのSnapStart (1)
- Handlerに設定しているPythonファイルをインポートしてから、キャッシュが作成される
- そのためグローバル領域での処理は行われる
---
## Python RuntimeのSnapStart (2)
```python
import json
from datetime import datetime, timezone
dt_cache = datetime.now(timezone.utc)
def lambda_handler(event, context):
data = {
"cache": str(dt_cache),
"now:": str(datetime.now(timezone.utc))
}
text = json.dumps(data)
print(text)
return data
```
---
## Python RuntimeのSnapStart (3)
```js
{
"cache": "2025-02-07 18:19:44.945058+00:00",
"now:": "2025-02-07 18:22:03.355189+00:00"
}
```
```js
{
"cache": "2025-02-07 18:19:44.945058+00:00",
"now:": "2025-02-07 18:22:13.156636+00:00"
}
```
---
## Python RuntimeのSnapStart (4)
- グローバル領域でデータを取得するように書けば、事前に大きなデータをダウンロードしておくこともできる
- バージョン発行時に取得するので、動的に何かを取得するようなことでは注意が必要
- バージョン発行時なので環境変数も保持されている
---
## Python RuntimeのSnapStartの注意点
- SnapStartのキャッシュ課金はLambda関数のバージョン毎に行われる
- バージョンを保存するか削除するかをきちんと管理しないと、アップデートのたびに料金が増えていく
---
## SAMで最新バージョンのみ残す書き方
```yaml
Transform: AWS::Serverless-2016-10-31
Resources:
Function:
Type: AWS::Serverless::Function
DeletionPolicy: Delete
Properties:
AutoPublishAlias: prod
...
```
---
## CDKで最新バージョンのみ残す書き方
```js
const myFunction = new lambda.Function(this, "cdk-latest-version", {
runtime: lambda.Runtime.PYTHON_3_13,
handler: "main.handler",
code: lambda.Code.fromAsset(path.join(__dirname, "../src")),
currentVersionOptions: {
removalPolicy: cdk.RemovalPolicy.DESTROY,
},
});
myFunction.addAlias("prod");
```
---
## Terrafromで最新バージョンのみ残す書き方
- 残念ながら設定方法を見つけることはできなかった
- `Ephemeral Resource: aws_lambda_invocation`を使って、バージョン発行後にLambdaを動かして過去のバージョンを削除刺せる必要がある
---
## SnapStartのPython対応を見て思ったこと
- SnapStartを使用するLambda関数が増えれば増えるほど課金額が増えていく
- 一つのLambdaに複数の処理を行わせるLambdalithの有用性が高まった
---
## Lambdalith (Monolithic Lambda Function)
- API GatewayのバックエンドのLambdaを一つにまとめるのは前から行われて生きた
- Pythonでは `Flask + aws-wsgi`を使う例を見たことある人がいるかもしれない
- ただ、外部ライブラリを使うのでLayerかデプロイパッケージに含める必要がある
---
## AWS Lambda Powertools
---
## AWS Lambda Powertools
- AWSが公式に提供しているOSS
- Lambdaで使える便利ツール群
- Public Layerが用意されているため簡単に使える
- LoggerやValidation, Event Source Data Classesなど便利なものがいっぱいある
---
## EventHandler - AWS Lambda Powertools
- 端的に言うとLambdalithを作りやすくするための仕組み
- 大きく分けると
- REST API
- API Gateway (REST, HTTP), ALB, Lambda Function URL, VPC Lattice
- GraphQL API
- Agent for Amazon Bedrock
---
## 非同期実行のLambda用のIssueとPR作成 (1)
![[9005460264645687] スクリーンショット 2025-02-08 13.47.54](https://mimemo.s3-ap-northeast-1.amazonaws.com/attachment/43221580-7873-4f2b-8e07-ae387fb5b7e9.png)
---
## 非同期実行のLambda用のIssueとPR作ってみた (2)
## 非同期実行のLambda用のIssueとPR作成 (2)
![[9005460264530344] スクリーンショット 2025-02-08 13.49.59](https://mimemo.s3-ap-northeast-1.amazonaws.com/attachment/10494e59-7018-4f06-8001-831cd5b478ac.png)![[9005460264530344] スクリーンショット 2025-02-08 13.49.59](https://mimemo.s3-ap-northeast-1.amazonaws.com/attachment/10494e59-7018-4f06-8001-831cd5b478ac.png)
---
## 非同期実行のLambda用のIssueとPR作成 (3)
> この問題に関しては、私はこのアイデアがとても気に入っていて、2025年のロードマップで議論しているところです。 これは、多くのサービス用の汎用イベント・ハンドラになる可能性がある: S3、StepFunctions、EventBridge、SQS、SNS、そしてイベントのどの部分をルートとして使うか、正規表現、文字列の一部、様々な可能性を決めることができる。 これは、例えばEventBridgeを扱っていて、いくつかのイベントに対して一つのLambdaを使いたい人たちの生活を楽にするだろう。 この新しいユーティリティには多くの利点があると思うし、2025年にリリースできたらクールだと思う。
自己紹介
- 夏目 祐樹 (ナツメ ユウタ)
- クラスメソッド
- 製造ビジネステクノロジー部
- 好きなAWS Service
- Lambda, DynamoDB, SQS, S3
- 近況
- FF7 Rebirthを100時間以上プレイするもクリアまで行かず
Cold Start
Cold Start
- AWS公式の考え方ではMicro VMの作成までがコールドスタート
- 再実行時はハンドラの実行から
- 広義の考え方ではコードの初期化も含める
Cold Start
- どうしてもコードの初期化で初回の実行は遅くなる
- Pythonのboto3の読み込みでも1秒くらいかかる
- Pandasとか重いライブラリを読めばもっとかかる
- Pythonのboto3の読み込みでも1秒くらいかかる
- GoやRustなどシングルバイナリを生成するような言語ではコールドスタートもウォームスタートも大した差にはならない
ユーザーのくふう (1)
- 手動ウォームアップ
- 何らかの手段でLambdaを実行させCold Startを回避する
- ただし
- 手動ウォームアップの実行中にリクエストが来たらCold Startが起きる
- 事前に立ち上げた数よりも多いリクエストが来たらCold Startが起きる
ユーザーのくふう (2)
- Lambdalith (Monolithic function)
- 1つのLambdaで複数のイベントを処理する
- 例えば、APIで複数のパスを一つのLambdaで処理する
- ただし、Cold Startを多少抑制できる程度
AWSのくふう (1)
- Provisioned Concurrency
- AWSによる自動ウォームアップ
- ただし
- 設定した実行数よりも多いリクエストが来たらCold Startが起きる
- ウォームアップしている期間についても課金される
AWSのくふう (2)
- Snap Start (Java)
- re:Invent 2022で発表された機能
- Java 11以降で使用可能
- コードの初期化済みの環境をキャッシュし、そこから実行することで広義のコールドスタートを高速化する
Pythonと.NETでSnapStartのサポートを開始
AWSのくふう (3)
- SnapStart (Python, .NET)
- 2024/11/18から利用できるようになった
- Python 3.12 以降と .NET 8以降で使用可能
SnapStartの特徴
- 初期化された実行環境のメモリとディスク状態のFirecracker microVMのスナップショットを保存し、それを再利用することで初回実行を高速化する
- スナップショットの保存はLambda関数のバージョン発行時
- 使用できるリージョンは9つ
- バージニア北部, オハイオ, オレゴン, シンガポール, シドニー, 東京, フランクフルト, アイルランド, ストックホルム
SnapStartの課金体系
- Pythonと.NETでは使用に料金がかかる (Javaは無料)
- Lambda関数のバージョン毎に課金される
- 課金体系は二つ
- キャッシュの保存期間
- 最低3時間, 以後ミリ秒単位で課金
- USD 0.0000015046/GB*秒
- USD 3.9540888/GB*月 (730h/月)
- キャッシュのレストア回数
- USD 0.0001397998/GB*回
- 7153.1回*GB/USD
- キャッシュの保存期間
Python RuntimeのSnapStart (1)
- Handlerに設定しているPythonファイルをインポートしてから、キャッシュが作成される
- そのためグローバル領域での処理は行われる
Python RuntimeのSnapStart (2)
import json
from datetime import datetime, timezone
dt_cache = datetime.now(timezone.utc)
def lambda_handler(event, context):
data = {
"cache": str(dt_cache),
"now:": str(datetime.now(timezone.utc))
}
text = json.dumps(data)
print(text)
return data
Python RuntimeのSnapStart (3)
{
"cache": "2025-02-07 18:19:44.945058+00:00",
"now:": "2025-02-07 18:22:03.355189+00:00"
}
{
"cache": "2025-02-07 18:19:44.945058+00:00",
"now:": "2025-02-07 18:22:13.156636+00:00"
}
Python RuntimeのSnapStart (4)
- グローバル領域でデータを取得するように書けば、事前に大きなデータをダウンロードしておくこともできる
- バージョン発行時に取得するので、動的に何かを取得するようなことでは注意が必要
- バージョン発行時なので環境変数も保持されている
Python RuntimeのSnapStartの注意点
- SnapStartのキャッシュ課金はLambda関数のバージョン毎に行われる
- バージョンを保存するか削除するかをきちんと管理しないと、アップデートのたびに料金が増えていく
SAMで最新バージョンのみ残す書き方
Transform: AWS::Serverless-2016-10-31
Resources:
Function:
Type: AWS::Serverless::Function
DeletionPolicy: Delete
Properties:
AutoPublishAlias: prod
...
CDKで最新バージョンのみ残す書き方
const myFunction = new lambda.Function(this, "cdk-latest-version", {
runtime: lambda.Runtime.PYTHON_3_13,
handler: "main.handler",
code: lambda.Code.fromAsset(path.join(__dirname, "../src")),
currentVersionOptions: {
removalPolicy: cdk.RemovalPolicy.DESTROY,
},
});
myFunction.addAlias("prod");
Terrafromで最新バージョンのみ残す書き方
- 残念ながら設定方法を見つけることはできなかった
Ephemeral Resource: aws_lambda_invocation
を使って、バージョン発行後にLambdaを動かして過去のバージョンを削除刺せる必要がある
SnapStartのPython対応を見て思ったこと
- SnapStartを使用するLambda関数が増えれば増えるほど課金額が増えていく
- 一つのLambdaに複数の処理を行わせるLambdalithの有用性が高まった
Lambdalith (Monolithic Lambda Function)
- API GatewayのバックエンドのLambdaを一つにまとめるのは前から行われて生きた
- Pythonでは
Flask + aws-wsgi
を使う例を見たことある人がいるかもしれない - ただ、外部ライブラリを使うのでLayerかデプロイパッケージに含める必要がある
- Pythonでは
AWS Lambda Powertools
AWS Lambda Powertools
- AWSが公式に提供しているOSS
- Lambdaで使える便利ツール群
- Public Layerが用意されているため簡単に使える
- LoggerやValidation, Event Source Data Classesなど便利なものがいっぱいある
EventHandler - AWS Lambda Powertools
- 端的に言うとLambdalithを作りやすくするための仕組み
- 大きく分けると
- REST API
- API Gateway (REST, HTTP), ALB, Lambda Function URL, VPC Lattice
- GraphQL API
- Agent for Amazon Bedrock
- REST API
非同期実行のLambda用のIssueとPR作成 (1)
非同期実行のLambda用のIssueとPR作成 (2)
非同期実行のLambda用のIssueとPR作成 (3)
この問題に関しては、私はこのアイデアがとても気に入っていて、2025年のロードマップで議論しているところです。 これは、多くのサービス用の汎用イベント・ハンドラになる可能性がある: S3、StepFunctions、EventBridge、SQS、SNS、そしてイベントのどの部分をルートとして使うか、正規表現、文字列の一部、様々な可能性を決めることができる。 これは、例えばEventBridgeを扱っていて、いくつかのイベントに対して一つのLambdaを使いたい人たちの生活を楽にするだろう。 この新しいユーティリティには多くの利点があると思うし、2025年にリリースできたらクールだと思う。