AWS Lambda Managed Instances 検証:1Gbps超の帯域と AVX-512 が切り拓く「第3のサーバーレス」を少しだけ感じてみる

記事タイトルとURLをコピーする

関連リンク

はじめに

AWSから、Lambdaの運用負荷の低さと、EC2の柔軟性・パフォーマンスを両立させた新しい実行モード「AWS Lambda Managed Instances」が発表されました。

本記事では、この新しい選択肢がどのような課題を解決し、従来のLambda(Firecracker)と何が違うのかを技術的な視点から解説してみようと思います。

背景:なぜ「EC2で動くLambda」が必要だったのか

これまで、特定のCPU命令セットが必要なワークロードや極めて高いネットワーク帯域を必要とする処理において、「Lambdaを使いたいが、制約によりEC2を選ばざるを得ない」というケースがあったようです。私には経験がありませんが。

Lambda Managed Instancesは、「EC2の強力なリソースと柔軟性が必要だが、Lambdaのコードを記述するだけでイベント駆動もできる運用モデルも捨てがたい」というニーズに応えるために登場しました。

従来のLambdaとManaged Instancesの実行環境の違い

このアップデートを理解する鍵は、実行基盤となる「仮想化技術」の違いにあります。

1. 従来のLambda:Firecrackerによる「軽量・多対一」の分離

従来のLambdaは、AWSが開発したオープンソースの仮想化技術「Firecracker」を利用しています。

  • 仕組み: AWSが管理する巨大な物理サーバー群(フリート)の上で、120MB程度の極めて軽量な仮想マシン(MicroVM)をミリ秒単位で起動します。
  • リクエスト処理(1 VM = 1 リクエスト): 1つのMicroVM(実行環境)は、一度に1つのリクエストしか処理できません。 並列で100リクエストが来れば、100個のMicroVMが起動します。1つのVM内ではリクエストが「直列」に処理されるため、計算リソースの分離が厳格です。
  • マルチテナンシー: 同一の物理ハードウェア上で、複数のAWSアカウントの処理が並行して動きます。
  • なぜコンテナではないのか: コンテナはOSカーネルを共有するため、もし一つが侵害されると他の顧客のデータに影響を及ぼすリスク(コンテナブレイクアウト)があります。Firecrackerは、OSレベルから分離された「仮想サーバー」として動作することで、強力なセキュリティ境界を提供しつつ、コンテナ並みの起動速度を実現しています。
  • 制約: 共有基盤であるため、ネットワーク帯域やI/O性能には一定の制限(バースト制限など)があります。

2. Lambda Managed Instances:EC2による「専有・透過的」な実行

一方、Managed Instancesでは、お客様が管理する「EC2インスタンス上のコンテナ」内でLambda関数を実行します。

  • 仕組み: ユーザーが指定したEC2インスタンスタイプのゲストOS上で、Lambda実行用のコンテナランタイムが動作します。関数へのリクエストがあるたびに、このEC2上のコンテナ内でコードが処理されます。
  • 並列処理(1 EC2 = 複数リクエスト): 従来のLambdaと異なり、1つのManaged Instance(およびその上の実行環境)で複数のリクエストを並列に処理できます。 EC2の持つマルチコアCPUや大容量メモリといったリソースを、複数のリクエストで効率的に共有・活用できるのが最大の特徴です。
  • 高可用性と「ACTIVE」状態: 回復性を確保するため、デフォルトで 3つのAZに跨って3台のインスタンス が起動します。関数バージョンが ACTIVE になる前にこれらすべての実行環境が準備されるため、プロビジョニングされた状態で即座に並列処理を開始できます。(コールドスタートなし)
  • パフォーマンスの最大化: FirecrackerのようなマイクロVMによる多重化のオーバーヘッドがなく、軽量なコンテナ技術を利用します。ホストとなるEC2の強力なリソースを直接利用できるため、100Gbpsを超えるような広帯域ネットワークや、高速なNVMeストレージのI/Oを最大限に享受できます。
  • 柔軟性: ホストOSがEC2インスタンスそのものであるため、特定のCPU命令セット(AVX-512等)の活用や、独自のカーネルモジュールのロードといった高度なカスタマイズが可能です。

比較図

帯域の比較

使用可能な帯域を具体的に比較してみましょう。

1. 従来の Lambda (Firecracker) の帯域

従来のLambdaでは、ネットワーク帯域は「関数に割り当てたメモリ量」に比例してスケールします。

  • 最大帯域: 公表されていませんが、メモリの増減に応じて CPU と帯域が拡張します。ベンチマークでは最大 10 Gbps 程度です。これはメモリを最大(約10GB)まで割り当てた場合の数値です。

  • 低メモリ時の制限: 128MBや512MBといった少ないメモリ設定では、帯域も大幅に絞られます。

  • 共有の壁: Firecrackerは一つの物理ホスト上のNIC(ネットワークカード)を多数のMicroVMで共有するため、他の利用者の通信状況による影響(ノイジーネイバー問題)を完全にゼロにすることは難しく、バースト的な通信には波が出やすい特性があります。

2. Lambda Managed Instances (EC2) の帯域

こちらは、ベースとなる EC2インスタンスのスペックがそのまま適用 されます。

  • 最大帯域: 10 Gbps 〜 100 Gbps 以上
  • 例えば c7gn.16xlarge のようなインスタンスを選べば、200 Gbps などの極めて太い帯域を専有できます。

  • 専有のメリット: そのEC2インスタンスに割り当てられた帯域は「自分だけのもの」です。他のアカウントのLambda実行に左右されず、常にフルスピードでS3から大容量データを落としたり、API連携を行ったりできます。

帯域の比較まとめ

項目 従来の Lambda Managed Instances (EC2)
最大帯域幅 最大 10 Gbps (メモリ依存) 最大 100 Gbps以上 (インスタンス依存)
リソース占有 物理NICを複数ユーザーで共有 インスタンスに割り当てられた帯域を専有
主な用途 一般的なWebAPI、小規模なデータ処理 巨大なAIモデルのロード、大規模なログ解析、HPC

「従来のLambda」が「サーバーの存在を意識させない共有型」であるのに対し、「Managed Instances」は「サーバーのパワーを最大限に引き出す専有型」のサーバーレスだと言えます。※「専有」は「ハードウェアを専有している」という意味ではないです。

CPU スペックの比較

従来のLambdaとManaged Instancesの最大の違いは、「CPUの型番(世代)を指定できるかどうか」にあります。

1. 従来の Lambda: AWSにおまかせの「抽象化されたCPU」

通常のLambdaでは、「x86_64」か「arm64」という大きな枠組みしか選べません。

  • x86_64: 裏側ではIntel XeonやAMD EPYCが動いていますが、どの世代のプロセッサが割り当てられるかはAWSのリソース状況次第です。
  • arm64: 基本的に AWS Graviton2 プロセッサで動作します。
  • 課題: 最新の計算命令(AVX-512など)を使いたくても、割り当てられたホストが古い世代だとその機能が使えず、処理速度が安定しないという「性能の不確実性」がありました。

2. Lambda Managed Instances: 性能面から自分で「指定するCPU」

Managed Instancesでは、ベースとなるEC2のインスタンスタイプを自分で選ぶため、「どのプロセッサで動かすか」を完全にコントロールできます。

  • 最新世代のパワー: 例えば c7i インスタンスを選べば、最新の 第4世代 Intel Xeon (Sapphire Rapids) を確実に利用できます。
  • 特化機能の解放:

    • AVX-512: 従来の2倍の効率で数値計算を行う命令。
    • AMX (Advanced Matrix Extensions): AI推論を加速させる新しい行列演算アクセラレータ。
  • Graviton3 / 4 の利用: 通常のLambda(Graviton2)よりも25%以上高速な Graviton3 や、さらに最新の Graviton4 を搭載したインスタンスをLambdaの基盤として使えます。

CPU の比較まとめ

項目 従来の Lambda (Firecracker) Lambda Managed Instances (EC2)
CPUの選択 アーキテクチャのみ(x86 / ARM) インスタンスタイプで詳細に指定可
主なプロセッサ Graviton2 / Intel Xeon (世代はAWS依存) Graviton3, 4 / 最新世代 Xeon, EPYC
高度な命令セット 保証なし(ホスト次第) AVX-512, AMX などを確実に利用可
パフォーマンス 隣人の影響(ジッター)の可能性あり 専有リソースのため常に一定

実際にやってみる

キャパシティプロバイダの設定(VPC周り)

ドキュメント:Networking for Lambda Managed Instances - AWS Lambda

ドキュメントに記載の通り、送信先 0.0.0.0/0 の 宛先が インターネットゲートウェイになっているパブリックサブネットを選択します。
こんな感じ。

サブネットのルートテーブルの設定:

また、パブリックサブネットでは パブリック IPv4 アドレスを自動割り当て を「はい」に設定し、EC2 がインターネットと通信できるようにします。
サブネット設定:

選択したセキュリティグループのアウトバウンドルールはインターネット通信できるようにしておき、インバウンドルールは不要なので閉じておきました。
アウトバウンド設定:

インバウンド設定:

キャパシティプロバイダの設定(IAM周り)

Lambda が EC2 を起動できるように IAM ロール(インフラストラクチャ運用者のロール)をドキュメントに沿って作成しておき、選択しました。
ドキュメント:Lambda operator role for Lambda Managed Instances - AWS Lambda

ロールを以下の信頼ポリシーで作成し、AWSLambdaManagedEC2ResourceOperator という AWS 管理ポリシーを付与しました。

{
  "Version": "2012-10-17",                
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

キャパシティプロバイダの設定(インスタンスタイプ周り)

「詳細設定」を開くと以下のように EC2 や AutoScaling の設定が現れます。

インスタンスタイプを指定する場合、カンマ区切りのテキスト( = csv形式)で書かなければいけないというストロングスタイルになっています。
利用可能なインスタンスタイプは、なぜか料金ページに、リージョンごとに記載があります。

  • AWS Lambda 料金
    • 料金ページに利用可能なインスタンスタイプの一覧があります。

料金ページから、c7i.xlarge が使用可能なので記載します。

例えば、arm64 を選んで、インテルの CPU を使用するc7i.xlargeを記述するとエラーになります。

c7i.xlarge ではx86_64 を選ぶのが正解です。

c7i.xlarge の vCPU は 4 なので、自動スケーリングの 最大 vCPU は 4 x 3 = 12 としました。3 AZ に 1 台ずつインスタンスを起動する仕様なので、これがおそらく最小構成です。

ちなみに、AZ 2 つ、つまりサブネットを 2 つしか選ばなかった場合、1 AZ に 2 インスタンス起動していました。
この場合は 自動スケーリングの 最大 vCPU は 4 x 2 x 2 = 16 が最小構成となっていました。

関数を作成

関数を作成してみます。

名前をつけました。

関数に割り当てるメモリを設定します。

メモリの割り当て設定

あとでベンチマークを取るために、Lambda でよく使用されるメモリ設定である 4 GB を割り当てます。 性能を考えると c7i.xlarge では比率は「2:1」が正解です。 c7i.xlarge の物理的なリソース比率は、2:1 だからです。

  • 物理リソース: 4 vCPU / 8 GiB RAM
  • 計算式: (GiB / vCPU)

※ただし、ベストプラクティスページを見ると Python だけは仕様上 4:1 か 8:1 を勧めていたりもします。
この「インスタンスタイプの比率」と「設定する比率」を一致させると、以下の表のようにリソースをピッタリ使い切れます。

設定した比率 メモリ設定 割り当て vCPU 1台のインスタンスに乗る関数の数 合計消費リソース 結果
2 : 1 4 GB 2 2つ 4 vCPU / 8 GB 無駄なし
4 : 1 4 GB 1 2つ 2 vCPU / 8 GB 2 vCPU が余る
8 : 1 4 GB 0.5 2つ 1 vCPU / 8 GB 3 vCPU が余る

※実際は「1台のインスタンスに乗る関数の数」はこんなに上手くいかないので、後ほど補足します。
上記のように、比率を 4:1 や 8:1 に上げると、「メモリは使い切っているのに、CPUが余って遊んでいる」 という非常にもったいない状態になります。
では、いつ「8:1」を使うのか?この設定は、例えば「メモリ特化型」のインスタンス を選択したときに意味を持ちます。

  • r7i シリーズ(メモリ最適化インスタンス)の場合:
    • r7i.xlarge4 vCPU / 32 GiB RAM です。
      • このインスタンスを使うなら、比率を 「8:1」 に設定することで、初めて CPU とメモリを同時に使い切ることができます。

「4:1」は「汎用」のインスタンスを選択したときに初めて意味を持ちます。

  • m7i シリーズ (汎用)の場合:
    • m7i.xlarge は 4vCPU / 16GB
      • 比率を 「4:1」 に設定することで、初めて CPU とメモリを同時に使い切ることができます。

メモリに対する vCPU 数を従来と違ってカスタマイズできるのは良いことですが、計算が小難しいので事前確認が大事です。
インスタンスタイプごとにリソース比率を確認して、設定する必要があります。
複数のインスタンスタイプを選択する場合の計算は・・考えたくないですね。一貫したインスタンスタイプを使用する設計が良いんじゃないでしょうか。

検証:c7i.xlarge のリソースを「100%」使い切れるのか?

では、関数のメモリを 8GB、比率を 2:1 に設定して、c7i.xlarge(4 vCPU / 8GB)のリソースをフルに使い切ることはできるのでしょうか?

イメージ:

結論から言うと、答えは NO です。エラーになり関数を更新できませんでした。

なぜ使い切れないのか?

ホストとなる EC2 インスタンス上では、ゲスト OS や Lambda の実行用ランタイム(エージェント)が常に動作しています。これらのシステムが稼働するための「余白(オーバーヘッド)」が必要なため、物理スペックの上限いっぱいを関数に割り当てることはできない仕様になっています。

実測:設定可能な最大値の境界線

検証の結果、安定して設定できた「現実的な最大サイズ」は以下の通りでした。

  • キリの良い最大値: メモリ 4096 MB (4GB) / 2 vCPU

    • 迷ったらこの設定が、インスタンスを最も効率よく使えるラインです。
  • 限界ギリギリの数値: 5119 MB

    • 5GB の寸前までであれば設定可能でした。この場合、計算上の vCPU は約 2.4 となりますが、実際の割り当ては切り捨ての 2 vCPU になっていると考えられます。

結論:リソースの「半分」がスイートスポット

Managed Instances では、1 台のインスタンスに対して リソースの約半分までを一つの関数に割り当てる のが設計上の上限となっているようです。

システムの安定性を担保する「非機能設計」の観点から見ても、リソースを 100% 詰め込まずに余裕を持たせるこの仕様は、非常に納得感のある合理的な挙動だと言えます。

長い解説を終え、関数を作成ボタンを押します。

Lambda Managed Instance の CPU アーキテクチャと、AVX-512命令セットが利用可能かどうかを確認する

Lambda 関数が実行されている環境のCPUアーキテクチャと、AVX-512命令セットが利用可能かどうかを確認するためのPythonコードをデプロイします。 更新すると、数分間は待たされます。3 AZ に配置した EC2 上に関数コードを配置するのはシステム側としても骨が折れる作業なのかもしれません。

さて・・・
テスト実行の結果です。
ジャジャン。

まず、テスト実行で結果が表示されるまでが爆速でびっくりしました。 そして、標準的なLambda(Firecracker基盤)では、ここまで豊富で最新の命令セット(特に avx512_bf16avx512_vnni など)が揃うことは稀であり、あったとしても実行のたびにホストの世代が変わるため保証されません。
下に各フラグの説明を表にします。

フラグ名 具体的に速くなる計算処理 活用シーンの具体例
avx512_vnni 8ビット整数(INT8)の行列演算。複数の掛け算と足し算を1工程で処理。 AI画像診断・顔認証。学習済みモデルを「量子化(軽量化)」して動かす際の推論速度が数倍に。
avx512_bf16 Bfloat16形式の数値計算。精度と速度のバランスが最高の形式を直接計算。 ChatGPTのような言語モデル(LLM)の実行。Llama 3等の最新AIモデルをCPUで高速に動かす。
avx512_fp16 16ビット浮動小数点のネイティブ計算 音声合成・ノイズキャンセリング。スマホやWeb会議で使われるような音声波形データのリアルタイム加工。
avx512_vbmi / vbmi2 バイト単位のデータ並べ替え、圧縮、検索 巨大なJSONやログのパース。S3から落とした数GBのログから特定の文字列を高速に抽出するETL処理。
avx512ifma 巨大な整数の掛け算と足し算 暗号化・復号処理。SSL/TLS通信や、データベース保存時の高度な暗号化をCPU負荷を抑えて実行。
avx512_vpopcntdq データ内の「1」が立っているビット数をカウント データベースの重複排除・検索アルゴリズム。ゲノム解析や、類似画像検索のスコアリング計算。
avx512bw / dq 8/16/32/64ビットの細かなデータ操作 画像フィルター・動画編集。ピクセルごとの色情報を一括で書き換える処理(モノクロ化や輝度調整など)。
avx512vl データの長さに合わせた柔軟な計算 プログラム全体の効率化。データが512bitに満たない場合でも、無駄なくAVX-512の回路を利用可能にする。

こういった複雑な処理を、EC2 ではなく Lambda でもできるようになるということですね。「EC2の強力なリソースと柔軟性が必要だが、Lambdaのイベント駆動な運用モデルも捨てがたい」が実現できそうです。

デフォルトの Lambda の CPUアーキテクチャと、AVX-512命令セットが利用可能かどうかを確認する

デフォルトの Lambda でも CPUアーキテクチャと、AVX-512命令セットが利用可能かどうかを確認するためのPythonコードをデプロイしてみました。
私の環境のデフォルトの Lambda では、AVX-512命令セットは使えないようでした。
残念。切腹ですね。

arm64

x86_64

付録:CPUアーキテクチャと、AVX-512命令セットが利用可能かどうかを確認するためのPythonコード

import platform
import subprocess
import json

def lambda_handler(event, context):
    # 1. 基本的なアーキテクチャ情報の取得
    arch = platform.machine() # x86_64 か aarch64 か
    processor = platform.processor()
    
    # 2. /proc/cpuinfo からフラグを取得
    # AVX-512に関連する主要なフラグ(avx512f, avx512dq, avx512bwなど)を探す
    cpu_info = ""
    avx512_supported = False
    specific_flags = []

    try:
        # linuxのcpuinfoコマンドの結果を取得
        cpu_info = subprocess.check_output("cat /proc/cpuinfo", shell=True).decode()
        
        # AVX-512の基本フラグ 'avx512f' が含まれているか確認
        if 'avx512f' in cpu_info:
            avx512_supported = True
            # 関連する詳細フラグを抽出
            all_flags = [line for line in cpu_info.split('\n') if 'flags' in line]
            if all_flags:
                specific_flags = [f for f in all_flags[0].split() if 'avx512' in f]
    except Exception as e:
        cpu_info = f"Error reading cpuinfo: {str(e)}"

    # 3. 結果を整理して標準出力(CloudWatch Logsへ)
    result = {
        "Architecture": arch,
        "Processor": processor,
        "AVX-512_Supported": avx512_supported,
        "AVX-512_Specific_Flags": specific_flags
    }

    print("--- CPU Hardware Inspection ---")
    print(json.dumps(result, indent=4))
    print("-------------------------------")

    return {
        'statusCode': 200,
        'body': result
    }

ベンチマーク結果まとめ:S3 へのアップロード性能(2 GBのファイル)

メモリ設定を 4096 MB (4 GB) に統一し、実行環境の違いがスループット(通信速度)にどう影響するかを測定した結果です。

実行環境 アーキテクチャ AVX-512 実行時間 (2 GB) スループット
Managed Instance (c7i.xlarge) x86_64 有効 13.83 秒 1.16 Gbps
標準 Lambda (x86_64) x86_64 無効 36.05 秒 0.44 Gbps
標準 Lambda (arm64) aarch64 無効 33.36 秒 0.48 Gbps

今回のベンチマークにより、Managed Instances は単なる「EC2 上で動く Lambda」ではなく、サーバーレスの枠を超えた計算・通信能力を持っていることが証明されました。

1. ネットワーク帯域の「専用化」による高速化

標準の Lambda 関数はネットワークインターフェースを他の実行環境と共有しており、1 関数あたりの帯域が制限される傾向にあります。 これに対し、Managed Instances は EC2 インスタンス本来のネットワークスタック(専用 ENI) を直接利用できるため、S3 へのアップロードにおいて 標準 Lambda の約 2.6 倍という圧倒的なスループット(1.16 Gbps) を実現しています。

2. 最新 CPU 命令セット「AVX-512」

標準 Lambda では無効化、あるいは世代によって利用不可だった AVX-512 が、Managed Instance(c7i.xlarge)では確実に有効となっています。 これは第 4 世代 Intel Xeon プロセッサなどの最新ハードウェアが割り当てられている証拠であり、データの暗号化、圧縮、あるいは AI 推論といった重い計算処理において、標準 Lambda では到達できない処理効率を発揮します。

大容量ファイルの ETL 処理、高解像度画像の変換、AI モデルの推論など、「I/O 待ち」や「計算力不足」がボトルネックとなっていた処理において、Managed Instances は極めて高い効果を発揮します。

生のログ

c7i.xlarge の Managed Instance を使用。
メモリ 4096 GB に設定し、vCPU との比率を 2:1 にした場合。vCPU は 2 つとなる。

{
  "statusCode": 200,
  "body": {
    "Architecture": "x86_64",
    "AVX512_Enabled": true,
    "Target_GB": 2,
    "Duration_sec": 13.8343,
    "Throughput_Gbps": 1.1565,
    "Memory_Config_MB": "4096"
  }
}

x86_64 のデフォルトの Lambda 関数でメモリを 4 GB に設定。 CPU と帯域は自動で設定される仕様。

{
  "statusCode": 200,
  "body": {
    "Architecture": "x86_64",
    "AVX512_Enabled": false,
    "Target_GB": 2,
    "Duration_sec": 36.05,
    "Throughput_Gbps": 0.4438,
    "Memory_Config_MB": "4096"
  }
}

arm64 のデフォルトの Lambda 関数でメモリを 4 GB に設定。 CPU と帯域は自動で設定される仕様。

{
  "statusCode": 200,
  "body": {
    "Architecture": "aarch64",
    "AVX512_Enabled": false,
    "Target_GB": 2,
    "Duration_sec": 33.3605,
    "Throughput_Gbps": 0.4796,
    "Memory_Config_MB": "4096"
  }
}

付録:ベンチマーク取得用コード

import boto3
import os
import time
import platform
import subprocess
import json
from boto3.s3.transfer import TransferConfig

s3 = boto3.client('s3')

def get_cpu_info():
    """CPUアーキテクチャとAVX-512フラグを取得"""
    arch = platform.machine()
    avx512_supported = False
    specific_flags = []
    try:
        cpu_info = subprocess.check_output("cat /proc/cpuinfo", shell=True).decode()
        if 'avx512f' in cpu_info:
            avx512_supported = True
            all_flags = [line for line in cpu_info.split('\n') if 'flags' in line]
            if all_flags:
                specific_flags = [f for f in all_flags[0].split() if 'avx512' in f]
    except:
        pass
    return {"arch": arch, "avx512": avx512_supported, "flags": specific_flags}

def lambda_handler(event, context):
    # --- 設定 ---
    bucket_name = "lambda-managed-instance-test-202512"
    file_size_gb = 2 
    file_path = "/tmp/bench_file.bin"
    file_key = f"bench_{int(time.time())}.bin"
    
    # 1. CPU情報の取得
    cpu = get_cpu_info()
    print(f"CPU Inspection: {json.dumps(cpu)}")

    # 2. ファイル準備(計測対象外)
    if not os.path.exists(file_path):
        chunk_size = 100 * 1024 * 1024
        with open(file_path, 'wb') as f:
            for _ in range(int((file_size_gb * 1024 * 1024 * 1024) / chunk_size)):
                f.write(os.urandom(chunk_size))
    
    # 3. 転送最適化(Managed Instanceの帯域を活かす)
    config = TransferConfig(
        multipart_threshold=64 * 1024 * 1024,
        max_concurrency=20,
        multipart_chunksize=64 * 1024 * 1024,
        use_threads=True
    )

    # 4. 純粋なアップロード計測
    start_time = time.perf_counter()
    s3.upload_file(file_path, bucket_name, file_key, Config=config)
    end_time = time.perf_counter()
    
    # 5. 計算
    duration = end_time - start_time
    throughput_gbps = (file_size_gb * 8) / duration

    result = {
        "Architecture": cpu["arch"],
        "AVX512_Enabled": cpu["avx512"],
        "Target_GB": file_size_gb,
        "Duration_sec": round(duration, 4),
        "Throughput_Gbps": round(throughput_gbps, 4),
        "Memory_Config_MB": context.memory_limit_in_mb
    }

    print(f"Final Result: {json.dumps(result, indent=4)}")
    os.remove(file_path) # 後片付け

    return {"statusCode": 200, "body": result}

まとめ:Lambda Managed Instances が切り拓く「第3のサーバーレス」

今回の検証を通じて、AWS Lambda Managed Instances は、従来の Lambda (Firecracker) が持っていた「手軽さ」という魔法をそのままに、EC2 が持つ「圧倒的なパワー」という物理限界を突破させる、非常に強力な選択肢であることが分かりました。小さかったハリーポッターが成長してヴォルデモートを倒せるようになったということです。

検証結果から得られた重要なポイントを 3 つに凝縮して振り返ります。

1. 「専用帯域」がもたらす圧倒的な I/O 性能

ベンチマークの結果、同じ 4 GB メモリ設定でありながら、Managed Instances は標準 Lambda の 約 2.6 倍のスループット (1.16 Gbps) を記録しました。 これは、共有 NIC を使う Firecracker 基盤ではなく、EC2 本来のネットワークスタック(専用 ENI) を直接使えるアドバンテージが数字として現れた結果です。巨大なデータセットを扱う ETL や AI 推論において、この「通信の太さ」はそのままコスト効率に直結します。

2. 「CPU 命令セット」を確約できる安心感

標準 Lambda では運任せだった AVX-512 命令セットを、インスタンスタイプ(c7i など)の指定によって確実に利用できる点は、計算密度の高い処理において決定的な差となります。 avx512_vnniavx512_bf16 といった最新フラグが利用可能であることは、サーバーレス環境で「最新世代の Intel Xeon や Graviton のパワーを 100% 引き出せる」ことを意味します。

3. 「物理リソース」を意識した高度な設計自由度

Managed Instances は、メモリと vCPU の比率を自由にカスタマイズできる柔軟性を持っています。

  • c7i シリーズなら「2:1」比率 で計算パワーを最大化
  • m7i シリーズなら「4:1」比率 で計算パワーを最大化
  • r7i シリーズなら「8:1」比率 で計算パワーを最大化
  • Python アプリなら「4:1」や「8:1」

ただし、検証でも判明した通り、インスタンスの物理限界(オーバーヘッド)を考慮した「ゆとり」の設定(例:8 GB メモリの EC2 に対して 4 GB 割り当てなど)が必要になります。このように私のようなゆとり世代のインフラエンジニア好み?の設計が楽しめるのも Lambda Managed Instance の醍醐味です。


結局、どちらを選ぶべきか?

今回の知見をもとにした、超簡単な判断基準がこちらです。

特徴 標準 Lambda (Firecracker) Managed Instances (EC2基盤)
トラフィック バーストが多い、予測不能 定常的、高ボリューム
計算負荷 軽〜中程度 重(AI推論、動画変換、HPC)
通信量 数MB 〜 数百MB 数GB以上の大容量通信
コスト最適化 実行時間ベースの従量課金 RI / SP 活用で最大化

料金比較:従量課金か、固定枠+管理手数料か

標準 Lambda と Managed Instances では、料金の計算方法が根本から異なります。

1. 料金モデルの比較表

項目 標準 Lambda (Firecracker) Lambda Managed Instances
基本コンセプト 完全な従量課金(使った秒数分のみ) 確保したリソースへの支払い(固定費に近い)
主な内訳 リクエスト数 + 実行時間(GB秒) EC2 インスタンス料金 + 管理手数料 (インスタンス料金の15%) + リクエスト料金: 0.20 USD/100 万リクエスト
割引オプション Compute Savings Plans EC2 SP / RI

2. コストパフォーマンスの分岐点

今回のベンチマーク結果(2 GB 転送:Managed 13.8秒 vs 標準 36.1秒)を元に考えると、どちらがお得かが明確になります。

標準 Lambda がお得なケース

  • リクエストが散発的: 1 日に数回しか動かない処理であれば、実行時間分だけ払う標準 Lambda が圧倒的に安いです。
  • 小規模な開発: 固定費をゼロにしたいフェーズ。

Managed Instances がお得なケース

  • 定常的な高負荷ワークロード: 24 時間常にリクエストが来るようなシステム。
  • 処理時間が長い I/O 処理: 今回の検証のように、「標準 Lambda だと転送に 36 秒かかるが、Managed なら 13 秒で終わる」 場合、時間あたりの処理効率が 2.7 倍になります。
    • 1 インスタンスで複数のリクエストを並列処理(マルチコンカレンシー)できるため、大量のリクエストを 1 台の EC2 に詰め込むほど、1 リクエストあたりの単価は標準 Lambda より劇的に下がります。

「安さの標準 Lambda、効率の Managed Instances」

  • 標準 Lambda: 「使った分だけ払いたい」時に。ネットワーク帯域がボトルネックにならない程度の軽い処理に最適。
  • Managed Instances: 「大量のデータを高速に捌きたい」時に。RI / SavingsPlanを組み合わせることで、最新の c7i インスタンスのパワーを、標準 Lambda でメモリを盛るよりも遥かに安価な実効単価で利用できます。

終わりに

Lambda Managed Instances は、「サーバーを管理したくない」という想いと「サーバーの性能を極限まで使いたい」という、相反する願いを叶える新しい選択肢です。

もし、あなたが今「Lambda のタイムアウト」や「ネットワークの詰まり」に悩んでいるなら、インスタンスタイプを c7i に設定した Managed Instances を、ぜひ一度試してみてください。そこには、これまでのサーバーレスの常識を塗り替える 「1 Gbps 超えの世界」 が待っています。

余談

今年も「伊豆トレイルジャーニー 70 km」というトレイルランニングの大会を走ってきました。
富士山が綺麗でした。

note にレポを書いています。
伊豆トレイルジャーニー 2025|山本 哲也 (やまもと てつや)

山本 哲也 (記事一覧)

カスタマーサクセス部のインフラエンジニア。

山を走るのが趣味です。