新闻详情

新闻详情

首页 / 资讯中心 / 详情

forkd 如何实现 56 毫秒 Live BRANCH:memfd + userfaultfd 写保护与写时复制原理深度剖析

发布时间:2026/10/2 12:50:56来源:尧图网络
forkd 如何实现 56 毫秒 Live BRANCH:memfd + userfaultfd 写保护与写时复制原理深度剖析
forkd 如何实现 56 毫秒 Live BRANCHmemfd userfaultfd 写保护与写时复制原理深度剖析【免费下载链接】forkd高性能Agent沙箱预热虚拟机可以在约 100 毫秒内派生出 100 个独立实例运行过程中约 150 毫秒“分叉”出一个新的运行环境。底层使用 KVM 隔离并利用快照写时复制降低资源开销。项目地址: https://gitcode.com/deeplethe/forkdforkd 是一款高性能 Agent 沙箱工具它用memfd 共享内存 userfaultfd 写保护UFFDIO_WRITEPROTECT 写时复制Copy-on-Write三件套把正在运行的虚拟机「分叉」出一个新分支的停机窗口压到了56 毫秒p50比传统 Diff 快照快 3.6 倍比全量快照快 242 倍——而且这个数字与磁盘速度无关。本文带你从「为什么慢」讲起拆解 forkd live BRANCH 的完整实现原理。一、BRANCH 到底慢在哪暂停窗口问题对运行中的沙箱做快照分叉最疼的不是「分叉出子实例要多久」而是源虚拟机被暂停的时长pause-window暂停期间源沙箱的 TCP 连接、kvmclock 全部「卡住」这是用户能直接感知的卡顿。forkd 在 1.5 GiB 的 Pythonnumpy 源沙箱、机械硬盘最差的存储条件上测得四种模式模式暂停窗口 p50说明full全量写 memory.bin13 550 ms被磁盘写速度锁死diff脏页快照202 ms脏页写入仍发生在暂停窗口内livev0.4 写保护路径56 ms内存拷贝移到恢复之后完整数据与测试方法见 bench/live-fork-pause-window/RESULTS-v0.4.md可用 bench-live-fork.py 复现。关键洞察full 和 diff 的耗时都绑死在磁盘上而 live 模式的暂停窗口只由「vmstate 转储约 30–50 ms 写保护武装约 0.4–0.6 ms」决定是与磁盘无关的 CPU 开销。存储越慢live 的优势反而越大。二、第一块拼图memfd——把客户机内存变成共享内存对象为什么不能直接对memory.bin文件做写保护这里有一个内核层面的硬约束UFFDIO_WRITEPROTECT只支持匿名anonymous和共享内存shmem类型的 VMA不支持任意文件映射。所以 forkd 在创建源沙箱时live_fork: true就提前布局用memfd_create(2)创建一个匿名文件把快照的内存字节拷进去再把/proc/pid/fd/N路径交给 Firecracker让它以MAP_SHARED映射这个 memfd 作为客户机 RAM。这个设计的完整论证在 crates/forkd-vmm/src/memfd.rs 的模块注释里memfd 是 shmem inode天然满足UFFD_WP 的 VMA 要求forkd-controller保留 memfd 句柄就能 mmap同一批物理页——客户机写什么控制器立刻看得见memfd 随 fd 关闭而消失不需要清理磁盘残留文件。memfd 创建与填充的核心逻辑见 create_and_populate还支持 2 MiB 大页后端以缓解页表压力。MemoryBackend::MemfdShared枚举与Vm::request_wp_uffd握手接口定义在 crates/forkd-vmm/src/lib.rsFC 侧需要mem_backend.shared true对应的上游提案见 FIRECRACKER-UPSTREAM-PROPOSAL.md。三、第二块拼图写保护 后台拷贝把「抄家」挪出停机窗口这是整个方案的灵魂。传统做法是「冻结 → 把整个内存写到磁盘 → 解冻」live BRANCH 变成「短暂冻结 → 给内存上写保护锁 → 解冻 → 边跑边抄」。以 crates/forkd-uffd/src/wp_snapshot.rs 中WpBranch的注释为蓝图一次 BRANCH 的时间线是暂停源 VMFirecracker 负责 pause武装写保护对源 VM 的 memfd 区域执行UFFDIO_WRITEPROTECT这就是整个 BRANCH 的临界区每 GiB 不到 1 毫秒见 WpBranch::begin在内存「对客冻结」状态下转储 vCPU 设备状态vmstate立即恢复源 VM 运行——暂停窗口到此结束共约 56 ms恢复后两路并发跑内存拷贝批量通道bulk_copy_clean逐页读走仍然干净的页见 bulk_copy_clean故障通道源 VM 一旦写某个页内核立刻向 userfaultfd 报写故障处理线程把写前的原始内容抄进快照文件再对该页解除写保护放行写入见 run_handler。这条路径有一条严格的一致性不变量快照文件里的每一页都持有「写保护武装那一刻」客户机能读到的值。也就是说分叉出来的分支拿到的是一份精确的时间点视图而源沙箱则继续向前演化互不干扰。Phase 1–3 的 PoCexperiments/v0.4-uffd-wp-poc/ 等在 64 MiB / 256 MiB / 1 GiB 区域、含 KVM 客户机经 EPT 的真实写入下验证了0 次不变量违例。跨进程细节值得一提UFFDIO_REGISTER是按进程计的而 KVM 跑在 Firecracker 里所以 uffd 由 FC 进程创建再经 SCM_RIGHTS 把 fd「快递」给控制器武装写保护——对应 begin_with_external_uffd。四、第三块拼图写时复制——N 个子实例为什么几乎不占内存分叉出的子实例从快照恢复时走的是 forkd 的老本行所有子 VM 对memory.bin做mmap(MAP_PRIVATE)干净页由内核页缓存天然共享只有被写脏的页才按子实例 CoW 复制。这里有个容易踩的坑为什么不干脆让子实例也走 UFFD 按需取页因为 UFFD 的UFFDIO_COPY是拷贝语义——N 个子实例各拿各的私有副本内核 CoW 共享直接没了等于把 forkd 最核心的密度优势换掉。这个权衡的完整推导见 docs/design/userfaultfd.md。五、56 毫秒是怎么量出来的硬件i7-12700 30 GiB 内存 机械硬盘故意用最差存储见 RESULTS-v0.4.md 的 Setup 与 Caveats源码POST /v1/sandboxes/id/branch带mode: liveCLI 为forkd snapshot --from-sandbox id --liveSDK 见 sdk/python/forkd/controller.py还有个隐藏大招waitfalse时 HTTP 请求在源 VM 恢复后就返回p5069 ms内存拷贝在后台跑完status字段从writing翻到ready时快照即可消费——调用方根本不用等那 13 秒的落盘。运行前提Linux 内核 ≥ 5.7UFFD_WP、vm.unprivileged_userfaultfd1或 root /CAP_SYS_PTRACE、带 memfd 共享补丁的 Firecrackerforkd doctor会自动探测见 crates/forkd-cli/src/doctor.rs。六、这 56 毫秒意味着什么 对 Agent 场景来说56 ms 的停机意味着「分叉」从一项昂贵的操作变成廉价到可以随手做的操作破坏性操作前自动分支——rm -rf/apt remove之前先分叉后悔即丢弃投机执行——同一状态并行尝试多种策略挑赢家对话检查点——每 N 轮自动存档第 47 轮跑偏就回到第 45 轮。相关设计文档docs/design/branching.md分支语义与暂停窗口行为、docs/design/userfaultfd.md架构演进全记录、DESIGN-v0.4.md 与 DESIGN-v0.4-PHASE6.mdv0.4 实现细节。从 v0.2 的 ~13.5 s到 v0.3.4 diff 快照的 ~200 ms再到 v0.4 live 的56 msforkd 用三个版本把「分叉」打磨成了一个几乎免费的动词。【免费下载链接】forkd高性能Agent沙箱预热虚拟机可以在约 100 毫秒内派生出 100 个独立实例运行过程中约 150 毫秒“分叉”出一个新的运行环境。底层使用 KVM 隔离并利用快照写时复制降低资源开销。项目地址: https://gitcode.com/deeplethe/forkd创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

写一篇“跳得出来、落得下去”的毕业论文:民族表演艺术同学的 AI 搭子指南 2026/10/2 13:36:36

写一篇“跳得出来、落得下去”的毕业论文:民族表演艺术同学的 AI 搭子指南

如果你读的是文化艺术大类 / 民族文化艺术类 / 民族表演艺术专业,大概率会遇到一种很典型的毕业任务:不只写论文,还要完成一场舞台作品或表演实践。 比如,以“云南楚雄彝族左脚舞从广场圈舞到校园舞台改编的实践研究”为题&#…

阅读更多 →
Java轻量级Agent工作流引擎:状态机轮转与流式输出实践 2026/10/2 13:36:30

Java轻量级Agent工作流引擎:状态机轮转与流式输出实践

把Agent的一连串步骤用if-else串起来,是我见过最劝退的写法。你可能觉得流程不复杂,无非就是“先调用大模型、判断结果、再决定下一步”,但一旦节点超过五六个,你就要维护一张隐形的状态网:下一步该走哪、失败怎么回退…

阅读更多 →
软考中级数据库系统工程师备考:大纲+第四版教材复习攻略 2026/10/2 13:36:30

软考中级数据库系统工程师备考:大纲+第四版教材复习攻略

简介:这是一份针对软考中级数据库系统工程师考试的官方考试大纲文档(对应第四版教材),适合正在备考该科目、需要明确考试范围与分值结构的考生使用。大纲完整列示了考试说明、考试要求、考试目的与考试科目,并逐章展开…

阅读更多 →
Laguna-s-2.1 118B 上 DGX Spark:MoE 与 nvfp4 实测,TaoToken 统一 Key 接入 2026/10/2 13:36:23

Laguna-s-2.1 118B 上 DGX Spark:MoE 与 nvfp4 实测,TaoToken 统一 Key 接入

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
自动标注实战:X-AnyLabeling、Grounded-SAM与autodistill高效协同指南 2026/10/2 13:36:17

自动标注实战:X-AnyLabeling、Grounded-SAM与autodistill高效协同指南

做视觉模型的人大概都经历过这种绝望:模型推理只要几毫秒,标注一箱图却要熬好几个通宵。我接手的第一个数据项目是两千张工业零件图,做实例分割标注,第一周只完成了三百多张,剩下的硬是被客户催着赶工。后来我开始研究…

阅读更多 →
LLM驱动Grep的代码搜索架构:TaoToken统一Key接入与本地验证 2026/10/2 13:36:17

LLM驱动Grep的代码搜索架构:TaoToken统一Key接入与本地验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉