一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

以秒为单位缩放至100万个并存沙盒。

时间:2026-07-18 16:59:49 编辑:袖梨 来源:一聚教程网

用户外观
用户外观

在莫达尔,我们建造沙盒等等。 智能体在沙盒里运行, 智能体正在吃软件。 如今,Modal每天运行数百万个沙箱,每个客户支持多达5万个并行沙箱,并支持各种规模的使用案例,从强化学习到背景智能体。

我们的用户越来越需要越来越多的沙盒,这些沙盒以更高和更高的速度建立。 强化学习需要同时运行数百万个沙盒,并在推出之初制造出数十万个沙盒。 同样,处理交通暴动的智能体人也日益需要大规模和高同步创建率。

我们现有的沙盒平台确实很好, 我们沉迷于规模和性能,我们希望我们的基础设施能加速智能体人的增长,而不是增加摩擦。 所以我们回到了画板。

过去几个月, 我们重建了核心沙盒平台, 在我们的新系统上,用户可以同时运行数百万个沙盒,每秒创建数万个沙盒. 我们从控制飞机上移除了所有核心瓶颈, 因此没有实际的缩放限制, 我们优化了集装箱排布和启动的每一个部分, 简化了排布路径,

我们同时运行了一百万个沙箱,

有证据表明我们可以运行很多沙盒。

为何大多数解决方案不会规模化?

运行100万个沙盒会推动任何集装箱平台的极限, 既因为集装箱数量庞大, 也因为运行这么多的沙盒需要数万个计算点。 将有许多O(容器),O(节点),或者两者兼有,会导致传统的容器平台达到缩放极限.

以库伯涅茨为例:

  • 在最坏的情况下,调度算法为n节点和ppodes的O(n x p),调度默认为序列.
  • 每个吊舱在其一生中会给等星(中央库伯内特斯耐久店)造成多个书写,这在高吊舱创建率或高吊舱churn下会造成严重的问题,而等星在密钥空间内不会在本土上被硬化.
  • 每个节点必须至少每心跳间隔向等星写一次,以信号活性,因此基线等星写负载是O(节点)完全独立于cod创建.
Kubernetes排程流程的大致描述. 新的吊舱由API服务器写入等(一个强烈一致的持久存储). Kubernetes调度器监视新的未分配的播客,并通过给API服务器的呼叫来指定它们为节点,它再次写到等;经过此写入后,一个节点就可以启动播客.

Kubernetes可以扩大,但它需要认真的工作。 要运行大量节点,等等一般必须重写或替换. . 支持高排程吞吐量,需要建立一个复杂的散射-加太系统,以并行排程算法,同时仍然维持一个单一的cock状态的真源. 硬化和平行化默认并不容易,因为Kubernetes依赖于强大的一致性作为其设计的支柱.

Modal的原始沙盒建筑也有类似的问题. 像Kubernetes一样,我们依赖整个后端的强烈一致性,所以创建和排程沙盒需要全球协调,O(sandboxes)写给Postgres,我们不能轻而易举地硬化.

莫达尔最初的沙盒控制平面建筑. 当沙盒被创建时,它们会被放置在队列上并写到Postgres. 时间安排是乐观的,并平行进行,需要中央协调以避免冲突。 将一个沙盒指定给工人(compute node)需要额外的写给Postgres.

因为我们不依靠库伯涅特, 例如,排程与默认平行,这使我们能够实现非常高的爆破沙盒创建率. 但是,当我们扩大为更多和更多的节点和沙箱时,我们不断遇到O(沙箱)或O(节点)操作产生的新的瓶颈,但这些操作既不容易扩大。

例如,我们运行一个持久的工作流程 每个沙盒完成, 所以高的沙盒churn率 将产生巨大的事件积压。 我们屡次遇到以O(沙盒)速度呼叫的RPC, 而运行大量沙盒所需的节点数量之多,在节点管理和自动缩放方面造成了多个下游问题. 最后,尽管我们可以围绕它开展工作,但将一个未磨损的Postgres案留在所有沙盒的创造和排期的关键道路上,已证明是一个坏主意。

解锁无限规模

我们很快认识到,实现我们想要的规模需要重新思考我们的架构。 我们想要运行数百万个沙盒,每秒创建数万个沙盒,这需要比任何现存的都更好的缩放特性. 我们不是试图发展我们所拥有的东西,而是认为,最快和最干净的道路是重新开始。

为了优化规模,我们决定,所有带O(sandboxes)或O(节点)负载的东西,默认必须是水平可扩展的,沙盒创建路径应该尽可能简单,其他东西都应该是次要的. 我们找到的解决办法明显不同于现有的系统。 我们完全放弃了任何类型的中央协调,并用全球一致性来换取在运行和创建沙盒的关键道路上各地的可伸缩性和性能。 以下是如何运作:

  • 而不是一个单一的,序列化的调度器, 我们运行了一组调度服务器, 它同时处理沙盒创建请求。 为了处理创建请求,调度服务器会对照内存缓存数据运行一个快速调度算法. 结果是横向排程,看起来比传统的集装箱排程更像是负载平衡.
  • 而不是一个核心的,持久的数据库 充当真理的来源 沙盒和工人状态, 这是大多数的容器平台 工作, 每一个工人 在我们的新系统 是自己的真理来源。 工人定期将其状态公布为Redis流。 调度服务器同步使用此状态并使用它来作出调度决定. 一旦一个调度服务器决定由哪个工人创建沙盒,它就会通过RPC直接与工人联系,要求创建沙盒. 如果工人有免费资源,他们就接受时间安排要求,否则就拒绝。
  • 在沙盒创造的关键道路上,我们根本没有数据储存,这提高了可扩展性和可靠性。 虽然我们确实需要写沙盒元数据和结果来进行持久的储存,但我们基本上是同步的。
  • 除了沙盒的创建,我们没有RPC是O(沙盒). 工人按照以数据为导向的设计理念精神,在单一RPC中将多个沙盒的控制信息一起批量使用.
我们最终的设计, 我们第一次白板。
莫达尔v2沙盒架构中的沙盒创建路径. Sandbox创建请求由横向缩放调度服务器处理,然后由服务器选择一个具有快速内置负载平衡算法的工人,并直接联系工人(计算节点)创建沙盒. 沙盒对象存储在Redis,但不是关键路径.

结果是沙盒创建路径只需要两个网络hop和一个廉价的CPU操作. 没有核心瓶颈或协调成本,也没有单一的故障点,因此没有实际的上限来汇集沙盒尺度或沙盒的创建吞吐量. 我们可以根据需要增加更多的排班员或工人. 最紧迫的瓶颈是所有工人都向单一的Redis溪流发布状态,但负载测试表明,这在超过10万工人之前仍然是可行的;我们也不依赖于溪流的订单,因此只要添加更多的溪流就很容易了. 从设计上讲,我们避免出现阻碍现有解决办法扩大规模的问题。

建立这个解决方案并不容易! 整个发展进程历时数月,跨越了我们后端的大多数主要系统。 我们花了几个小时在白板上。 我们四个人逃到迈阿密海滩的一间租房 建造我们想要的新系统的原型 而不会分散注意力 我们花了八天的时间写代码,直到我们身体上不能, 玩着快速棋子来恢复,跳入海洋, 然后回到代码, 争取我们的新系统清洁和功能。

我们最好的工程师在迈阿密海滩放松

一旦我们把芯片弄好(并回到纽约),我们还需要在新系统上重新执行每一个单色的Sandbox特性和所有Sandbox的可观察性。 这个项目还需要改变我们的核心工人管理堆以及集装箱运行时间。 例如,我们遇到的一个有趣的问题是,我们新的沙箱排程器可以如此迅速地将容器推向工人,以至于许多集装箱在设定容器联网规则时会同时争夺Linux内核的rtnl锁,并需要数十秒的时间才能启动,因此我们必须改变我们的沙箱集装箱联网设置,这样我们的工人就不会在沙箱制造被淹时爆炸。

我们的表演如何叠加

我们以尽可能快地 旋转100万个沙盒作为我们的系统的基准 在高水平上,我们可以在一分钟内创建100万个沙盒,其中主要的瓶颈是基准本身. 单个沙盒的时间到互动性一直很低,我们看到没有发生规模化的真正退化。

沙盒创建请求的发行和eCDF. 一个沙盒创建请求返回, 当我们的调度服务器已经成功指派一个沙盒给一个工人, 它已经开始了 。

我们认为,考虑到我们的设计,这是预料之中的。 日程安排路径没有协调,因此日程安排应当保持非常快,独立于货币和规模。 就我们而言, 我们没有严重的限制,

从我们1M的沙盒测试中,随机从1M的沙盒中选取10k的沙盒开始时间.

沙盒在我们的新系统上的起始时间(即从客户端第一次尝试创建沙盒时到沙盒可以运行用户代码时的空闲时间)在中位数时不到半秒,并且保持规模固态. 它们也大大快于我们的旧制度,主要是因为时间安排快得多——现在只需要几十毫秒。 时间的长尾巴比我们想要的长。 当许多沙盒同时从同一个工人身上开始, 另外,规模的尾巴也是真实的. 随着集装箱启动路径的优化,我们期望这种情况将得到改善。

总的来说,我们对这些业绩数字非常满意。 当特工占领世界时,我们显然可以和他们一起扩大规模。

自己看吧 自己看

这个新系统很快会回溯所有在Modal的沙盒调度, 您想要选择一个简单的代码修改 。 如果你需要运行很多的沙盒, 试一下,和我们谈谈!

鸣谢

很多人为这个项目献血,流汗,流泪. 我们的迈阿密POC由科林·韦尔德(我),丹尼尔·沙尔,沃尔特·唐(Walter Tang)和格莱布·波索宾(Gleb Posobin)建造,然后由沃尔特,科林,康纳·亚当斯,阿克沙伊·巴尔瓦利,汤姆·怀登海因,斯科特·豪(Scott Hao)和泰勒·鲍德温(Taylor Baldwin)带入生产.

热门栏目