キーポイント
-
Lambdaは、サーバー管理や運用のオーバーヘッドなしに、オンデマンドでコードを実行することを可能にし、様々な統合言語で効率的な実行を可能にする。
-
Lambdaは同期および非同期呼び出しモデルを提供する。同期呼び出しは迅速なレスポンスを保証し、非同期呼び出しは遅延実行のためにリクエストをキューに入れる。
-
Lambdaは、可用性、効率性、スケール、セキュリティ、パフォーマンスといった基本設計原則を遵守しており、信頼性が高く安全な実行環境を構築し、オーバーヘッドを最小限に抑え、リソースを効率的にスケールさせるための技術的決定を通知する。
-
呼び出し要求ルーティングレイヤーは、マイクロサービスを接続し、可用性やスケールなどの属性を提供する。
-
Lambdaスナップショット配信サービスは、チャンキングとオンデマンドローディングを組み込み、呼び出しプロセスを合理化し、特にダウンロード時間を短縮し、システム効率を向上させる。
キーポイント
AWS Lambdaは、可用性、拡張性、安全性、耐障害性の高いサービスとしてコードを実行するサーバーレス・コンピュート・サービスだ。Lambdaは、基礎となるコンピュート環境を抽象化し、開発チームが主にアプリケーション開発に集中できるようにし、市場投入までの時間を短縮し、総所有コストを削減する。
AWSのシニアプリンシパルエンジニアであるMike Danilov氏は、QCon San Francisco 2023の中で、AWS Lambdaとそのフードの中身について発表した。本記事はその講演の内容を表したもので、まずLambda自体の紹介から始まり、サービスの主要なコンセプトとその基礎を概説することで、システムの理解を深めることを容易にする。
その後、全てのマイクロサービスを接続し、システム全体のシームレスな運用を保証する重要なコンポーネントとして認識されている呼び出しルーティングレイヤーについて掘り下げていく。続いて、コードの実行が行われる空間であるコンピュート・インフラにシフトする。これは、より広範なサーバーレス・フレームワーク内のサーバーレス環境を表している。同時に、クラウドインフラでコードを実行する際によくあるトピックであるコールドスタートについての話も織り交ぜていく。
AWS Lambdaの概要
Lambdaは、サーバーの所有権、プロビジョニング、管理を必要としないサーバーレス・コンピューティング・システムとして、ユーザーがオンデマンドでコードを実行することを可能にする。様々な統合言語で構築されたLambdaは、ユーザーがコードのみに集中できるようにすることで、プロセスを合理化し、効率的に実行される。
さまざまな需要に迅速に対応するLambdaは、数年前から稼働しており、毎月数百万人のユーザーに対応し、数兆回という相当量の呼び出しを生み出している。運用の仕組みはシンプルで、ユーザーは好みのメモリサイズと、コンピューティングやCPUを含むリソースの比例割り当てを指定する。
Lambdaは、同期呼び出しから始まる2つの呼び出しモデルをサポートしている。このシナリオではリクエストが送信され、実行環境にルーティングされ、コードが実行され、同じタイムライン上で同期応答を提供する。一方、非同期呼び出しでは、リクエストをキューイングし、ポーラーシステムを通じて別のタイムラインで実行する。同期呼び出しと非同期呼び出しの実行が等価であることを強調し、本コンテキストでは主に同期呼び出しに焦点を当てて議論する。
その設計原則は、Lambdaのアプローチを理解する上で極めて重要であり、技術的な決定やトレードオフのフレームワークの指針となる。最初の原則である可用性は、すべてのユーザーリクエストに対する信頼性の高いレスポンスを保証する。オンデマンド・システムでは効率性が重要であり、無駄を省くためにリソースの迅速なプロビジョニングとリリースが求められる。需要に応じて迅速にスケーリングし、無駄を最小限に抑えるために効率的にスケールダウンすることが、スケールの信条を表している。セキュリティはAWSの最優先事項であり、ユーザーがコードを実行し、信頼できる安全でセキュアな実行環境を保証する。最後に、Lambdaはパフォーマンスを重視しており、アプリケーションのビジネスロジックの上に最小限のオーバーヘッドを提供し、目に見えない効率的なコンピュートシステムを実現することを目指している。
呼び出し要求のルーティング
呼び出し要求のルーティングはLambdaの重要な部分であり、様々なマイクロサービスを相互接続する重要なレイヤーであり、可用性、スケール、実行環境へのアクセスといった本質的な属性を提供する。このレイヤーをよりよく理解するために、構築プロセスを例示することで実践的なアプローチを取ろう。
このシナリオでは、アリスが自分のコードをクラウドにデプロイするための支援を求めている。最初のステップは、彼女のコードと関連するコンフィギュレーションを保存するコンフィギュレーション・サービスを組み込むことだ。続いて、フロントエンドが導入される。フロントエンドは、呼び出しリクエストの処理、検証と認可の実行、設定の詳細のデータベースへの保存を担当する。次に必要なコンポーネントはワーカーで、アリスのコードの実行環境またはサンドボックスとして機能する。一見シンプルだが、オンデマンド・コンピューティング・システムでは、呼び出し中にワーカーや実行環境が利用できるかどうかが不確実であるという課題が生じる。これに対処するために、オンデマンドで実行環境やサンドボックスを作成する「プレイスメント」と呼ばれる新しいシステムが導入される。
フロントエンドは、作成された実行環境に呼び出し要求を転送する前に、サンドボックスを要求するためにプレイスメントと通信する必要があり、機能的なセットアップが完了する。しかし、各呼び出し要求の前にオンデマンドの初期化が含まれるため、課題が残る。この初期化には、実行環境の作成、顧客コードのダウンロード、ランタイムの開始、関数の初期化など、複数のステップが含まれる。このプロセスには数秒かかることがあり、顧客体験全体に悪影響を及ぼす可能性がある。
待ち時間の分布グラフは、時間の経過に伴う呼び出し時間の頻度を示している。緑色のレイテンシは、ビジネスロジックの効率とCPU使用率を反映し、コードの実行が成功したことを示す。オーバーヘッドを最小限に抑え、顧客体験を向上させるために、ワーカーマネージャーという新しいシステムが導入された。2つのモードで動作し、フロントエンドのリクエスト時に既存のサンドボックスを提供し、スムーズな「ウォーム・インボーク」を導くか、サンドボックスがない場合は、新しいサンドボックスを作成するために配置を含むより遅いパスを開始する。ウォーム・インボークは最小限のオーバーヘッドとスピードを示すが、さらなる改良の必要性を認識しつつ、コールド・スタートをなくす努力が進められている。
上記は、本番環境におけるLambdaの同期呼び出しルーティングの実用的な描写であり、耐障害性の強化に重点を置いている。追加のアベイラビリティゾーンとフロントロードバランサーが統合された。サンドボックスのトラッキングを担当するワーカーマネージャは、インメモリストレージに依存しているため、ホストの障害時にデータが失われる可能性があるという課題があった。これに対処するため、アサインメント・サービスと名付けられた代替サービスが1年前に導入された。機能的には似ているが、ジャーナル・ログとして知られる信頼性の高い分散ストレージを備え、地域の一貫性を保証している。
アサインメント・サービスはパーティションを利用し、それぞれがリーダーと2人のフォロワーを持ち、リーダー・フォロワー・アーキテクチャを活用してフェイルオーバーを容易にする。この変革により、システムの可用性が大幅に強化され、単一ホストの障害やアベイラビリティゾーンのイベントに対する耐障害性が向上した。インメモリから分散ストレージへの移行は、リーダー・フォロワー・モデルの実装と相まって、効率を改善し、待ち時間を短縮した。これは、コールド・インボークとウォーム・インボークの側面と、可用性を高める上で一貫性のある状態が果たす極めて重要な役割について探求した、呼び出しルーティングに関する最初の章の締めくくりとなる。
コンピュート・ファブリック
コンピュート・ファブリック、具体的にはLambdaのインフラ内のワーカー・フリートが、コードの実行を担う。このフリートはワーカーと呼ばれるEC2インスタンスで構成され、実行環境が構築される。キャパシティ・マネージャーは、需要に基づいた最適なフリート・サイズの調整を保証し、ワーカーの健全性を監視して、不健全なインスタンスを速やかに交換する。データサイエンスのコラボレーションは、リアルタイムのシグナルと予測モデルを活用することで、配置とキャパシティマネージャが情報に基づいた意思決定を行うのを支援する。
データの分離を考慮し、複数のユーザーのコードを同じワーカー上で実行するという課題について考察している。高速仮想化技術であるFirecrackerを採用することで、このハードルを克服できる。各実行環境をマイクロVMにカプセル化することで、Firecrackerは強力なデータ分離を保証し、多様なアカウントを同じワーカー上に安全に共存させることができる。EC2からFirecrackerへの移行は、リソースの利用率を大幅に向上させ、過負荷を防ぎ、安定したパフォーマンスを提供する。
強固な分離、最小限のシステムオーバーヘッド、ワーカーフリートの熱に対する制御の改善など、Firecrackerの利点が強調されている。Firecrackerの採用により、レイテンシ分布図に示されるように、新しい実行環境を作成するコストが顕著に削減される。続いて、VMスナップショットを使用して初期化プロセスを迅速化し、新しい実行環境の作成にかかるオーバーヘッドを削減するというアイデアが紹介される。
VMスナップショットのためのシステム構築のプロセスが概説されている。本文では、スナップショットをワーカー間で分散させること、VMの高速な再開を確保すること、強力なセキュリティ対策を維持することを強調している。「コピー・オン・リード」として知られるインダイレクト・レイヤーを導入することで、共有メモリに関連する潜在的なセキュリティ脅威に対処する。同一のVMに一意性を復元するという課題や、JavaやLinuxなど様々なコミュニティとの継続的なコラボレーションについては、システムのセキュリティと効率性を高めるための継続的な取り組みの一環として議論されている。
スナップショットの配布
スナップショットの配布はEC2インスタンスにとって重要な側面であり、特にスナップショットのサイズが30ギガバイトに達することもあることを考慮すると重要である。従来のダウンロード方法では、完了までに少なくとも10秒はかかる。このプロセスを最適化するために、ビデオストリーミングに例えて、コンテンツは最初の部分が再生されるときにバックグラウンドで徐々にロードされる。同様に、スナップショットはより小さなチャンク(通常は512キロバイト)に分割され、VMの再開に必要なチャンクの最小セットを最初にダウンロードできるようにする。このアプローチには、ダウンロード時間の償却と、起動時に必要な作業セットのみを取得できるという2つの利点がある。
オンデマンド・チャンク・ローディングのメカニズムには、VMメモリーをスナップショット・ファイルにマッピングすることが含まれる。プロセスがメモリにアクセスすると、メモリページからデータを取得するか、利用できない場合はスナップショットファイルにフォールバックする。このプロセスの効率は、ローカルキャッシュ、分散キャッシュ、オリジンキャッシュを含むキャッシュヒット率に大きく依存する。使い慣れたチャンクを識別し共有することで、キャッシュヒット率を最大化する戦略が提案されている。例えば、オペレーティングシステムとランタイムのチャンクを重複排除し、複数の機能で共有することで、効率を高め、領域への呼び出しを最小限に抑えることができる。
チャンク管理をさらに最適化するために、 レイヤー化された増分スナップショットが提案されている。これらのスナップショットは異なるキーで暗号化され、オペレーティングシステム、ランタイム、関数のチャンクに分類される。オペレーティングシステムのチャンクとランタイムのチャンクは共有でき、出所が不明な場合でも収束暗号化を活用して共通ビットを重複排除する。収束暗号化により、同一のプレーンテキストの内容が同一の暗号化チャンクになることが保証される。この包括的なアプローチにより、キャッシュのローカリティが強化され、ローカルに分散されたキャッシュへのヒットが増加し、遅延のオーバーヘッドが削減される。
本番システムでは、間接レイヤーをスパースファイルシステムに置き換え、リクエストプロセスを効率化し、ファイルシステムレベルでチャンクをオンデマンドで提供する。この洗練されたアプローチは、より効率的で応答性の高いシステムに貢献している。
コールドスタートは解決したか?
スナップショットの配布とVMの再開を成功させた後、システムは理想的にはうまく機能するはずである。しかし、ターゲットの場所に近いにもかかわらず、コールド呼び出しに遅延が発生することがある。この問題を理解するためには、ページキャッシュとメモリマッピングの見直しが不可欠である。オペレーティング・システムの最適化には先読みがあり、通常のファイルではシーケンシャル・リードを予期して、1ページがアクセスされると複数のページが読み込まれる。ランダムアクセスが可能な通常のファイルではなく、マップされたメモリの場合、この方法は非効率であることが判明し、一見ランダムなページ要求に対してスナップショットファイル全体をダウンロードすることになる。
この非効率性はレイテンシ分布グラフに描かれており、解決の必要性を強調している。この問題に対処するため、100台のVMのメモリ・アクセスを分析したところ、一貫したアクセス・パターンが明らかになった。このパターンはページアクセスログに記録され、すべてのスナップショットに添付される。その結果、スナップショット再開時に、システムは必要なページとその順序に関する事前知識を持ち、効率を大幅に向上させる。この革新的なソリューションは、コールドスタートに関連する問題を軽減することに成功している。特筆すべきは、Java関数でLambda SnapStartを有効にし、VMスナップショットの最適化されたパフォーマンスを体験することで、ユーザーはこの改善を直接試すことができる。
まとめ
この記事では、Lambda内の呼び出しルーティングレイヤーを掘り下げ、システムの可用性とスケーラビリティを強化した。コンピュート・インフラを包括的に調査した結果、Firecrackerの導入が紹介された。Firecrackerは、堅牢なセキュリティ対策を維持しながら効率を大幅に向上させるテクノロジーである。システムの性能は著しく向上し、コールドスタートという課題も見事に解決した。これらの努力は、「サーバーを介さずにクラウド上でコードを実行する」という基本コンセプトに結実し、ユーザー体験の圧縮アルゴリズムとしてのLambdaの本質を捉えた。
最後に、詳細はこちらをご覧いただきたい。