> [!abstract] 概要(Abstract の日本語訳) > AWS Lambda はサーバーレスのイベント駆動型コンピュートサービスであり、Function-as-a-service (FaaS) と呼ばれるクラウドコンピュートの一カテゴリに属する。当初 Lambda を公開したとき、関数は単純な圧縮アーカイブとしてパッケージされた 250MB のコードと依存関係に制限されていた。2020 年、最大 10GiB のコンテナイメージを Lambda 関数としてデプロイするサポートを公開し、顧客がはるかに大きなコードベースや依存関係の集合を Lambda に持ち込めるようにした。より大きなパッケージをサポートしながら、Lambda の目標である高速スケール(単一顧客に対して毎秒最大 15,000 の新規コンテナを追加)、高リクエストレート(毎秒数百万リクエスト)、高スケール(数百万の固有ワークロード)、低起動時間(最低 50ms)を満たすことは重大な課題だった。 > > われわれは構築したストレージとキャッシュシステムについて説明する。このシステムはコンテナイメージをオンデマンドで配信するために最適化されており、設計・構築・大規模運用の経験を含む。セキュリティ・効率・レイテンシ・コストの課題に焦点を当て、キャッシング・重複排除・収束暗号化・イレイジャーコーディング・ブロックレベルのオンデマンドロードを組み合わせてこれらの課題に対処した方法を述べる。 > > このシステムを構築して以来、100 万人超の AWS 顧客に対して数百兆回の Lambda 呼び出しを信頼性高く処理し、負荷とインフラ障害に対して優れた耐性を示した。 ## 論文情報 - **タイトル**: On-demand Container Loading in AWS Lambda - **著者**: Marc Brooker, Mike Danilov, Chris Greenwood, Phil Piwonka - **所属**: Amazon Web Services - **発表媒体**: USENIX ATC 2023(Best Paper 受賞) - **発表日**: 2023 年 7 月 10〜12 日、Boston, MA - **PDF**: https://www.usenix.org/system/files/atc23-brooker.pdf ## 概要 AWS Lambda がコンテナイメージ(最大 10GiB)のサポートを追加する際に直面した「冷起動レイテンシを悪化させずに大容量コンテナを起動する」という課題を解決したシステムを記述する。コンテナイメージを 512KiB の固定サイズチャンクに分割し、(1) 決定論的フラット化と収束暗号化によるブロックレベル重複排除、(2) 3 階層キャッシュとイレイジャーコーディングによる低レイテンシ・高可用性配信、(3) FUSE ベースのブロックデバイスによるスパースロード、の 3 本柱で構成される。本番環境で数百兆回の呼び出しを処理し、USENIX ATC 2023 最優秀論文賞を受賞した。 ## 問題設定 - **入力**: 最大 10GiB のコンテナイメージ(Docker OCI 形式)を Lambda 関数としてデプロイしたい顧客のリクエスト - **出力**: 冷起動レイテンシを最小化しつつコンテナを起動する(目標: 最低 50ms) - **スケール要件**: 単一顧客に対して毎秒最大 15,000 コンテナを起動。単純に 10GiB × 15,000 を転送すると 150Pb/s のネットワーク帯域が必要になり不可能 - **活用できる性質**: - **キャッシャビリティ**: スパイクは少数の人気イメージに集中する - **共通性**: 多くのイメージが同じベースレイヤー(Alpine、Ubuntu など)を共有する - **疎性(Sparsity)**: Harter et al. [15] によれば起動時に必要なデータはコンテナ全体の平均 6.4% に過ぎない ## 提案手法 ### アーキテクチャ全体 3 つのコンポーネントで構成される。 1. **決定論的フラット化と チャンク生成**(制御プレーン、関数作成時に 1 回のみ実行) 2. **3 階層キャッシュ**: ワーカーローカル(L1)→ AZ レベル分散キャッシュ(L2)→ S3 オリジン(L3) 3. **スパースロード機構**: FUSE ベースのブロックデバイスを介してチャンクをオンデマンドで取得 ### ブロックレベルスパースロード(Section 2) 既存のファイルシステムレベルのアプローチ(Slacker、Starlight)は Lambda の厳格なセキュリティ要件に適合しないため、**ブロックレベル**での疎ロードを選択した。ファイルシステム操作は MicroVM ゲスト内部で行い、外部とのやり取りは virtio-blk インタフェースのみに限定することで攻撃対象領域を最小化する。 **フラット化プロセス**: OCI コンテナイメージのタールボールレイヤースタックを、決定論的な ext4 ファイルシステム 1 枚に「フラット化」する。通常のファイルシステム実装が持つ並行性起因の非決定論的挙動(タイムスタンプなど)をすべて除去し、同じコンテナからは必ず同じバイト列が生成されるようにする。これによりベースレイヤーを共有するコンテナ間でチャンクが一致し、ブロックレベルの重複排除が可能になる。 **チャンクサイズ**: 512KiB(固定)。小さいほど重複排除効率が高く疎アクセスに適し、大きいほどメタデータ削減・スループット向上・シーケンシャルリードアヘッドに有利なトレードオフ。 **各 MicroVM の起動フロー**: - Micro Manager がローカルエージェント(FUSE で仮想ブロックデバイスを提供)と Firecracker MicroVM を新規作成 - MicroVM 内のゲストカーネルが virtio-blk 経由でブロックデバイスをマウント - 読み取りはローカルエージェントがローカルキャッシュで処理し、ミスなら上位層からチャンクを取得 - 書き込みはコピーオンライト方式でワーカー上の暗号化ストレージに記録(ビットマップでページ粒度管理) ### 収束暗号化による重複排除(Section 3) セキュリティを維持したままブロックレベルの重複排除を行う仕組み。Farsite [2, 11] の収束暗号化を応用・拡張した。 **アルゴリズム**: 1. チャンクのプレーンテキストを SHA256 ハッシュ → これを AES-CTR の暗号化キーとして使用(決定論的 IV: オールゼロ) 2. 同じコンテンツ → 同じ暗号文 → 同じチャンク名で重複排除可能 3. チャンクのオフセット・キー・SHA256 ハッシュを列記したマニフェストを作成 4. マニフェストの「キーテーブル」のみを顧客固有の KMS キーで AES-GCM 暗号化(ガーベジコレクタがチャンクリストにアクセスできるよう、ハッシュリストは平文で保持) 5. チャンクは暗号文ハッシュの関数で命名し、S3 に保存 **利点**: - キーを共有しない: 顧客マニフェストの復号キーはその顧客専用であり、KMS 経由でその顧客の関数が配置されたワーカーのみがアクセス可能 - 中央ディレクトリ不要: フラット化プロセスは独立して動作し、必要なのは「このファイルを既存になければストレージに上書き」という操作のみ - エンドツーエンド完全性保護: ワーカーがダウンロードしたチャンクをマニフェスト内の MAC で検証し、改ざんを検出 **マニフェストサイズ**: 16GiB コンテナに対して 3MiB 未満(0.02% オーバーヘッド) **塩(Salt)による爆発半径の制御(Section 3.3)**: 人気の高いチャンクが広く共有されると、そのチャンクの障害が多数顧客に波及する(爆発半径問題)。これを防ぐため、キー導出ステップに可変の塩値を混入する。塩値を時間・チャンク人気度・インフラ配置(AZ 間など)で変化させることで、同一コンテンツのチャンクでも意図的に異なる暗号文を生成し、重複排除の範囲を制御する。塩のローテーション頻度で重複排除効率と爆発半径のトレードオフを継続的に調整できる。 **世代別ガーベジコレクション(Section 3.4)**: 中央ディレクトリを持たないため、正確な参照カウントは不可能。代わりにルートベースの世代別 GC を採用する。 - 各ルートは自己完結したマニフェストとチャンクの名前空間 - 新しいルートを定期的に作成し、古いルートに残る使用中データを新ルートへ移行 - ルートは「アクティブ → 退役 → 期限切れ → 削除」というライフサイクルを経る - 期限切れ状態でもデータへのアクセスはアラームを発火させ、誤削除を自動検出・停止する **Figure 5: 重複排除効率の CDF** ![[_attachments/atc23-brooker/fig05-deduplication-unique-chunks-cdf.png]] (Figure 5. チャンク作成時の重複排除効率の経験的 CDF。新規アップロードの約 80% はゼロユニークチャンク(完全な再アップロード)であり、残り 20% の関数でも中央値 2.5%・平均 4.3% のユニークチャンクしか存在しない。重複排除でストレージを最大 23x 削減できることを示す。Source: Figure 5 in Brooker et al., USENIX ATC 2023.) ### 3 階層キャッシュとイレイジャーコーディング(Section 4) **キャッシュ構成**: | 階層 | 場所 | 中央値ヒット率 | 10 百分位ヒット率 | |------|------|----------------|------------------| | L1(ワーカーローカル) | 各ワーカー | 67% | 65% | | L2(AZ レベル分散) | 可用性ゾーン単位 | 99.9% | 99.4% | | L3(オリジン) | Amazon S3 | — | — | | **合計** | — | **~99.94%** | — | 生産環境 1 週間の観測: チャンクの 67% を L1 から、32% を L2 から、0.06% を L3(S3)から取得。 **Figure 7: 各キャッシュ階層のヒット率分布** ![[_attachments/atc23-brooker/fig07-cache-tier-hit-rates.png]] (Figure 7. 1 週間の生産使用における各キャッシュ階層のヒット率: ワーカーローカル(L1)、AZ 内分散(L2)、バッキングストア(L3)。L1 が中央値 67%、L2 が約 32% を受け持ち、L3 は 0.06% のみ。Source: Figure 7 in Brooker et al., USENIX ATC 2023.) **Figure 8: L2 キャッシュのヒット率 CDF** ![[_attachments/atc23-brooker/fig08-l2-cache-hit-rate-cdf.png]] (Figure 8. AZ レベルキャッシュのヒット率の経験的 CDF(1 分バケット、1 週間、本番 AZ 1 基)。ほぼすべてのバケットでヒット率 99.75% 超。左裾は新規作成関数へのトラフィックスパイクに起因する。Source: Figure 8 in Brooker et al., USENIX ATC 2023.) **L2 キャッシュ設計**: - HTTP2 でチャンクを配信 - 2 層ストレージ(ホットチャンク→メモリ、コールドチャンク→フラッシュ) - 退避アルゴリズム: LRU-k [29](スキャン耐性 LRU の亜種) - チャンク分散: コンシステントハッシュ + 負荷平準化最適化 [7] - L1 → L2 ミスでのレイテンシ: 中央値 550µs vs S3 直取得 36ms(99.9 パーセンタイル: 3.7ms vs 175ms) **イレイジャーコーディングによるテールレイテンシ削減(Section 4.1)**: 単純な非レプリケーション方式では、(a) 単一ノード障害によるヒット率低下、(b) 単一ノード帯域上限によるスループット制約、(c) 遅延ノードによるテールレイテンシ悪化、の 3 問題が生じる。レプリケーションはコスト増大するため、代わりに EC-Cache [31] に類似したイレイジャーコーディングを採用した。 **4-of-5 コード**: ワーカーがキャッシュミス時にチャンクをオリジンから取得後、イレイジャー符号化されたストライプをキャッシュに分散アップロード。取得時は必要数(4 ストライプ)より多く(5 ストライプ)をリクエストし、最初に届いた 4 ストライプで再構成する。 - ストレージオーバーヘッド: 25% - リクエスト増加率: 25% - 利点: テールレイテンシの大幅削減、ノード障害時のヒット率低下ゼロ、再試行によるメタ安定性問題の回避 **定常作業(Constant Work)原則**: 成功時と失敗時で同量の作業を行うよう設計。再試行はメタ安定障害モードを引き起こすため使用しない。 **Figure 9: 4-of-5 イレイジャーコーディング vs 4-of-4 並列ロードのレイテンシ CDF** ![[_attachments/atc23-brooker/fig09-erasure-vs-parallel-latency-cdf.png]] (Figure 9. 本番デプロイメントからのクライアント側レイテンシの経験的 CDF 比較。erasure_k(4-of-5 イレイジャーコード)が parallel_k(4-of-4 並列)よりテールレイテンシを大幅に削減。erasure_k は 1500µs 以下でほぼ全ケースが収束するのに対し、parallel_k は 4000µs 超まで裾が伸びる。Source: Figure 9 in Brooker et al., USENIX ATC 2023.) **メタ安定性への対策(Section 4.2)**: ヒット率 99.8% 超のキャッシュが空になると、S3 への負荷が通常の最大 500 倍になり得る。このトラフィック増が冷起動レイテンシを悪化させ、より多くのスロットが必要になり、さらなる起動要求が生じるという自己強化ループ(メタ安定障害)が発生する。対策: - 並行処理数制限: コンテナ起動が遅延して同時タスクが上限を超えると、新規起動を拒否して飛行中の起動が完了するまで待機 - 最大並行数で空キャッシュからの冷起動を積極テスト **LRU-k による退避とキャッシュサイジング(Section 4.3)**: 低頻度の定期 cron ジョブ関数が大量起動すると、LRU では人気のエントリが二度と使われないデータで置き換えられるスキャン汚染が発生する。LRU-k は最後 k 回のアクセス時刻を追跡し、スキャン耐性を持つ。キャッシュサイズは「コスト最適サイズ」と「ヒット率目標を達成するサイズ」の大きい方に設定。 ## 新規性 | 既存手法 | 問題 | 本研究の解決策 | |---------|------|---------------| | Slacker / Starlight(ファイルシステムレベル) | Lambda の攻撃対象領域が増大する | ブロックレベルを維持し、FS 操作はゲスト内部に閉じ込める | | DADI(ブロックレベル、P2P) | 広域重複排除が不可能 | 収束暗号化により中央ディレクトリなしで安全な広域重複排除 | | FaaSNet(レイヤーレベル) | 重複排除なし、フラット化なし | 決定論的フラット化でブロックレベルの重複排除を可能にする | | 通常のレプリケーション | メモリ多用でコスト高 | 4-of-5 イレイジャーコードで 25% オーバーヘッドに抑制 | ## 実験設定 - 本番 AWS 環境(大規模 AWS リージョン 1 基) - 対象期間: 1 週間(キャッシュヒット率計測) - 100 万超の AWS 顧客、数百兆回の Lambda 呼び出し - 評価指標: キャッシュヒット率(L1/L2/L3)、レイテンシ CDF(L2 サーバ側・クライアント側・ローカルエージェント)、重複排除効率(ユニークチャンク率) ## 実験結果 **重複排除**: - 新規アップロードの約 80% がゼロユニークチャンク(完全な再アップロード) - 残り 20% の関数: 平均 4.3%、中央値 2.5% のユニークチャンク - 重複排除によるストレージ削減: 最大 23x **キャッシュ効率**: - L1 ヒット率: 中央値 67%、10 百分位 65% - L2 ヒット率: 中央値 99.9%、10 百分位 99.4% - エンドツーエンドヒット率: 99.94%(L3 からの取得はわずか 0.06%) - L2 レイテンシ(サーバ側): GET 中央値 50µs 未満、PUT 中央値 125µs、99.99 パーセンタイル 413µs **Figure 10: L2 キャッシュサーバの GET / PUT レイテンシ CDF** ![[_attachments/atc23-brooker/fig10-l2-server-get-put-latency.png]] (Figure 10. L2 キャッシュサーバ側で計測した 512KiB チャンクの GET と PUT レイテンシの経験的 CDF(1 週間、本番デプロイ全ノード)。GET は中央値 50µs 未満で非常に安定しており、PUT は書き戻し動作に起因する多モード性があるが 99.99 パーセンタイルでも 413µs。Source: Figure 10 in Brooker et al., USENIX ATC 2023.) **スパースロードのエンドツーエンドレイテンシ(ローカルエージェント視点)**: 多モード分布が観察される: - L1 ヒット: 100µs 未満 - L2 ヒット(+復号処理): 約 2.75ms - L3(S3 オリジン)ヒット: 稀(0.06%) **Figure 11: ローカルエージェントでのエンドツーエンド読み取りレイテンシ CDF** ![[_attachments/atc23-brooker/fig11-local-agent-read-latency-cdf.png]] (Figure 11. ローカルエージェント(FUSE 実装)から見たエンドツーエンド読み取りレイテンシの経験的 CDF。100µs 未満の L1 ヒットモード(約 67%)、2.75ms 付近の L2 ヒットモード(約 32%)という多モード性が明確に見える。L3 ヒットはグラフから切り取られるほど稀。Source: Figure 11 in Brooker et al., USENIX ATC 2023.) **イレイジャーコーディング**: 4-of-5 vs 4-of-4 比較では、erasure_k が 1500µs 以内に 99% 以上を収めるのに対し、parallel_k は 4000µs 超まで裾が伸びる(Figure 9)。 ## 考察 **多モードレイテンシの運用上の課題**: L1/L2/L3 のヒット比率がわずかに変化するだけで平均レイテンシが大きく変動するため、中央値や外れ値パーセンタイルだけでは変化を捉えにくい。著者らはヒートマップや前日比 eCDF を試験運用中だが、定番の提示方法はまだ見つかっていない。 **FUSE の限界と移行**: FUSE 経由でブロックデバイスを提供する構造は、ゲストカーネル→ Firecracker→ ホストカーネル FUSE レイヤー→ ローカルエージェントという 4 段のコンテキストスイッチが発生し、スケジューリングジッタの原因となる。そのため userfaultfd + mmap を使った新実装に移行中。なお FUSE は初期実装としては適切であり、セキュリティ分離・開発のしやすさという点で価値があった。 **Rust 選択の評価**: tokio / reqwest / hyper を使った Rust 実装は、本番で主要なバグなしに運用中。自動ベクトル化の脆弱さ(parity 計算で 10x 差が生じた)は課題だが、criterion クレートによるビルド時マイクロベンチマークと自動ベクトル化アサーションで回帰を防止している。 ## 強み / 弱点・課題 **強み**: - 顧客に複雑さを露出せず(通常の Docker イメージをそのままアップロード)、透明な最適化を実現 - 収束暗号化で信頼なしの重複排除を安全に実現 - イレイジャーコーディングで再試行に依存しないテールレイテンシ削減 - 世代別 GC で顧客データの誤削除リスクを多層に防御 - Rust 実装により本番での主要バグなし **弱点・課題**: - FUSE の 4 段コンテキストスイッチがジッタの原因(userfaultfd+mmap に移行中) - 暗号化復号がレイテンシに与える影響(最適化中) - 新規関数の初回起動時に L2 キャッシュのコールドスタートが生じ、ヒット率が一時的に低下する(L2 プリウォームを検討中) - 塩によるデデュプ範囲制御はストレージコスト増大とのトレードオフ ## 広範な教訓(著者の主張) - **コンテナは「大規模な静的リンク」**: 依存関係クロージャのより軽量な代替が必要 - **キャッシュはメタ安定障害リスクを孕む**: 空キャッシュ時の挙動設計と積極テストが不可欠 - **MicroVM は強力な新ツール**: プロセス並みの軽量さで、外部 OS ロジックをプラグインできるインタフェースを持つ