← 返回信息流
AI 资讯Hacker News·3 小时前

秒级扩展至百万并发沙箱

原标题:Scaling to 1M concurrent sandboxes in seconds

速览

该技术突破使得系统可以在数秒内动态创建并管理多达100万个隔离沙箱环境,满足大规模AI模型训练、安全测试等场景的突发需求。这标志着基础设施弹性伸缩能力迈上新台阶,有望降低用户等待成本并加速开发迭代。

AI 深度解读

背景

Modal 是一家专注于构建沙箱(sandbox)基础设施的公司。沙箱被广泛用于运行 AI 代理(agent),而代理正在吞噬软件。目前,Modal 每天运行数百万个沙箱,每个客户支持高达五万个并发沙箱,并支持从强化学习到后台代理等多种大规模用例。然而,随着用户对沙箱数量和创建速率的要求越来越高——例如强化学习需要同时运行数百万个沙箱,并在 rollout 开始时创建数十万个沙箱;代理也需要应对流量突发——原有沙箱平台虽然优秀,但并非为这种规模设计,也没有任何现有解决方案能直接满足需求。Modal 认为基础设施应加速代理的增长,而非制造摩擦,因此决定从零开始重构核心沙箱平台。

核心内容

为什么大多数方案无法扩展

运行 100 万个沙箱会挑战任何容器平台的极限,不仅因为容器数量巨大,还因为需要数万个计算节点。许多操作要么是 O(容器数),要么是 O(节点数),或两者兼有,导致传统容器平台遇到扩展瓶颈。以 Kubernetes 为例:

  • 调度算法在最坏情况下是 O(n × p)(n 为节点数,p 为 Pod 数),且默认串行调度。
  • 每个 Pod 在其生命周期内会对 etcd(Kubernetes 的中央持久化存储)进行多次写入,在高 Pod 创建速率或高 Pod 变更率下会引发严重问题;etcd 在 keyspace 内无法原生分片。
  • 每个节点必须至少每隔一个心跳间隔向 etcd 写入一次以表明存活,因此基线 etcd 写入负载是 O(节点数),与 Pod 创建完全无关。

要扩展 Kubernetes 需要大量工作:运行大量节点通常需要重写或替换 etcd;支持高调度吞吐量需要构建复杂的 scatter-gather 系统以并行化调度算法,同时保持 Pod 状态的单一真实来源;分片和并行化并不容易,因为 Kubernetes 的设计依赖强一致性。

Modal 原有的沙箱架构也有类似问题。与 Kubernetes 一样,Modal 的后端依赖强一致性,因此创建和调度沙箱需要全局协调,并且对 Postgres 进行 O(沙箱数) 的写入,而 Postgres 无法轻松分片。

由于不依赖 Kubernetes,Modal 已经能够扩展系统的许多部分,例如调度默认是并行的,从而实现很高的突发沙箱创建速率。但随着节点数和沙箱数不断增加,他们不断遇到新的瓶颈,这些瓶颈来自 O(沙箱数) 或 O(节点数) 且不易扩展的操作。例如,每个沙箱完成后会运行一个持久化工作流,高沙箱变更率会导致大量事件积压;O(沙箱数) 的 RPC 调用频率会导致系统负载问题;大量节点在节点管理和自动扩缩容方面造成下游问题;在沙箱创建和调度的关键路径上保留未分片的 Postgres 实例已被证明是个坏主意。

解锁无限扩展

Modal 意识到,要达到所需的规模,必须从头重新思考架构。他们希望运行数百万个沙箱,每秒创建数万个沙箱,这需要比现有方案更好的扩展特性。他们决定重新开始,而不是试图演进现有系统。

为了优化扩展性,他们设定:所有 O(沙箱数) 或 O(节点数) 的负载必须默认能水平扩展;沙箱创建路径应尽可能简单;其他一切退居次要。最终方案与现有系统显著不同:完全摒弃任何中央协调,在运行和创建沙箱的关键路径上,用可扩展性和性能换取全局一致性。具体工作方式如下:

  • 调度不是单个串行调度器,而是一组调度服务器,并行处理沙箱创建请求。调度服务器根据内存缓存的数据运行快速调度算法,结果使调度水平扩展,更像负载均衡而非传统容器调度。
  • 大多数容器平台依赖中央持久化数据存储作为沙箱和节点状态的单一真实来源,而 Modal 新系统中每个 worker 都是自己的真实来源。Worker 定期将状态发布到 Redis 流中。调度服务器异步消费这些状态,并据此做出调度决策。一旦调度服务器决定在哪个 worker 上创建沙箱,便通过 RPC 直接联系该 worker 请求创建。Worker 在有空闲资源时接受请求,否则拒绝。
  • 沙箱创建的关键路径上完全没有数据存储,这提高了可扩展性和可靠性。沙箱元数据和结果需要持久化,但基本是异步写入。
  • 除了沙箱创建,没有其他 RPC 是 O(沙箱数) 的。Worker 将多个沙箱的控制消息批量合并到单个 RPC 中,遵循数据导向设计的思想。

结果:沙箱创建路径只需要两次网络跳转和一次廉价的 CPU 操作。没有中央瓶颈或协调成本,没有单点故障,因此沙箱规模和创建吞吐量没有实际上限。可以根据需要增加调度器或 worker。最接近的瓶颈是所有 worker 都向单个 Redis 流发布状态,但负载测试表明,在超过 10 万个 worker 之前这仍然可行;而且他们不依赖流的顺序,因此很容易增加更多流。通过设计,他们避免了现有方案在扩展时遇到的问题。

构建过程

构建这个解决方案并不容易。整个开发过程耗时数月,涉及后端大部分主要系统。团队在白板上花了数小时,四人搬到迈阿密海滩的一栋出租屋,不分心地构建新系统原型。他们连续八天写代码直到身体无法支撑,通过下快棋恢复精力、跳进海里,然后继续写代码,努力让新系统干净且功能正常。核心部分完成后(回到纽约),还需要重新实现所有……

(原文后续内容未完整给出,但主要技术要点已覆盖。)

关键要点

  • 传统容器平台(如 Kubernetes)在超大规模下存在根本性扩展瓶颈:O(n×p) 的串行调度、etcd 的写入压力、节点心跳导致的 O(节点数) 负载,以及强一致性带来的分片困难。
  • Modal 原有架构同样依赖强一致性和 Postgres 全局协调,无法支持百万级沙箱并发和每秒数万创建速率。
  • 新架构的核心设计原则:所有 O(沙箱数) 或 O(节点数) 的操作必须可水平扩展;沙箱创建路径尽可能简单;摒弃全局协调,用弱一致性换取性能和可扩展性。
  • 关键实现:
    • 调度器集群:无中央调度器,各调度服务器利用内存缓存并行调度,类似负载均衡。
    • 无中心状态存储:每个 worker 自报告状态到 Redis 流,调度器异步消费,通过 RPC 直接创建沙箱,无数据库在关键路径上。
    • 避免 O(沙箱数) 的 RPC:将多个沙箱的控制消息批量合并。
  • 性能成果:创建一个沙箱仅需两次网络跳转和一次 CPU 操作;已成功在不到一分钟内创建 100 万个并发沙箱;没有中央瓶颈,可通过增加调度器或 worker 线性扩展。
  • 困难:整个开发耗时数月,涉及后端大部分系统,团队曾集中开发八天完成原型。

意义与影响

Modal 的新沙箱平台展示了在超大规模容器化场景下,通过放弃强一致性和中央协调,可以大幅突破现有系统的扩展极限。这对 AI 代理、强化学习等需要大量并行沙箱的领域具有直接价值——用户不再受限于基础设施瓶颈,可以更快地创建和销毁沙箱,从而加速迭代。此外,该设计思路(去中心化调度、worker 自报告状态、无关键路径存储)为其他容器平台提供了借鉴:在追求极致扩展性时,可能需要重新权衡一致性与性能。Modal 明确表示不依赖 Kubernetes,而是自建底层,这暗示了在某些极端场景下,Kubernetes 的架构假设可能成为障碍,而定制化方案能实现更优的扩展特性。

查看原文 →modal.com