ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Cloudflare Computer同步协议30分钟深入:从ChangeEntry到applyChanges全流程

Cloudflare Computer同步协议30分钟深入:从ChangeEntry到applyChanges全流程 Cloudflare Computer同步协议30分钟深入从ChangeEntry到applyChanges全流程【免费下载链接】computerGive your agent a computer 项目地址: https://gitcode.com/GitHub_Trending/computer1/computerCloudflare Computer 是一个跑在 Cloudflare Durable Object 里的虚拟文件系统它的**同步协议Sync Protocol**负责把云端 SQLite 文件树与沙箱容器里的 FUSE 挂载双向同步。这篇文章带你用 30 分钟走完全流程从一条ChangeEntry记录如何产生、如何在网络上流转到最终被applyChanges写进本地存储的每一步帮你彻底搞懂这套增量双向同步的设计。同步协议要解决什么问题Cloudflare Computer 的架构里同一个文件系统有两份副本DO 侧Durable Object基于 SQLite 的虚拟文件系统是重启后仍然存在的事实来源source of truth容器侧通过 FUSE 挂载暴露给沙箱的真实文件系统供computerd守护进程和 Agent 使用。难点在于两边都可能随时被修改——你在容器里跑npm installDO 侧也可能会收到外部写入。如果每次都全量传输文件树网络成本会爆炸。所以同步协议是增量的、双向的每侧都维护一个单调递增的修订号计数器rev双方只交换对方还没见过的那部分变化。核心构件ChangeEntry 同步记录整套协议的最小传输单元就是 ChangeEntry一条描述某个路径的最终状态的记录。它有四种形态类型携带的信息说明file路径、权限、mtime、大小、分块哈希列表文件内容不在记录里只有每块的sha256哈希dir路径、权限、mtime目录元数据symlink路径、链接目标、权限符号链接永不解引用delete路径、修订号删除操作的墓碑记录两个关键设计值得新手特别注意基于最终状态而非操作日志。协议里没有rename这类操作指令——目录改名只是把子树里每个 inode 都盖上新的修订号再为旧路径补一条墓碑。这样接收方不需要按顺序重放操作重复应用也天然幂等。字节从不内联传输。文件按固定 512 KiB 分块每块用内容寻址sha256。同一内容比如node_modules里被多处引用的库无论在几个路径出现网络上只传一次。一条ChangeEntry是怎么来的当路径被修改后materialiseChange 会读取该路径的当前状态——存活的 inode 优先于墓碑正确处理了删除后重建的场景——然后把它打包成线上记录。Push 流程DO 如何把变更推给容器每次执行命令前DO 会先做一次push把容器还没见过的变更流过去。流程分三步合并coalesce。coalesceChanges 扫描修订号区间内的所有脏路径同一路径合并成一条最新状态胜出——两次执行命令之间重写同一个文件 5 次网络上只花 1 条记录。条目按rev升序、路径升序输出为后面的断点续传铺路。哈希探测hasObjects。发送方先问接收方这些块哈希你有哪些——相当于 git 的have协商用一次集合差运算就跳过所有已有字节没有任何多余的元数据往返。补传对象pushObjects 推条目流push。只传输缺失的块然后流式发送合并后的ChangeEntry批次。接收方容器把整批变更放进单个同步事务里原子应用——半途失败就整批回滚接收方永远不会看到半截的推送。Pull 全流程fetchChanges 到 applyChanges命令执行完后方向反过来DO 把容器里 FUSE 捕获的写入拉回来。这是 pullOnce 实现的六步循环也是全文的精华步骤动作一句话解释① FetchfetchChanges({ after: 游标 })从上次停下的(rev, path)游标处按修订号排序流出ChangeEntry② 批处理缓冲最多 256 条PULL_BATCH_SIZE峰值内存被批大小封顶而不是整个流③ Diff探测本地vfs_blobsfetchObjects拉取缺失块32 字节哈希的集合差零内容重复传输④ Apply批次交给applyChanges逐条写入 SQLite见下方详解⑤ 检查点游标推进到该批最后一条的(rev, path)崩溃后从最后提交批次恢复最多重做 256 条⑥ 循环回到 ② 处理下一批直到流耗尽最后写入currentCursorapplyChanges 的三条防御线applyChanges 是变更真正落地的地方它内建了三道安全机制幂等跳过alreadyApplied。应用前逐条比对本地状态文件比 manifest 哈希目录比权限位符号链接比目标权限。已经一致的条目直接丢弃——这让重复拉取既便宜又无副作用是断点恢复能安全工作的根基。只读挂载守卫。落在只读挂载点下的条目不会被应用而是收集进skipped返回给调用方保证挂载点内容不被静默篡改。结构冲突清理。当远端发来一个文件、而本地该路径是个目录时接收方会删掉本地子树再应用远端条目——这是**最后写入者胜出last-writer-wins**的冲突处理树永远收敛但不会做内容合并。水位线Watermark崩溃恢复的秘密协议双方交换的进度表有五个水位线pushRevDO 已推到的修订号、fetchCursorDO 已拉取到的容器游标、currentRev本地最新修订号、appliedPushCursor接收方已应用到的推送游标。两个亮点(rev, path)双坐标游标。一个大的目录改名可能在单个rev内产生成百上千条记录。纯数字游标崩溃后只能重放整个 rev加入path坐标后崩溃可以在 rev 内部精确恢复而不用伪造从未整体提交的幽灵修订号。详见 watermarks.ts。跨侧不变量。每次 push 和 pull 的响应都会回声接收方的appliedPushCursor发送方断言它覆盖了自己刚推的修订号。一旦断言失败说明接收方丢过状态——协议选择大声失败而不是静默腐坏。重连场景更贴心reconcileWatermarks 在连接建立时先问对方你到哪了发现落后就把本地游标归零从 rev-0 基线全量重发——由于幂等检查重复传输几乎零成本。并发与冲突什么时候安全单个 Workspace 内所有写入被 DO 运行时串行化不存在写-写冲突两个容器共享一个 Workspace可能出现真冲突语义是同步粒度上的 last-writer-wins——最后到达 DO 的推送胜出先写的变更会被静默覆盖。这和无锁 NFS 挂载同语义。实践建议来自官方文档一个 workspace 同时只有一个活跃写者、给多 Agent 划分互不相交的子树、把共享状态放到 DO 的 RPC 面上而不是共享文件里。完整的冲突语义分析见 docs/02_sync_protocol.md。另一个对新手很实用的机制是ignore 列表默认排除node_modules否则一次npm install会把数万个小文件推进同步网络。被忽略的路径在容器内照常工作只是字节永远不上线。想继续深挖三个入口协议规范与全部设计取舍为什么不要 rename 操作码、为什么借鉴 git 的 haves/wantsdocs/02_sync_protocol.md线上记录的定义与物化逻辑packages/dofs/src/sync/changes.ts批量应用与幂等检查的完整实现packages/dofs/src/sync/apply.ts拉取/推送/水位线对账的驱动循环packages/rpc/src/sync-driver.ts文件系统表结构与 rev 递增机制docs/03_filesystem_schema.md小结Cloudflare Computer 的同步协议用四个概念解决了两份文件树如何廉价且安全地收敛——ChangeEntry状态化记录、内容寻址分块、(rev, path)断点游标、applyChanges幂等应用。它不追求合并冲突而是用幂等和最终状态保证任何崩溃、重连、重复传输下系统都能收敛到正确状态。这正是分布式文件系统简单优于聪明的经典取舍。【免费下载链接】computerGive your agent a computer 项目地址: https://gitcode.com/GitHub_Trending/computer1/computer创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表