我们为何放弃Cloudflare Durable Objects
速览
本文阐述某团队决定弃用Cloudflare Durable Objects的理由,可能涉及性能限制、成本问题或架构复杂性。这一选择反映了开发者对Serverless数据库持久化方案的实际考量,对使用Cloudflare生态的项目有参考价值。
AI 深度解读
深度解读:为什么Wire从Cloudflare Durable Objects迁移
背景
Wire 是一个为AI Agent提供上下文容器的平台:每个容器是隔离的已处理知识存储(包含条目、嵌入向量、知识图谱和溯源图谱),通过MCP(Model Context Protocol)进行查询。自产品上线以来,每个容器都运行在 Cloudflare Durable Objects 上。然而,Wire 团队决定将容器运行时从 Durable Objects 迁移到自建的数据平面。这不是一篇“离开Cloudflare”的抱怨文章——团队仍然热爱 Cloudflare,并将 API、前端、控制平面和所有处理流程保留在 Workers 上。迁移的原因是 Durable Objects 存在四个结构性限制,而非可靠性问题。
核心内容
Wire 团队从头重建了容器运行时,在相同数据(相同容器、相同问题、相同评估器)上进行了基准测试,并已将首批工作区迁移到自建的数据平面。以下是迁移背后的故事和基准测试细节。
为什么离开:四个结构性限制
-
向量索引位于对象外部
检索是容器最重要的功能,但嵌入向量存储在 Vectorize(一个独立服务)中。这意味着最热路径上存在一次网络跳转,并且状态存在第二份副本,可能发生漂移。Durable Objects 使用的 SQLite 无法加载扩展,因此向量索引永远无法内置到对象内部。 -
希望计算靠近数据
检索是一个多阶段流水线:混合候选生成、融合、查询扩展和广泛的重排序。在 Durable Objects 上,只有极小一部分计算能运行在数据所在位置;其余部分需要导出到对象周边的服务。Agent 在工具循环中调用容器,每一次网络跳转的延迟方差都会落在关键路径上。 -
放置仅在创建时确定,且计算始终共享
位置提示(Location hints)在创建时存在,但对象创建后永远不会移动。因此,从伦敦创建的容器可能永远服务于弗吉尼亚的Agent集群。此外,无法为单个租户购买专用容量。团队希望放置能跟随调用者,并且隔离性可以作为产品层级:付费工作区应获得独立的进程和机器。 -
无法自托管 Durable Objects
受监管的团队一直要求将容器运行在他们控制的基础设施上。一个只存在于 Cloudflare 上的运行时无法满足这一需求。
自建方案
- 每个组织在 Fly Machines 上获得一个宿主进程(Bun),用于运行其所有容器。
- 一个容器就是一个 SQLite 文件,通过 sqlite-vec 内嵌了向量索引,因此候选检索在进程内完成;模型调用、查询嵌入和重排序仍然走外部推理。
- 快照写入对象存储,因此容器可以在任何地方逐字节重建。
- 按区域路由将容器放置在调用者附近,控制平面通过签名请求与数据平面通信,且从不接触容器内容。
性能对比
| 指标 | 迁移前(Durable Objects) | 迁移后(自建运行时) | |------|--------------------------|----------------------| | 热工具调用延迟 | 约0.4秒,峰值超过2秒 | 约0.3秒,稳定 | | 空闲容器唤醒延迟(端到端) | 3.7秒 | 1.4秒 |
注意:3.7秒并非 Durable Objects 的冷启动时间(Cloudflare 的隔离区唤醒仅需毫秒),而是 Wire 自身堆栈重新组装所需的时间。
接口不变
容器URL、五个MCP工具、REST API和响应格式均未改变。Agent 继续调用相同的地址,迁移后的容器请求由新运行时回答。
应对持久性挑战
Durable Objects 免费提供了持久性和单写入者一致性。离开意味着需要自己实现这些保障。Cloudflare 在确认每次存储写入之前会进行复制。Wire 的初始实现仅做到“下一个检查点时的持久性”,在负载下杀死机器的浸泡测试显示:少量已确认的写入丢失。真正的解决方案是持续 WAL 日志传输:写入直到其 WAL 帧写入对象存储后才确认,组提交将此延迟控制在约100毫秒,已确认的写入不会因机器宕机而丢失。
数字的诚实解读
检索增益(recall@5 从78.1%提升到89.1%)并非全部来自架构变化——团队也切换到了更新的嵌入模型。架构的真正作用是让昂贵部分变得便宜:进程内检索允许过度获取并广泛重排序,且每个容器的索引足够小,可以进行精确的最近邻搜索。完整的对比表和评估方法在基准测试报告中。
当前状态
新运行时处于 Beta 阶段:已在预览环境及部分可选的生产工作区上线,完整生产迁移将在持久性监控指标保持绿色后推进。迁移完成后,团队计划开源容器运行时。
关键要点
- 迁移原因:四个结构性限制(向量索引外置、计算远离数据、固定放置且共享、无法自托管)促使 Wire 自建运行时。
- 核心改进:通过将向量索引嵌入 SQLite(sqlite-vec)实现进程内检索,消除网络跳转;使用 Fly Machines 提供专用宿主进程和区域路由。
- 性能提升:热调用延迟从0.4秒(峰值2秒+)降至0.3秒稳定;空闲容器唤醒从3.7秒降至1.4秒。
- 持久性方案:通过持续 WAL 日志传输到对象存储实现与 Cloudflare 等效的持久性,组提交延迟约100ms。
- 接口兼容:所有外部 API 和工具接口不变,用户无感迁移。
- 开源计划:迁移完成后开源容器运行时。
- 建议:如果不需要上述四个特性,建议继续使用 Cloudflare Durable Objects。
意义与影响
Wire 的迁移案例展示了在高度依赖平台服务(如 Cloudflare Durable Objects)时,如何识别和突破平台的结构性限制。对于AI Agent基础设施而言,检索延迟和计算位置是直接影响用户体验的关键因素。Wire 通过将向量索引嵌入 SQLite 并自行管理持久性,实现了更好的性能、隔离性和可部署性。这一做法为其他需要低延迟、可自托管的向量检索和状态管理服务的团队提供了参考。同时,Wire 表示将继续使用 Cloudflare 的其他服务(如 Workers、API 等),体现了“平台混合”策略的可行性——在合适的地方利用平台,在必要的地方自行构建。这将推动平台提供商(如 Cloudflare)思考如何提供更灵活的计算放置、专用容量和扩展支持,以满足日益复杂的AI工作负载需求。
