打开文档导航

Prepared runtime 与 private-COW

一句话

Pysolate 的 Experimental/default-off private-COW lane 可以把一个从未服务过请求的 WASM linear-memory baseline 封存在 Linux memfd 中,再用 MAP_PRIVATE 为每个 consumer 建立私有 mapping;这样共享未修改页面,同时仍为每次执行建立和清理独立 module instance。

先看一个例子

一间机房要给每位学生提供相同的预装环境。每次从零安装依赖很慢,让所有人共用同一台正在被修改的电脑又会相互污染。

一种折中方式是保存一份只读的“刚安装完”磁盘映像。每位学生从它启动自己的实例:没修改的部分可以共享,写入后只产生自己的副本。课程结束后删除这个实例,原始映像不变。

Private-COW 对 WASM linear memory 做了类似处理。这个类比只覆盖内存页;Pysolate 没有因此获得完整 Python 解释器快照。

真实机制

普通 prepared runtime 先 instantiate module,运行 _initializeruntime_init,保存一个尚未服务请求的 preparedInstancetakePrepared 取走后 slot 立即清空,所以它是 single-use slot,不是循环 reset 的解释器池。

Linux private-COW 将复用粒度移到 linear-memory page:

  1. Host 从 canonical prepared module 读取 baseline bytes。
  2. newCOWImageWithMaximum 建立 memfd,写入 baseline,按声明的 maximum 调整大小,并加 F_SEAL_*,使 backing image 不能再写或伸缩。
  3. 每个 consumer 用 mmap(..., MAP_PRIVATE) 建立自己的读写 mapping。
  4. 未修改页面可以由内核共享;consumer 首次写某页时,内核为它创建私有 copy。
  5. Runtime 为该 mapping 重新 instantiate module,检查 memory shape,运行必要初始化,并在 serve 前用 MADV_DONTNEED 丢弃准备期间的私有脏页,重新看到 sealed baseline。
  6. 这份 instance 只服务一次 Run,随后关闭 module、temporary 和 COW lease,并 unmap 私有 memory。
compiled module + sealed immutable baseline
          ├─ MAP_PRIVATE → consumer A → private writes → close
          └─ MAP_PRIVATE → consumer B → private writes → close

两个 consumer 共享的是 sealed memfd/page-cache lineage,不是同一个可变 module。Request、response、stdout/stderr、workspace、Broker context 和 Host handles 仍按本次 Run 建立。Baseline bytes 写入 memfd 本身也涉及 copy,因此不能笼统称为 zero-copy。

当前 Prepared Family v1 在这个 substrate 上增加了一个显式 multi-consumer owner。两条 lane 复用同一份 bounded NumPy input:Linux exact-artifact private-COW lane 还共享 sealed image/page lineage;portable private-copy lane 则逐 Guest prepare。每个 member 仍建立 fresh single-use runner,不共享 Plan、Broker、Invocation 或 workspace。

MemoryCOW 依赖 PreparedRuntime,只在 Linux、单一 exported memory、声明 maximum 等受支持形状下成立。非 Linux stub 直接报告 unavailable。部分 mechanism-selection 或 semantic session 可以在承诺 capacity 前选择 ordinary fresh path;显式 capacity 和普通 Run 的 COW 初始化/clone 失败会 fail closed,不会静默伪装成一次 fresh 命中。

为什么重要

技术上: 多个 fresh consumer 可以共享 sealed linear-memory baseline,减少部分重复页面分配与 runtime_init 路径成本,同时隔离各自的 mutation。每个 consumer 仍要 instantiate 新 module,并执行必要的 _initialize。Engine 用 active lease 阻止 image 在 consumer 仍运行时被关闭。

产品和业务上: 当 Guest 初始化昂贵、并发 fan-out 较多且 Linux worker 支持时,private-COW 可能改善内存密度和启动成本。是否值得启用仍取决于 clone、page fault、初始化和 cleanup 的真实经济性。

不能推出什么

  • Private-COW 不保存 Python frame、完整 heap、module globals/tables、WASI handle、Broker state 或 native extension state。
  • 它不是 workflow continuation、checkpoint/restore 或跨平台能力。
  • MAP_PRIVATE 是既有 Linux substrate;论文主张依赖的是 Host-owned authority 与 fresh-consumer lifecycle,不把 COW 本身包装成新创新。
  • Prepared Family v1 已把 bounded NumPy input/private consumer 做成显式 opt-in API,但仍不是通用 object ABI、scheduler 或性能默认项。

术语卡

  • Prepared runtime:初始化完成但尚未服务请求的 runtime instance 或 baseline。
  • Linear memory:WASM module 使用的连续字节地址空间。
  • memfd:Linux 中由文件描述符持有的匿名内存文件。
  • MAP_PRIVATE:写入时产生私有页面、不修改 backing image 的映射方式。
  • Private-COW:多个 consumer 共享只读基线、修改时各自复制页面的机制。

继续阅读