re:Invent 2025: Lambda Managed InstancesでEC2上でLambda関数を実行する新機能
はじめに
海外の様々な講演を日本語記事に書き起こすことで、隠れた良質な情報をもっと身近なものに。そんなコンセプトで進める本企画で今回取り上げるプレゼンテーションはこちら!
re:Invent 2025 の書き起こし記事については、こちらの Spreadsheet に情報をまとめています。合わせてご確認ください
📖re:Invent 2025: AWS re:Invent 2025 - Lambda Managed Instances: EC2 Power with Serverless Simplicity (CNS382)
この動画では、AWS re:InventでローンチされたLambda Managed Instancesについて、Principal Solutions ArchitectのStephen LiedigとPrincipal EngineerのArchana Srikantaが詳しく解説しています。この新機能により、顧客のアカウント内のEC2インスタンス上でLambda関数を実行でき、400種類以上のインスタンスタイプから選択可能になります。高トラフィックで定常的なワークロード向けに設計されており、コールドスタートがなく、マルチ同時実行をサポートします。Capacity Providerの作成、関数の作成、バージョンの公開という3ステップで構成され、EC2の価格設定とSavings Plansが適用されます。リソースベースの非同期スケーリング、コンテナ境界によるセキュリティ分離、DatadogやZEETなどのパートナー統合も提供されます。従来のLambdaを置き換えるものではなく、特定のユースケースを補完する位置づけです。
※ こちらは既存の講演の内容を最大限維持しつつ自動生成した記事になります。誤字脱字や誤った内容が記載される可能性がありますのでご留意下さい。
本編
Lambda Managed Instancesの発表とServerlessイノベーションの歴史
皆さん、こんにちは。これはおそらくre:Inventが終わりを迎える前の最後のセッションの一つだと思います。ご参加いただきありがとうございます。本日はWerner Vogelsの基調講演という強力な競合がありますが、それでもお越しいただき感謝しております。本当にありがとうございます。私の名前はStephen Liedigと申します。オーストラリアとニュージーランドのServerlessチームのPrincipal Solutions Architectを務めております。そして本日は、AWS LambdaチームのPrincipal EngineerであるArchana Srikantaと一緒に登壇しております。本日は、今週初めにローンチした新機能、Lambda Managed Instancesについてご紹介したいと思います。
AWSはServerlessを開拓しただけでなく、ご覧いただけるように、この分野で継続的かつ厳格にイノベーションを起こしてきました。Python、Node.js、Javaといったランタイムを導入した初期の頃から、今日では事実上あらゆるタイプのランタイムをサポートするまでに進化しました。VPC統合、Hyperplaneインターフェースを通じた最適化されたネットワーク統合を導入し、さらにlayersやconcurrencyといった機能も導入しながら、皆さんが今日構築しているアプリケーションの開発を支援するため、コールドスタートを継続的に最適化してきました。また、その過程でStep FunctionsやEventBridgeといった新しいサービスも導入し、数百万のワークフローをオーケストレーションし、イベント駆動型アーキテクチャを構築できるようにしてきました。
この10年間、お客様は、今日クラウド上でモダンなアプリケーションを実行・構築するために、この非常に幅広いServerlessサービスのポートフォリオのメリットを本当に享受してきました。お客様は、大量のコードを書くことなく、ビジネスロジックに集中し、スケーリング、セキュリティアップデート、その他のメンテナンスの問題に煩わされることなく、それを実現しています。組織に価値をもたらすサービスに対してのみ料金を支払い、無駄を最小限に抑えています。そして、分散アーキテクチャとセキュリティに関する私たちのベストプラクティスを活用できています。
ご覧のように、今日、Serverlessには非常に多様なユースケースがあります。金融機関は、コアバンキングアプリケーションをAWSに移行し、Lambdaやその他のAWSサービスを活用して運用コストを削減し、将来の開発を加速しています。医療プロバイダーは、Lambdaを使用して予約の自動化、保険請求処理、安全な患者ポータルアクセスを実現しています。小売企業は、迅速にイノベーションを起こし、ショッピングのピーク時の急増に対応する方法として、イベント駆動型アーキテクチャを採用しています。スタートアップ組織は、特に成長初期段階でコストをネットゼロに抑え、機能を迅速に反復できるようにするためにServerlessを使用しています。政府機関もServerlessを活用しており、例えばAustralian Bureau of Statisticsのような機関は、前回のオーストラリア国勢調査を完全にServerless上で構築しました。
しかし、これらすべての成功とこの多様性にもかかわらず、お客様は依然として、プログラミングモデルは気に入っているものの、他のオプションを検討する必要があるユースケースがまだあると言っています。それが、大幅なアーキテクチャの変更と、運用の観点からはるかに大きな責任を負うことにつながっています。お客様は、関数がどこで実行されているか、何の上で実行されているかについて、より多くのコントロールを求めており、また、他のコンピュートサービスで行っている早期コミットメントや使用量割引を適用できるようにしたいと考えています。お客様は、価格とパフォーマンスを最適化する方法として、マルチコンカレンシーも検討しています。
Lambda Managed Instancesは、この課題に対するソリューションです。 Lambda Managed Instancesを使用することで、皆さんが今日慣れ親しんでいるのと同じプログラミングモデルを維持し、同じServerlessの方法でアーキテクチャを構築できます。同時に、一貫性のある使い慣れた開発体験も維持できます。私たちは、特殊なコンピュートに対するより多くの制御と、関数が実行されるコンピュートに関する幅広い選択肢を提供し、さらにコールドスタートがないというメリットも活用できます。それに加えて、EC2の価格メカニズムを通じて効率性と予測可能性を推進しながら、同時にマルチ並行実行の呼び出しに関するオプションも提供しています。
では、Lambda Managed Instancesとは何でしょうか?基本的には、AWS Lambda関数をお客様のアカウント内で、お客様が選択したEC2インスタンス上で実行できる機能です。汎用、コンピュート最適化、メモリ最適化のインスタンスファミリーにわたって400種類以上の異なるインスタンスタイプにアクセスでき、お客様の特定のワークロードニーズに最適なものを選択できます。そして、AWSは依然としてすべての運用要素を処理しています。私たちはインスタンスのライフサイクルを管理し、それらのインスタンスに組み込まれているオペレーティングシステムとランタイムのパッチ適用を管理しています。すべてのルーティングと自動スケーリングを処理し、お客様の設定に従ってそれを行っています。同時に、お客様はEC2 Savings Plans、Compute Savings Plans、リザーブドインスタンス、その他私たちとの特別な契約など、EC2の価格構造を適用できるというメリットを享受できます。
では、いつManaged Instancesを使用するのでしょうか?Managed Instancesは、現在のLambdaの代替として置き換えるものではありません。具体的には、スムーズで予測可能なトラフィックパターンを持つ、高トラフィックで定常状態のワークロードに対してManaged Instancesの使用を検討することになります。非常に特定の計算ニーズやメモリ要件、ネットワークスループット要件を持つアプリケーションに対してManaged Instancesの使用を検討することになります。そして、それ以外のすべてについては、引き続きLambdaを使用することになります。現在のLambda、または私たちがLambda defaultと呼んでいるものは、予測不可能なトラフィックや、短時間で頻度の低い呼び出しがあるワークロードに本当に理想的です。
それでは今日は、Lambda Managed Instances環境を構築する方法について、その体験を順を追って説明していきます。そして、Lambda defaultが提供するものと、Lambda Managed Instancesがどのように機能するかの主な違いについてお話しします。そして最後に、パートナー統合と、私たちがサポートしている開発者ツールに関する情報、そして価格情報についてまとめます。それでは、Archにバトンタッチします。ありがとうございました。
Lambda Managed Instancesの技術的概要と構築の3ステップ
それでは、皆さんこんにちは。Stephenが述べたように、私はArchです。Lambdaのプリンシパルエンジニアで、最近ではこのプロジェクトのテックリードを務めており、皆さんにお届けできることを非常に楽しみにしています。それでは、Stephenが私たちにLambda Managed Instances、つまり私がこのトークの残りの部分でLMIと呼ぶものを構築した理由について、本当に素晴らしい紹介をしてくれました。そして私は、LMI上で実際に関数を作成する体験について、技術的な詳細を説明していきます。そしてその体験を順を追って見ていく中で、LMIの体験が、皆さんが今日知っていて愛用しているデフォルトのLambda体験と実際にどのように非常に似ていて、非常に馴染みのあるものであるかに注目していただきたいと思います。そして、その後のセクションでは、LMIがLambda defaultとどのように異なるか、そしてそれがどのプラットフォームをいつ使用するかの選択にどのように影響するかについてお話しします。
さて、Stephenが言及したように、私たちがここで目指している最終的なセットアップは、お客様のアカウント内、お客様のVPCにおいて、LambdaがEC2インスタンスを起動し、そしてそれらのEC2インスタンス上にお客様の関数をデプロイするというものです。これらのEC2インスタンスは、私たちがLambda Managed Instancesと呼んでいるもので、これが意味するのは、基本的には通常のEC2インスタンスとほぼ同じですが、Lambdaによって完全に管理されているということです。このインスタンスの起動は私たちが処理します。これらのインスタンスのOSパッチ適用も私たちが処理し、インスタンスの終了に至るまで、インスタンスのライフサイクル全体を管理します。このインスタンスに対してお客様ができることは、コンソールで確認したり、インスタンスをdescribeしたりすることですが、たとえ望んだとしても、それに触れることは一切できません。つまり、インスタンスを更新することも、インスタンスを編集することも、インスタンスにSSHで接続することもできませんし、実際にインスタンスを終了させることすらできません。ですので、これらのインスタンスの管理全体は、それを管理するサービスとしてのLambdaに完全に委任されています。そして課金に関しては、Stephenが言及したように、これらのインスタンスには通常のEC2の課金が適用され、EC2でお持ちの価格設定の仕組みも適用されます。
さて、お客様のインスタンス上にデプロイされるこれらの関数についてですが、これは私たちが実行環境と呼んでいるものです。ご存じない方のために説明すると、Lambda関数の実行環境とは、基本的にはお客様のアプリケーションの実行中のコピーです。つまり、お客様の関数コード、その下にある言語ランタイム、お客様のレイヤー、エクステンション、これらすべてがブートストラップされて起動し、呼び出しを処理する準備ができている状態です。これが私たちが関数実行環境と呼んでいるものです。
さて、では、お客様のアカウントでこのすべての魔法をどのように実現するのでしょうか? ここでの体験には3つのステップがあります。これらの各ステップを詳しく見ていきますが、最初のステップはCapacity Providerを作成することです。
ここで、お客様はインスタンスレベルの設定とセッティングをすべて私たちに提供します。次に、関数を作成し、それを先ほど作成したCapacity Providerに関連付けます。 最後に、関数バージョンを公開します。これがすべての魔法を実現するステップで、インスタンスの起動とそれらのインスタンス上への関数のデプロイが行われます。
Capacity Providerの作成:VPC設定、インスタンスタイプ、スケーリング設定
それでは、これらをそれぞれもう少し詳しく見ていきましょう。まずはCapacity Providerから始めます。 Capacity Providerは全く新しい構成要素です。これはLambda Managed Instancesのためだけに導入したLambdaの構成要素で、先ほど申し上げたように、基本的にはインスタンスに関するすべてのものです。インスタンス設定に関して私たちに提供したいオーバーライドや設定のすべてが、このCapacity Providerオブジェクトに入ります。 ここにいくつかの設定があります。最初の1つはインスタンスのVPC設定です。2つ目は、お客様の関数に使用してほしい実際のインスタンスタイプです。最後に、関数への負荷が増加したときにインスタンスをどのようにスケールさせるかについて設定できるガードレールをいくつか見ていきます。
それではVPC設定から始めましょう。ここに新しいCapacity Provider作成APIがあります。最初にあるのがCapacity Provider名です。名前を付けて、タグを付けることができます。そして、ロールを指定する必要があります。これがCapacity Providerオペレーターロールです。これは標準的なIAMロールで、Lambdaにお客様のアカウント内でEC2インスタンスを実際に起動して管理する権限を与えるものです。次にVPC設定に進みます。これは標準的なVPC設定で、サブネットとセキュリティグループです。これがインスタンスを起動するVPCになります。さて、必須パラメータという観点では、Capacity Providerを作成するために本当に必要なのはこれだけです。他にも様々な設定がありますが、それについてはこれからお話しします。ただ、それらにはすべてデフォルト値があることを知っておいてください。それらは、関数の下にあるキャパシティを本当に細かく調整したいパワーユーザー向けの高度な設定です。しかし、必須パラメータという点では、これだけで十分です。ロールとVPCが必要で、それを指定していただくだけです。
VPC設定で指定していただくサブネットについてですが、本番アプリケーションの場合は、標準的なAWSのガイダンスが適用されます。3つのアベイラビリティーゾーンにサブネットを指定してください。そうすることで、私たちが起動するインスタンス、つまり実行環境を、それらのアベイラビリティーゾーン全体に均等に分散させることができます。ネットワーキングに関しては、これらは通常のEC2インスタンスですので、VPC内にプライマリネットワークインターフェースを持ちます。つまり、VPCからIPアドレスを取得します。関数の実行環境からのすべてのアウトバウンドトラフィックは、実際にこのインスタンスのネットワークインターフェースを経由して通過します。関数がダウンストリームの依存関係と通信したい場合は、Capacity Provider VPCを通じて、それらの依存関係のエンドポイントへのパスがあることを確認してください。
また、CloudWatchに送信するアプリケーションログも、このインスタンスのネットワークインターフェースを経由して通過します。もう一つ覚えておいて確認していただきたいのは、VPCを通じてCloudWatchエンドポイントへのパスが実際にあることです。これは、パブリックエンドポイントにアクセスするためのインターネットアクセスを許可するか、VPC内でPrivateLinkのCloudWatchエンドポイントを使用することで実現できます。すべてのログもこのインスタンスのVPCを経由して通過することを覚えておいてください。イングレストラフィックに関しては、これは今日のLambdaのデフォルト関数と同じです。そのネットワークインターフェースを通じてインスタンスや実行環境に入ってくるイングレストラフィックはありませんので、指定していただくセキュリティグループのインバウンドルールはすべて閉じていただいて構いません。
VPC設定に関するもう一つのポイントは、関数からのすべてのエグレストラフィックがインスタンスのネットワークを経由するため、関数レベルでVPC設定を指定することは実際には許可していません。関数作成APIで、Lambda Managed Instances関数を作成する場合、VPC設定を指定することはできません。常にCapacity Providerで指定していただいたVPC設定を使用します。
それでは、インスタンスタイプについてお話ししましょう。Lambda Managed Instancesでサポートされているインスタンスタイプの全セットは、基本的にこれらの最新世代のC、M、Rインスタンスファミリーです。Cはコンピューティング最適化されたEC2インスタンスファミリー、Mは汎用、Rはメモリ最適化です。サイズに関しては、これらのファミリー内でlargeインスタンスサイズ以上をサポートしています。
アーキテクチャに関しては、X86についてはIntelとAMDの両方をサポートしており、さらにARM Gravitonインスタンスタイプもサポートしています。さて、このサポートしている大規模なインスタンスタイプのセットの中で、デフォルトではLambdaが関数のメモリサイズと設定に基づいて、関数用のインスタンスタイプを選択します。これについては関数のセクションでもう少し詳しくお話しします。ただし、使用するインスタンスタイプのセットを制限したい場合は、いつでもオーバーライドできます。このセット全体を使用したくない場合は、オーバーライドを通じてそれが可能です。そしてそれが、キャパシティプロバイダー内のこのインスタンス要件セクションに繋がります。ここでは、許可されたインスタンスタイプを指定できます。これは、これらのインスタンスタイプのみを使用するという意味です。または、除外されたインスタンスタイプを指定することもできます。これは、これら以外のすべてを使用するという意味です。そして、ここにはいくつかの他の設定もあります。
アーキテクチャはデフォルトでX86アプリケーションを想定しています。ARMの場合は上書きする必要があります。もう一つ覚えておくべきことは、関数のアーキテクチャがキャパシティプロバイダーのアーキテクチャと一致することです。そして最後に、インスタンスにアタッチされるEBSボリュームについては、デフォルトではサービスマネージド型のキーで暗号化されます。ここでは、EBSボリュームの暗号化に使用できる独自のKMSキーを提供できます。
さて、スケーリングです。スケーリングについては、数セクション後にかなり深く掘り下げて説明します。そこでは、より高度なスケーリング設定についてお話しします。ただし、ここではキャパシティプロバイダーのスケーリング設定セクションがあることをご紹介したいと思います。ここで話しているのは、すべてインスタンスレベルのスケーリングです。最初の設定は最大vCPU数です。これは基本的に、キャパシティプロバイダー内の負荷が増加するにつれてスケールアウトできる最大インスタンス容量の制限です。主にコスト管理のノブとして有用で、特定のキャパシティプロバイダーから発生するインスタンス課金にハードリミットを設定できます。繰り返しになりますが、これはオプション設定です。デフォルト値がありますので、必要がある場合にのみオーバーライドできます。そして先ほど申し上げたように、ここにはさらに設定があり、スケーリングセクションのコンテキストでお話しします。
Lambda関数の作成とバージョン公開によるデプロイメント
さて、これでキャパシティプロバイダーができました。次のステップは関数を作成することです。ここで馴染みのあるLambdaの体験が始まります。関数を作成するプロセスは、今日行うものとほぼ全く同じです。唯一の小さな変更点は、関数を作成する際に、先ほど作成したこのキャパシティプロバイダーと関連付ける必要があることです。これにより、これがLMI関数であり、お客様のインスタンスにデプロイする必要があることを私たちが認識できます。これは、私たちのインフラストラクチャ上に配置されるデフォルトのLambda関数とは対照的です。そして、LMIでサポートされている関数機能のいくつかについてお話しします。最後に、関数のメモリとCPU設定、そしてそれがこれらの関数の下で選択するインスタンスタイプにどのように影響するかについてお話しします。
さて、これが私たちのお馴染みの関数作成APIです。そしてここに、キャパシティプロバイダー設定のための新しいセクションがあります。そこでキャパシティプロバイダーのARNを提供します。LMI関数にするには、これだけで簡単です。そして、同じキャパシティプロバイダーに複数の関数を関連付けることができます。その場合、それらすべての関数がそのキャパシティプロバイダー内の同じインスタンス容量を共有します。
それでは、サポートされている機能について見ていきましょう。パッケージング形式については、OCIコンテナとzip形式の両方をサポートしています。言語ランタイムについては、Java、Python、Node、.NETの最新バージョンをサポートしています。インスタンスレベルで行われるOSパッチに加えて、実際の言語ランタイムもLambdaによって管理およびパッチ適用されるという利点を引き続き享受できますので、これは皆さんがよく知っている使い慣れた体験と同じです。その他にサポートしている機能として、オブザーバビリティの領域では、layersとextensionsがLMIでサポートされています。呼び出しのダイナミクスに関しては、function URLsをLMIで使用でき、response streamingもLMIで動作します。呼び出しタイムアウトは15分で、これは現在のデフォルト関数と同じです。そして最後に、Lambdaからもう一つ大きなローンチを発表しました。それはDurable Functionsで、これにより中断を許容できる長時間実行される関数や、マルチステップアプリケーションを実行できるようになりますが、これもLMIで動作します。
LMIでサポートされていない、あるいは適用されないものについてですが、Lambda Managed Instancesに適用されない、またはサポートされていない機能がいくつかあります。
SnapStartは、LMIには適用されないものの一つです。なぜなら、LMIには実際にはコールドスタートが存在しないからです。これについては、スケーリングのセクションでもう少し詳しくお話しします。コールドスタートがないため、SnapStartはLMIでは意味を持ちません。Provisioned concurrencyとreserved concurrencyは、LMIではサポートされていません。なぜなら、LMIには最小および最大実行環境という手段によって同等の概念があるからです。これも、スケーリングについて話すときに見ていきます。
それでは、関数の設定について話しましょう。皆さんの多くがご存知のように、関数の作成にはメモリサイズの設定があり、そこで関数の実行環境がどれだけのメモリを取得すべきかを指定します。範囲については、LMIでは範囲が高くなっています。LMI関数では最大32ギガバイトのメモリサイズをサポートしています。LMIで導入した新しい設定のもう一つが、この実行環境のメモリ per vCPUです。これは基本的に、関数の実行環境に対するメモリとvCPUの比率です。メモリとこの比率に基づいて、どれだけのCPUを割り当てる必要があるかを推定します。デフォルトは2対1、つまりvCPUあたり2ギガバイトで、4対1または8対1まで設定できる値となっています。
これらの比率とメモリ設定を適用すると、これが許可されているすべての組み合わせの表になります。ここで注意すべき点の一つは、分数のvCPUは許可していないということです。使用している比率に応じて、メモリは比率の倍数で増加します。8対1を使用している場合、メモリは8の倍数でのみ設定できます。4対1を使用している場合は、メモリは4の倍数でのみ設定できます。インスタンスタイプの選択に関しては、これらの比率は基本的に私たちが持っているインスタンスファミリーの比率と一致しています。2対1の比率の関数を使用している場合、コンピュート最適化インスタンスタイプを選択します。スペクトラムの反対側で8対1の比率を使用している場合は、関数の下でメモリ最適化インスタンスタイプを選択し、4対1は汎用インスタンスタイプとなります。
さて、これでcapacity providerができました。LMI functionとして指定されたfunctionもあります。しかし、まだ皆さんのアカウントにはinstanceやexecution environmentは存在していません。この魔法が実際に起こるのは、function versionをpublishした時です。これが実際にdeploymentをトリガーするんです。 Function versionのpublishは、今日既に存在する機能です。Lambda defaultのfunctionには必須ではありませんので、ここでの唯一の変更点は、LMI functionの場合、実際にdeployするためにはversionをpublishする必要があるということです。これを行うには2つの方法があります。既存のpublish version APIを使うか、あるいはcreateとupdate function APIに少し構文糖衣を用意していまして、publishフラグをtrueに設定するだけで、すべてのcreateとupdateが自動的に裏側でversionをpublishしてくれます。
このversionをpublishした時に、皆さんのアカウントですべてのアクションが起こり始めます。 そのdeploymentがどのようなものか見ていきましょう。それから、function levelのscaling configurationも見ていきます。 さて、publish versionを呼び出すと、最初に行うのは、実際に皆さんのfunctionを適切なinstance typeにマッピングすることです。 皆さんのアカウントにそれらのEC2 instancesを起動し、それらのEC2 instances上で、デフォルトで3つのexecution environmentsを初期化します。3つのavailability zonesを指定していただいた場合、3つのinstancesを3つのavailability zonesに起動し、それらの上に3つのexecution environmentsを初期化します。 初期化が完了するまで、functionは実際にはpending状態にあり、activeになって初めて、実際にfunctionを呼び出すことができるようになります。
関数レベルのスケーリング設定と呼び出しの実行
さて、functionのactivationの一部として立ち上がるこれら3つのexecution environmentsを、私たちはmin execution environmentsと呼んでいます。 デフォルトでは3つですが、もちろんいつでも上書きできます。これがfunction scaling configのセクションに繋がります。 これはまた別の新しいAPIで、function levelのscaling parametersをオーバーライドするためのものです。これがput function scaling configuration APIです。ここにはminとmax execution environmentsがあり、function levelで何個のexecution environmentsをscale inおよびscale outできるかを制限しています。
minimum execution environmentsに関しては、先ほど申し上げたように、デフォルトは3です。 このminimumをオーバーライドしたい理由がいくつかあります。既知のピークや予想される需要、あるいはバッファのためにcapacityを事前にプロビジョニングしたい場合は、minimumを高く設定することができ、私たちは常にそれらのexecution environmentsをwarmに保ち、稼働させ続けます。一方で、3つのexecution environmentsを稼働させ続けることや、そのような高可用性の姿勢を気にしない場合は、より低くオーバーライドできます。devやtestのworkloadを使用している場合は、それをより低くオーバーライドできます。
maximum execution environmentsに関しては、デフォルトではmaximumはありませんので、基本的に必要なだけscaleすることができます。同じcapacity providerにマッピングされた複数のfunctions間でfair sharingを行うためにオーバーライドできます。先ほど申し上げたように、同じcapacity providerに複数のfunctionsがある場合、それらはそのcapacity provider内のinstance capacityを共有しますので、noisy neighborの妨害を防ぐために、それぞれがどれだけscaleできるかを制限できます。これらはLambda Defaultで持っているprovisioned concurrencyとreserved concurrency modelと同等のものです。LMIではこれを少し異なる方法で行っているだけです。
最後に、もう一つの小さなトリックとして、最小値と最大値を0に設定することができます。そうすると、基本的にはcapacity provider内で関数を完全にスケールダウンさせることができます。その時点では非アクティブな状態になっているので、invokeは通りません。スケールバックアップしてinvokeを通すためには、戻ってきて最小値と最大値を0より大きい値に設定する必要があります。つまり、これは基本的に関数を非アクティブ化する方法なんです。開発テストワークロードで夜帰宅する際に、実際に関数を削除する必要はありません。スケールダウンしておいて、朝戻ってきたらスケールアップすればいいんです。
さて、capacity providerを作成し、関数を作成し、バージョンを公開し、インスタンスへのデプロイを行いました。そして今、invokeする準備ができました。この機能の素晴らしいところは、invokeのエクスペリエンスが現在のものと全く同じだということです。invokeが来ると、私たちは関数がLMI関数かどうか、capacity providerが関連付けられているかどうかをチェックします。もしそうであれば、すべてのinvokeをインスタンスにデプロイした実行環境にルーティングします。そして、invokeのエクスペリエンスが全く同じなので、実際に今日Lambdaでサポートされているすべてのイベントソース統合が利用できます。LMI関数でもそのまま使えます。私たちが持っているさまざまなinvokeタイプも含めてです。直接invokeまたは同期invokeと呼んでいるものがあります。また、イベントinvocationタイプもサポートしており、この一連のイベント統合がそのまま動作します。
では、create functionとinvokeのエクスペリエンスを見てきましたが、Lambda Defaultのエクスペリエンスとできるだけ近い形で維持してきました。しかし、capacity providerでほんの数クリック、数ステップ追加するだけで、関数の下にあるインフラストラクチャをサービス所有のインフラストラクチャから、アカウント内の通常の良き古きEC2インスタンスへと効果的に完全に変更したわけです。そして、関数の下にあるこの大きなキャパシティシフトのために、Lambda DefaultとLMIの間には、その下にあるキャパシティの管理に関していくつかの違いがあります。LMIを使用する際には、これらを認識しておく必要があります。
マルチ同時実行とスロットリング保護の仕組み
では、それらを見ていきましょう。最初はconcurrencyです。以前にLambdaを使ったことがある方は、おそらくLambda Default関数のconcurrencyについて詳しくご存知だと思います。ConcurrencyはLMIのコンテキストでは少し異なる意味を持ちます。そしてStephenが簡単に触れましたが、LMIではマルチconcurrent関数をサポートしているので、ここでそれを見ていきます。2つ目はscalingです。これもStephenが言及したもう一つのことですが、LMIにはcold startがないので、LMIでは少し異なる方法でscalingを行います。そして、LMIでscalingがどのように行われるかをより深く見て理解していきます。
そして最後に、セキュリティ境界です。Lambda Defaultでは、私たちのサービスアカウントで実行されています。完全なマルチテナントセットアップです。ここLMIでは、アカウント内で実行されることになり、これは完全なシングルテナントセットアップなので、セキュリティの観点から境界が少し異なります。それについてお話しします。
それでは、concurrencyから始めましょう。LMIに入る前に、Lambda Defaultにおけるconcurrencyが何を意味するのか、少しおさらいしておきましょう。Lambda Defaultでは、関数があって、invokeが入ってきたときに、まだその関数用の実行環境がない場合、invokeのパスの中で、実行環境がないと判断して、新しい実行環境を初期化し、その実行環境内でinvokeを実行します。さて、このinvokeが実行されている間に、2つ目のinvokeが来ると、実行環境1はビジーだと判断し、2つ目の実行環境を初期化して、その中で2つ目のinvokeが実行されることになります。
新しい実行環境の初期化を引き起こすこれらのinvokeを、私たちはcold startsと呼んでいます。これらは若干高いレイテンシーを伴います。なぜなら、同期invokeリクエストパスの一部として、実際に初期化ロジックを実行しなければならないからです。さて、このinvoke番号3ですが、これはinvoke1が完了した後に入ってきます。invoke3で何が起こるかというと、実際には実行環境1を保持しておくんです。もっとinvokeを送ってくれることを期待して。なので、invoke3では、既存の実行環境にルーティングするだけでよく、初期化のコストを払う必要がありません。これを私たちはwarm invokesと呼んでいます。warm invokesは超高速で、初期化のレイテンシーコストがかからないので、みんな大好きですよね。
ここで注目すべきことは、Lambda Defaultでは、これらの実行環境はすべて、私たちがsingly concurrentと呼ぶものだということです。つまり、特定の実行環境から同時に実行されるinvokeは常に1つだけということです。後で時間が経過すると複数のinvokeに再利用されるかもしれませんが、ある時点では、実行環境ごとに1つのinvokeだけがアクティブです。ですから、Lambda Defaultでconcurrencyと言うとき、それが本当に意味するのは、アクティブなin-flight invokesの数、または、それらのin-flight invokesを処理しているアクティブな実行環境の数です。それがLambda Defaultにおけるconcurrencyの意味です。
LMIでは、少し違います。ここには、バージョンを公開したときに事前初期化された3つの実行環境があります。そして、invokeが入ってき始めると、LMIは実際に、単一の実行環境に複数の並行invokeを送ることができます。これを私たちはmulti-concurrencyと呼んでいます。単一の実行環境が複数のinvokeを同時に処理できるんです。そしてこれがcold startsがない理由です。なぜなら、関数のアクティベーションの一部として、これらの実行環境を事前初期化しているからです。なので、invokeが入ってくると、常にこれらの事前初期化された実行環境のいずれかにルーティングされます。つまり、LMIではcold startsがないんです。
ここで最初の質問は、どれだけのconcurrency、つまりどれだけのmulti-concurrencyを各実行環境に送れるのかをどうやって知るのか、ということです。さて、私たちは実行環境が受け取れる最大concurrencyについて、言語に基づいたデフォルト値を考え出しました。皆さんがLambdaや私たちのスイートの他のserverless製品上で構築してきたすべてのアプリケーションを調査した結果、すべてのワークロードを見て、これらのデフォルト値を導き出しました。ただし、常にオーバーライドできます。これはcreate function APIの新しいcapacity provider configセクションにあります。実行環境ごとの最大concurrencyも指定できるので、依存関係などで私たちが把握していない特定のボトルネックがある場合は、ここに来て、実行環境が受け取れる最大concurrencyをオーバーライドできます。
さて、私たちはこの魔法のような最大同時実行数を考え出すのが簡単ではないこと、そして万能な解決策は存在しないということも認識していました。そこで、この最大同時実行数を高く設定しすぎた場合に備えて、いくつかの保護機能を用意しています。では、それがどのように機能するか見ていきましょう。ここにマネージドEC2インスタンスがあり、その上にいくつかの実行環境がデプロイされています。そして、これらのインスタンス上で、実行環境の前段に、私たちがデプロイするエージェントが配置されています。ここではLMIエージェントと呼んでいますが、このエージェントは、呼び出しが入ってきたときに実行環境へのプロキシとしても機能します。
呼び出しが私たちのサービスに入ってくると、すべての実行環境に負荷を均等に分散しようとします。実行環境を選択して、そのインスタンス上のこのLMIエージェントにルーティングします。
さて、実行環境が設定した最大同時実行数に達した場合、または最大同時実行数に達する前であっても、メモリプレッシャーやCPUプレッシャーなど、高いリソースプレッシャーが発生し始めた場合、LMIエージェントは「ちょっと待って。これは負荷が高すぎる。他を試して」と言い、呼び出しを別の実行環境に再ルーティングします。さて、これらすべての実行環境が熱くなり始めて、みんなが私たちに待つように言ってきたら、実際にあなたのところに戻って、呼び出しをスロットルします。これを行うのは、先ほど言ったように、私が有効スループット保護と呼んでいるもののためです。最大同時実行数に達するまで、盲目的に呼び出しトラフィックをすべて実行環境に送り続けて、実際にすべての実行環境をブラウンアウトさせたりクラッシュさせたりして、アプリケーション全体が停止してしまうようなことは避けたいのです。そこで、実行環境がどのような状態にあるかを測定して確認し、ブラウンアウトしそうな状態になってきたと判断したら、一部のトラフィックを拒否し始めます。そうすることで、少なくとも持っている容量で前進できるようにします。
メトリクスに関しては、これが発生し始めた場合、スロットルされた正確な理由とボトルネックとなっているリソースを示す新しいCloudWatchメトリクスがあります。最大同時実行数によってスロットルされることもあります—これは同時実行スロットルです—またはCPUスロットル、メモリ、ディスクもあります。これらのスロットルを引き起こしたボトルネックリソースは何だったのか、ということです。そして、次のセクションに移る前に、マルチ同時実行についてもう一つ。実行環境が複数の呼び出しを同時に処理しているため、アプリケーションをコーディングして開発する際には、これらのスレッドセーフティのベストプラクティスを念頭に置く必要があることを理解することが重要です。これは、単一の同時実行環境を持つLambdaのデフォルトとは異なる点です。ここでのスレッドセーフティのベストプラクティスとは、複数の呼び出しが同時に実行されているときに、共有オブジェクトやグローバルオブジェクトを変更しないようにする必要があるということです。データ構造にはスレッドローカルストレージとスレッドセーフなストレージを使用してください。初期化している共有クライアントや接続については、呼び出し自体でそれらの設定が不変であることを確認してください。また、ディスクへの書き込みを行う際には、複数の呼び出しが同時にディスクに書き込むと、互いに上書きしてしまう可能性があることを覚えておく必要があります。そのため、スラッシュtempへの書き込みには、リクエスト固有のファイル名を使用してください。
リソースベースのスケーリングとセキュリティ境界の設計
さて、これが同時実行についてでした。次はスケーリングについて話しましょう。改めて、Lambdaのデフォルトでスケーリングが何を意味するかをおさらいしましょう。Lambdaのデフォルトでは、スケーリングは単に自然発生的なものです。これらのコールドスタート—これは新しい実行環境を初期化するときです—そしてそれが実際にスケールする方法なのです。大量の呼び出しを送信すると、多くの同時呼び出しが発生している場合、呼び出しパスでコールドスタートとして実行環境を自然にスケールアウトします。しかしLMIでは、コールドスタートがないと言いました。そこで問題になるのは、これらの既存の実行環境すべてが飽和点に達し始めた場合、実際にどのように、そしていつ新しい実行環境をスケールアップするのか、ということです。
LMIにおけるスケーリングは、実際には非同期でリソースベースのスケーリングです。これが意味するのは、実行環境のリソース負荷を常に監視していて、特定の閾値に近づいてきたことを検知すると、その時点で非同期的にキャパシティプロバイダー内で新しい実行環境をスケールアップするということです。そして、新しいインスタンスが必要な場合は、それも行います。では、ここで見ていきましょう。ここには3つのインスタンスと3つの実行環境があります。親切なLMIエージェントがいて、このLMIエージェントは実行環境とインスタンスからCPU使用率の統計を常に収集し、そのデータを私たちに送信しています。私たちはキャパシティプロバイダーレベルでの平均CPU使用率を監視していますが、同時にファンクションレベルでも監視していて、この目標CPU使用率の閾値を維持しようとしています。この目標閾値のプラスマイナス10%の範囲内にいる場合、定常状態にあると呼んでいます。問題なく、スケーリングアクションは発生していません。CPUが熱くなり始めて、プラス10%を超える範囲に入り始めると、その時点で新しい実行環境をスケールアップし始めます。
まず、既存のEC2インスタンスを埋めていき、それでも足りない場合は、新しいEC2インスタンスを起動して、そこにさらに実行環境をデプロイします。さて、もし非常にスパイキーなトラフィックのバーストがあって、私たちが反応してこれらのインスタンスと実行環境をキャパシティプロバイダーに追加できるよりも速くバーストした場合、その時はCPU使用率がgoodput保護モードに入ってしまい、実際にその負荷に対応するためのインスタンスと実行環境をさらに立ち上げることができるまで、スロットルをかけなければなりません。
スケールダウンに関しては、逆になります。その後クールダウンし始めてマイナス10%のマークを下回ると、まず実行環境をスケールダウンし、その後圧縮して、詰め直すことができればインスタンスを実際にスケールダウンします。スケールダウンに関しては、設定した最小実行環境数によって常に保護されています。デフォルトでは3ですが、ファンクションへの呼び出しがまったくない場合でも、その数を下回ってスケールダウンすることはありません。
さて、皆さんがおそらく抱いている疑問は、この魔法の目標CPU使用率閾値とは何なのか、ということですよね。ここで、あのキャパシティプロバイダースケーリング設定の作成と、私が話した、より高度なスケーリングオプションに戻ります。スケーリングモードには、automaticとmanualがあります。automaticの場合、基本的には負荷パターンやスケーリングパターンを見て、アプリケーションにとって適切な場所にその閾値を自動的に調整します。manualモードでは、自分の手で、自分のコントロール下に置くことができ、目標CPU使用率のパーセンテージを手動で設定できます。
これらすべての楽しいものを監視するためのメトリクスに関してですが、これらはすべてLambda Managed Instances用に追加した新しいメトリクスです。ファンクションレベルでは、CPU使用率とメモリ使用率を提供しています。これはそのファンクションのすべての実行環境にわたって集約されています。また、同時実行数も確認できます。最大制限と実際に使用している数の比較ですね。そして最後のチャートは、ファンクションに対してスケールアップした実行環境の実際の数です。
そして、同様のメトリクスがキャパシティプロバイダーレベルでも用意されています。つまり、キャパシティプロバイダー内に複数の関数がある場合ですね。インスタンスレベルでは、メモリ使用率、CPU使用率、そしてキャパシティプロバイダー内で起動した実際のインスタンス数を確認できます。さて、スケーリングについてここで皆さんにお伝えしたい要点ですが、これもStephenが触れていたことですが、Lambdaデフォルトでは、関数が私たちのインフラストラクチャ上で実行される際、Firecracker上に構築された非常に特殊なスタックを使用しており、これはスパイクが多く、散発的でバースト性の高いワークロードを処理するために超最適化されています。コールドスタートに対して超最適化されています。コールドスタートのレイテンシを低く抑えるために超最適化されているので、実際に呼び出しのパス内で新しい軽量なFirecracker VMを立ち上げることができるのです。
一方、Lambda Managed Instancesは、実際には異なるプロファイルのワークロード向けに構築・設計されています。Stephenが言っていたように、これは安定したワークロード、つまり良好なベースライントラフィックがあり、より滑らかで予測可能なワークロード向けに構築されています。この機能の目的全体が、私たちが裏側で使用している特殊なスタックから離れて、お客様のアカウント内のより汎用的なEC2インスタンスに移行することなんです。つまり、下にある仕組みが大きく異なるため、Lambda Managed Instancesに適したワークロードのプロファイルは、デフォルトに適したプロファイルとは異なるのです。ですから、この2つは本当にLambdaの補完的な機能であり、一緒に使用することでより多くのユースケースをカバーできます。
さて、最後のセクションはセキュリティ境界についてです。先ほど申し上げたように、Lambdaデフォルトでは、すべての関数が私たちのサービスアカウントで実行されています。大きなマルチテナントアカウントです。そしてLambdaデフォルトでは、各関数の実行環境がマルチテナントセットアップであるため、独自のVM内で実行されます。Lambda Managed Instancesでは、すべてがお客様のアカウント内で実行され、他の誰のコードもお客様のアカウント内で実行されません。その意味でシングルテナントセットアップです。そして、Lambda Managed Instancesのセキュリティ境界は実際にはキャパシティプロバイダーなのです。
関数間でVMレベルの分離が必要な場合、その方法は別々のキャパシティプロバイダーを持つことです。なぜなら、定義上、2つの別々のキャパシティプロバイダー内のインスタンスは異なるものになるからです。ですから、2つの関数を別々のキャパシティプロバイダーにマッピングすれば、それらは異なるインスタンス内の異なるVM上に配置されます。EC2インスタンス内では、私たちがデプロイする関数実行環境は基本的にコンテナなので、コンテナ境界によって分離されています。また、複数の関数をキャパシティプロバイダーにマッピングした場合、先ほど述べたように、それらの異なる関数からの実行環境も同じインスタンスを共有でき、ここでもコンテナ境界となります。ですから、ここでの要点は、関数間でVMレベルの分離が必要な場合は、それらを別々のキャパシティプロバイダーにマッピングしてください。なぜなら、それがLambda Managed InstancesにおけるVMレベルのセキュリティ境界だからです。
パートナー統合、開発ツールサポート、価格体系とまとめ
それでは、Stevenにバトンタッチして、パートナー統合とツール、そして価格についてお話しいただきます。Lambda Managed Instancesについて本当に良い紹介でしたね。これから、私たちが持っている新しいパートナー統合についてお話しし、ローンチパートナーであるDatadogとZEETをご紹介します。DatadogはLambda Managed Instancesに対して完全なオブザーバビリティを提供します。お客様は主要なメトリクスを監視して、Lambda Managed Instancesの健全性と使用率を理解でき、また、お客様はそれらのメトリクスや、注意が必要なエラーや異常な動作についてアラートを設定することもできます。上流および下流のサービスにまたがる自動的に相関付けられたメトリクス、ログ、トレースを使用して、お客様は問題を調査し解決することもできます。
新しく起動されるすべてのインスタンスには、トレースサポートと自動インストルメンテーションが備わっています。そのため、お客様はDatadog extensionをインストールするだけで、自動的なトレース伝播を取得できます。さて、ZEETもまた、Lambda Managed Instancesをその自律最適化プラットフォームを通じてサポートしており、Lambda EC2インスタンスおよび環境全体のパフォーマンス、コスト、信頼性の向上を支援します。これにより、エンジニアリングチームやプラットフォームチーム、そしてFinOpsチームに、安全でデータに基づいた最適化された意思決定を行うための単一のワークフローが提供されます。彼らのプラットフォームは、Lambda関数を自動的にスコアリングし、Lambda Managed Instancesへの移行に適した候補を表示してくれるため、推測作業を行う必要がありません。
移行の準備が整ったら、ZEETのco-pilotを使用することで、ワンクリックで関数の移行と設定が可能になります。これは、Lambda Managed Instancesへ関数を移行する際の、シンプルで摩擦の少ない方法です。さて、AWS AppConfigもフィーチャーフラグ機能を備えており、そのサービスに付属するその他の動的設定も、Lambda Managed Instancesによって完全にサポートされています。AWS AppConfig agent Lambda extensionをLambda関数として使用することで、これらのフィーチャーフラグの呼び出しをよりシンプルにすることができます。また、このextension自体には、コストを削減しながらAWS AppConfigの使用を簡素化するベストプラクティスが含まれています。このコスト削減は、AWS AppConfigサービスへのAPI呼び出しの減少と、Lambdaの処理時間の短縮によってもたらされます。
さて、Amazon CloudWatch Lambda InsightsもLambdaコンソールからワンクリックでデプロイメントが可能です。これにより、キャパシティプロバイダーをフィルタリングできます。インスタンスタイプや関数へのドリルダウン機能に加えて、最大および平均CPU使用率やメモリ使用率の統計など、1分間隔の粒度で12の主要メトリクスを提供します。これにより、Lambda Managed Instancesを監視するための完全に統合された体験が提供されます。さて、現在Powertools for AWSをお使いの場合、Powertoolsは実際には、オブザーバビリティ、バッチ処理、冪等性の実装、フィーチャーフラグやデータ抽出といった、さまざまなユースケースにわたってアプリケーション開発とサポートを標準化するのに役立つユーティリティのスイートです。
Powertoolsスイートもまた、完全に互換性があり、スレッドセーフでLambda Managed Instances上で実行する準備が整っています。そしてもちろん、完全なインフラストラクチャ
完全なInfrastructure as Codeのサポートが、AWS CloudFormation、Serverless Application Model、AWS Cloud Development Kit、そしてパートナーであるTerraformを通じて提供されています。Archanaが話していたすべてのAPIは、これらのフレームワーク内で完全にサポートされています。
それでは価格の観点から見ていきましょう。 AWS Lambda Managed Instancesは、EC2ベースの価格設定を使用しており、EC2インスタンスのコストに加えて15%の管理手数料が上乗せされます。インスタンス自体の価格は、そのインスタンスに適用される割引に大きく依存します。ただし、管理手数料は依然としてEC2インスタンスのデフォルト価格に基づいて計算されます。それに加えて、現在のLambdaと同じ呼び出しごとのコストが引き続き課金されますが、すべてがお客様のマシン上で実行されるため、関数の実行時間に対するコストは不要になります。
それではまとめとして、いくつかの重要なポイントを見ていきましょう。先ほども申し上げましたが、Lambda Managed Instancesは、現在Lambdaで実行しているLambda関数の置き換えとして設計されているわけではありません。これは本当に特定のユースケース、つまり高トラフィックで定常的なワークロードや、特定のユースケースで関数を実行するために特殊なコンピューティングオプションが必要な場合を支援するために設計されています。それ以外のすべてについては、Lambdaは予測不可能なトラフィック、短時間の実行、または頻度の低い呼び出しを持つ新しいアプリケーションを引き続き実行する機能を提供します。これが本当に重要なポイントです。
そして、私たちがお客様のために何を実現したかを理解していただくと、基本的にお客様自身で実行環境を定義できるようにしたということです。これは今日お客様が使っているのと同じLambdaを実行するもので、同じ体験が得られます。同じプログラミングモデルを維持でき、同じアーキテクチャを維持でき、同じ開発ツールを使用できますが、関数がどこでどのように実行されるかについて、より多くのコントロールが得られます。そして、それに加えてEC2で得られるすべてのコストメリットを適用することもできます。
それでは本日は以上となります。Lambda Managed Instancesで皆さんが何を構築されるのか、私たちは本当に楽しみにしており、皆さんがそれで何をされるのかを見るのを心待ちにしています。どうもありがとうございました。
※ こちらの記事は Amazon Bedrock を利用し、元動画の情報をできる限り維持しつつ自動で作成しています。


























































































































Discussion