100 万個の同時実行サンドボックスを数秒でスケールさせる方法

@modal
英語23 時間前 · 2026年7月16日
128K
415
41
14
515

TL;DR

Modal が中央集権型アーキテクチャから分散型のワーカー中心モデルへ移行し、100 万個のサンドボックスを数秒で立ち上げ可能にした経緯を説明します。

この記事は Colin Weld と Connor Adams によって執筆されました。こちらで読むか、[ブログ](https://modal.com/blog/scaling-to-1-million-concurrent-sandboxes-in-seconds)でご覧ください。

Modal では、サンドボックスをはじめとするさまざまなものを構築しています。エージェントはサンドボックス内で動作し、エージェントがソフトウェアを飲み込みつつあります。現在、Modal は 1 日あたり数百万のサンドボックスを実行し、顧客ごとに最大 5 万の同時サンドボックスをサポートし、強化学習からバックグラウンドエージェントまで、さまざまなユースケースを大規模にサポートしています。

ユーザーはますます多くのサンドボックスを、より高いレートで作成する必要が生じています。強化学習では、数百万のサンドボックスを同時に実行し、ロールアウトの開始時に数十万のサンドボックスを一気に作成する必要がある場合があります。同様に、エージェントはトラフィックの急増に対処するために、大規模なスケールと高い同時作成レートを必要としています。

既存のサンドボックスプラットフォームは非常に優れていますが、これらの規模向けに設計されたわけではありません。他の既存のソリューションも同様です。私たちはスケールとパフォーマンスにこだわっており、インフラストラクチャがエージェントの成長を促進し、摩擦を生まないようにしたいと考えています。そこで、白紙に戻して再設計することにしました。

ここ数か月で、コアのサンドボックスプラットフォームをスケールと信頼性の両面でゼロから再構築しました。新しいシステムでは、ユーザーは数百万のサンドボックスを同時に実行し、1 秒あたり数万のサンドボックスを作成できます。コントロールプレーンからすべての中央ボトルネックを排除し、実質的なスケーリング制限がないようにしました。また、コンテナのスケジューリングと起動のあらゆる部分を最適化し、スケジューリングパスを、ワーカーフリート上で直接コンテナを作成するロードバランサーの層に簡素化しました。

プラットフォームの能力を示すため、100 万のサンドボックスを同時に実行し、そのすべてを 1 分未満で作成しました。

Modal - inline image

多くのサンドボックスを実行できる証拠です。

ほとんどのソリューションがスケールしない理由

100 万のサンドボックスを実行することは、あらゆるコンテナプラットフォームの限界に挑戦します。それは単にコンテナの数が多いだけでなく、これだけの数のサンドボックスを実行するには数万のコンピュートノードが必要だからです。O(コンテナ) または O(ノード)、あるいはその両方の操作が多数存在し、従来のコンテナプラットフォームではスケーリングの限界に達します。

例として Kubernetes の場合:

  • スケジューリングアルゴリズムは最悪の場合、n ノードと p ポッドに対して O(n x p) であり、スケジューリングはデフォルトで直列化されています。
  • 各ポッドはそのライフサイクル中に etcd (Kubernetes の中央永続ストア) に複数回書き込みを行います。これにより、ポッド作成レートが高い場合やポッドのチャーンが多い場合に深刻な問題が発生する可能性があり、etcd はキースペース内でネイティブにシャーディングできません。
  • 各ノードは生存確認のために、ハートビート間隔ごとに少なくとも 1 回 etcd に書き込む必要があるため、ベースラインの etcd 書き込み負荷はポッド作成とは完全に独立して O(ノード) になります。
Modal - inline image

Kubernetes のスケジューリングフローの近似図。新しいポッドは API サーバーによって etcd (強整合性を持つ永続ストア) に書き込まれます。Kubernetes スケジューラーは新しい未割り当てのポッドを監視し、API サーバーへの呼び出しを通じてノードに割り当てます。これにより再び etcd に書き込みが行われ、この書き込みが完了すると、ノードがポッドを起動できます。

Kubernetes はスケール可能ですが、それには多大な労力が必要です。多数のノードを実行するために、etcd は一般的に書き換えまたは置き換えが必要です。高いスケジューリングスループットをサポートするには、複雑な scatter-gather システムを構築してスケジューリングアルゴリズムを並列化しつつ、ポッド状態の単一の真実源を維持する必要があります。Kubernetes は設計の基盤として強整合性に依存しているため、シャーディングと並列化はデフォルトでは容易ではありません。

Modal の元のサンドボックスアーキテクチャにも同様の問題があります。Kubernetes と同様に、バックエンド全体で強整合性に依存しているため、サンドボックスの作成とスケジューリングにはグローバルな調整が必要であり、Postgres への O(サンドボックス) の書き込みが発生しますが、これを簡単にシャーディングすることはできません。

Modal - inline image

Modal の元のサンドボックスコントロールプレーンアーキテクチャ。サンドボックスが作成されると、キューに配置され、Postgres に書き込まれます。スケジューリングは楽観的で並行して実行され、競合を避けるために中央調整が必要です。サンドボックスをワーカー (コンピュートノード) に割り当てるには、Postgres への追加の書き込みが必要です。

Kubernetes 上に構築していないため、このシステムの多くの部分をスケールアウトすることができました。例えば、スケジューリングはデフォルトで並列化されており、非常に高いバーストサンドボックス作成レートを達成できます。しかし、ノードとサンドボックスの数が増えるにつれて、O(サンドボックス) または O(ノード) でありながらスケールアウトが容易ではない操作から生じる新しいボトルネックに継続的に直面しました。

例えば、完了した各サンドボックスに対して耐久性のあるワークフローを実行するため、サンドボックスのチャーンレートが高いと大量のイベントバックログが発生します。O(サンドボックス) のレートで呼び出される RPC に繰り返し遭遇し、システム全体に予期しない負荷の問題を引き起こしました。また、多数のサンドボックスを実行するために必要なノードの数が、ノード管理とオートスケーリングにおいて複数の下流問題を引き起こしました。最後に、回避策はあったものの、シャーディングされていない Postgres インスタンスをすべてのサンドボックス作成とスケジューリングのクリティカルパスに残すことは悪いアイデアであることが証明されました。

無限のスケールを実現する

私たちはすぐに、望むスケールを達成するにはアーキテクチャをゼロから再考する必要があることに気づきました。数百万のサンドボックスを実行し、1 秒あたり数万のサンドボックスを作成するには、既存のどのソリューションよりもはるかに優れたスケーリング特性が必要です。既存のものを進化させるのではなく、最も速くてクリーンな道は新たに始めることだと信じました。

スケールを最適化するために、O(サンドボックス) または O(ノード) の負荷を伴うすべてのものはデフォルトで水平スケーラブルでなければならず、サンドボックス作成パスは可能な限りシンプルにし、その他はすべて二次的にすることを決定しました。私たちがたどり着いたソリューションは、既存のシステムとは明らかに異なります。中央調整を完全に排除し、サンドボックスの実行と作成のクリティカルパス上のあらゆる場所で、グローバルな整合性をスケーラビリティとパフォーマンスと引き換えにしました。仕組みは次のとおりです:

  • 単一の直列化されたスケジューラーの代わりに、サンドボックス作成要求を同時に処理するスケジューリングサーバーのフリートを実行します。作成要求を処理するために、スケジューリングサーバーはインメモリにキャッシュされたデータに対して高速なスケジューリングアルゴリズムを実行します。その結果、スケジューリングは水平方向にスケールし、従来のコンテナスケジューリングというよりもロードバランシングに近くなります。
  • ほとんどのコンテナプラットフォームのように、サンドボックスとワーカーの状態の真実の源として中央の永続データストアを使用する代わりに、新しいシステムの各ワーカーはそれ自身が真実の源です。ワーカーは定期的に自身の状態を Redis ストリームに公開します。スケジューリングサーバーはこの状態を非同期に消費し、スケジューリングの決定に使用します。スケジューリングサーバーがどのワーカーでサンドボックスを作成するかを決定すると、RPC 経由で直接ワーカーに連絡し、サンドボックスの作成を要求します。ワーカーは空きリソースがある場合はスケジューリング要求を受け入れ、それ以外の場合は拒否します。
  • サンドボックス作成のクリティカルパスにはデータストアが一切なく、スケーラビリティと信頼性が向上します。サンドボックスのメタデータと結果を永続ストレージに書き込む必要はありますが、そのほとんどは非同期に行います。
  • サンドボックスの作成以外に、O(サンドボックス) の RPC はありません。ワーカーは、データ指向設計のアイデアに基づいて、複数のサンドボックスの制御メッセージを単一の RPC にバッチ処理します。
Modal - inline image

最終的な設計を初めてホワイトボードに書いたときのものです。

Modal - inline image

Modal の v2 サンドボックスアーキテクチャにおけるサンドボックス作成パス。サンドボックス作成要求は水平スケールされたスケジューリングサーバーによって処理され、高速なインメモリロードバランシングアルゴリズムでワーカーを選択し、ワーカー (コンピュートノード) に直接連絡してサンドボックスを作成します。サンドボックスオブジェクトは Redis に保存されますが、クリティカルパス上にはありません。

その結果、サンドボックス作成パスには 2 回のネットワークホップと 1 回の安価な CPU 操作のみが必要です。中央ボトルネックや調整コスト、単一障害点はなく、その結果、サンドボックスの総スケールやサンドボックス作成スループットに実質的な上限はありません。必要に応じてスケジューラーやワーカーを追加できます。最も差し迫ったボトルネックは、すべてのワーカーが単一の Redis ストリームに状態を公開することですが、負荷テストでは、10 万ワーカーをはるかに超えても十分に機能することが示されています。また、ストリームの順序に依存していないため、ストリームを追加するのは簡単です。設計上、既存のソリューションがスケールできない原因となる問題を回避しています。

このソリューションの構築は簡単ではありませんでした!開発プロセス全体には数か月の作業を要し、バックエンドの主要なシステムのほとんどに及びました。ホワイトボードで何時間も過ごしました。4 人のメンバーがマイアミビーチのレンタルハウスに集まり、 distractions のない環境で新しいシステムのプロトタイプを構築しました。物理的に限界が来るまで 8 日間コードを書き、スピードチェスで回復し、海に飛び込み、そしてまたすぐにコードに戻り、新しいシステムをクリーンで機能的なものにしようと奮闘しました。

Modal - inline image

最高のエンジニアがマイアミビーチでリラックスしている様子。

コア部分が動作するようになり (そしてニューヨークに戻ってきて)、新しいシステムの上にすべてのサンドボックス機能とすべてのサンドボックス可観測性を再実装する必要もありました。このプロジェクトでは、コアのワーカーマネジメントスタックとコンテナランタイムの変更も必要でした。例えば、遭遇した興味深い問題の 1 つは、新しいサンドボックススケジューラーが あまりにも高速に コンテナをワーカーにプッシュするため、多数のコンテナが同時に起動すると、コンテナネットワーキングルールの設定時に Linux カーネルの rtnl ロックをめぐって競合し、起動に数十秒かかることがありました。そのため、サンドボックス作成が殺到してもワーカーが爆発しないように、サンドボックスのコンテナネットワーキング設定を変更する必要がありました。

パフォーマンスの比較

可能な限り高速に 100 万のサンドボックスを起動してシステムをベンチマークしました。大まかに言うと、100 万のサンドボックスを 1 分未満で作成でき、主なボトルネックはベンチマーク自体です。個々のサンドボックスのインタラクティブになるまでの時間は一貫して低く、スケールによる劣化は見られません。

Modal - inline image

サンドボックス作成要求の分布と eCDF。スケジューリングサーバーがサンドボックスをワーカーに正常に割り当て、起動が開始されると、サンドボックス作成要求が返されます。

これは設計上当然のことだと考えています。スケジューリングパスに調整がないため、スケジューリングは並行性やスケールに関係なく非常に高速であるべきです。私たちの見解では、利用可能な容量以外に、同時サンドボックススケジューリングやスケールに対する深刻な制限はなく、容量管理はすでに得意としている分野です。

Modal - inline image

100 万サンドボックステストからランダムに選択された 1 万サンドボックスの起動時間の散布図。

新しいシステムでのサンドボックス起動時間 (クライアントが最初にサンドボックスを作成しようとしてから、サンドボックスがユーザーコードを実行できるようになるまでのレイテンシ) は、中央値で 0.5 秒未満であり、スケールしても堅調です。また、旧システムよりも大幅に高速です。これは主にスケジューリングがはるかに高速になったためで、現在は数十ミリ秒しかかかりません。レイテンシのロングテールは、私たちが望むよりもやや長くなっています。このテールの多くは、同じワーカー上で多数のサンドボックスが同時に起動する際のカーネルとネットワークの競合 (前述の rtnl ロック競合を含む) によるものと考えており、削減に取り組んでいます。また、スケールにおけるテールは現実のものです。コンテナ起動パスを最適化するにつれて、これが改善されることを期待しています。

全体として、これらのパフォーマンス数値には非常に満足しています。エージェントが世界を支配するにつれて、明らかに私たちはエージェントとともにスケールできます。

実際に試してみる

まもなくこの新しいシステムが Modal のすべてのサンドボックススケジューリングを支えることになりますが、すでにベータ版で利用可能です。コードを 1 行変更するだけでオプトインできます。多数のサンドボックスを実行する必要がある場合は、ぜひお試しください。そして、ぜひご連絡ください!

謝辞

多くの人々がこのプロジェクトに血と汗と涙を注ぎました。マイアミでの POC は Colin Weld (私)、Daniel Shaar、Walter Tang、Gleb Posobin によって構築され、その後 Walter、Colin、Connor Adams、Akshay Balwally、Tom Wildenhain、Scott Hao、Taylor Baldwin によって本番化されました。

ワンクリック保存

YouMindでバイラル記事をAI深読み

ソースを保存し、的を絞った質問をし、主張を要約して、バイラル記事を再利用できるノートに変えます。すべてを1つのAIワークスペースで行えます。

YouMindを探索
クリエイターのために

あなたの Markdown をきれいな 𝕏 記事に

自分の長文を投稿するとき、画像・表・コードブロックを 𝕏 向けに整形するのは手間がかかります。YouMind は Markdown 全体を、そのまま投稿できるきれいな 𝕏 記事に変換します。

Markdown → 𝕏 を試す

解読すべきパターンをもっと

最近のバイラル記事

バイラル記事をもっと見る