スライド/Python LambdaのSnapStartとAWS Lambda Powertools version 34

2025/02/08 15:11 by sinofseven
  :追加された部分   :削除された部分
(差分が大きい場合、文字単位では表示しません)
スライド/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で使える便利ツール群
  - Python以外の言語もある
- 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)

![[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)

- DeepLによる翻訳と一部抜粋
  - この問題に関しては、私はこのアイデアがとても気に入っていて、2025年のロードマップで議論しているところです。 
  - これは、例えばEventBridgeを扱っていて、いくつかのイベントに対して一つのLambdaを使いたい人たちの生活を楽にするだろう。
  - この新しいユーティリティには多くの利点があると思うし、2025年にリリースできたらクールだと思う。

---

## 非同期実行のLambda用のIssueとPR作成 (4)

- 冬休みの自由研究として、プロトタイプを実装
- 今は単体テストを頑張って書いてる
  - Event Source Data Classes用のイベントデータがあるので単体テストでも割となんとかなる
  - ただし物量が多い

---

## 非同期実行のLambda用のIssueとPR作成 (5)

- 非同期実行用のLambdaが片付いたら
  - イベントソースマッピングのトリガー用のEventHandlerを作ろうかと思ってる
    - 非同期実行用のLambdaの実装で色々意見もらうだろうから、そのあとでIssueを作ろうと思ってる

---

# おまけ

---

## Developers.IO re:Invent 2024 索引 (1)

![[9005460263786569] スクリーンショット 2025-02-08 14.02.09](https://mimemo.s3-ap-northeast-1.amazonaws.com/attachment/26236e33-891b-4183-a0ce-a05ef76d78ed.png)

https://reinvent2024.index.devio.luciferous.app/

---

## Developers.IO re:Invent 2024 索引 (2)

![[9005460263726526] da98d658537028220befab77c4006e38fab05c9d](https://mimemo.s3-ap-northeast-1.amazonaws.com/attachment/1fa853ff-a8d2-4500-af30-28959ba6f2a4.png)      

自己紹介

  • 夏目 祐樹 (ナツメ ユウタ)
  • クラスメソッド
    • 製造ビジネステクノロジー部
  • 好きなAWS Service
    • Lambda, DynamoDB, SQS, S3
  • 近況
    • FF7 Rebirthを100時間以上プレイするもクリアまで行かず

Cold Start


Cold Start

[9005460307943389] perf-optimize-figure-1

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)

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かデプロイパッケージに含める必要がある

AWS Lambda Powertools


AWS Lambda Powertools

  • AWSが公式に提供しているOSS
  • Lambdaで使える便利ツール群
    • Python以外の言語もある
  • 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


非同期実行のLambda用のIssueとPR作成 (2)

[9005460264530344] スクリーンショット 2025-02-08 13.49.59


非同期実行のLambda用のIssueとPR作成 (3)

  • DeepLによる翻訳と一部抜粋
    • この問題に関しては、私はこのアイデアがとても気に入っていて、2025年のロードマップで議論しているところです。
    • これは、例えばEventBridgeを扱っていて、いくつかのイベントに対して一つのLambdaを使いたい人たちの生活を楽にするだろう。
    • この新しいユーティリティには多くの利点があると思うし、2025年にリリースできたらクールだと思う。

非同期実行のLambda用のIssueとPR作成 (4)

  • 冬休みの自由研究として、プロトタイプを実装
  • 今は単体テストを頑張って書いてる
    • Event Source Data Classes用のイベントデータがあるので単体テストでも割となんとかなる
    • ただし物量が多い

非同期実行のLambda用のIssueとPR作成 (5)

  • 非同期実行用のLambdaが片付いたら
    • イベントソースマッピングのトリガー用のEventHandlerを作ろうかと思ってる
      • 非同期実行用のLambdaの実装で色々意見もらうだろうから、そのあとでIssueを作ろうと思ってる

おまけ


Developers.IO re:Invent 2024 索引 (1)

[9005460263786569] スクリーンショット 2025-02-08 14.02.09

https://reinvent2024.index.devio.luciferous.app/


Developers.IO re:Invent 2024 索引 (2)

[9005460263726526] da98d658537028220befab77c4006e38fab05c9d