
celld:把 Cloudflare Durable Objects 搬回自己的服务器,Deno 官方出品
celld 是 Deno 官方开源的分布式 Durable Objects 运行时,每个对象就是一个独立的 SQLite 数据库,通过 S3 兼容桶协调节点,无需控制面和共识协议,自托管 Cloudflare Workers 生态。
原文来源:GitHub - denoland/celld — Deno 官方开源的自托管分布式 Durable Objects 运行时,每个对象是一个独立的 SQLite 数据库,节点通过 S3 兼容桶协调,无控制面、无共识协议。
8 月初,Deno 官方(denoland)开源了一个新项目 celld,短短几天在 Hacker News 上就积累了不少关注。项目定位一句话就能说清楚:把 Cloudflare 的 Workers 和 Durable Objects 跑在你自己的机器上。仓库里 278 个 star、8 个 fork,v0.1.0 版本刚刚发布,代码提交者是 Deno 创始人 Ryan Dahl(ry)。
它解决什么问题
用过 Cloudflare Durable Objects 的人都知道它的好:有状态的分布式对象、内置持久化、自动故障转移,写起来就像操作一个本地对象,不用操心分布式系统的脏活。但代价是——你得把应用绑死在 Cloudflare 平台上。数据在别人的基础设施里,出口流量要付费,平台的限额和定价随时可能变。
celld 的思路是:把 Durable Objects 的编程模型原样保留,但让数据和控制权回到你手里。每个对象就是自己的一个小 SQLite 数据库,按名字寻址,并复制到你拥有的 S3 兼容桶里。节点之间只通过这个桶协调——没有控制平面,没有共识协议。因为每个对象都是独立的小数据库,应用天然就是分片的:单个共享数据库的争用和爆炸半径问题,在设计上就被消灭了,而不是靠运维去管理。空闲的 cell(对象实例)会休眠到几乎不占资源。
—— 广告 ——
核心设计:对象存储即协调层
celld 的架构相当有 Deno 风格——极简,把复杂度推给现成的组件。
每个 celld 节点内嵌 V8 引擎,直接执行 Wrangler 打包的 Worker bundle。整个集群共享一个 S3 兼容桶,里面放着部署产物、cell 状态和小型的所有权记录。对象存储的 compare-and-swap 机制保证同一时间只有一个节点拥有某个 cell,完全不需要成员协议、故障检测器或共识服务。
节点会持续把每个 cell 的 SQLite 数据库复制到桶里。当一个 cell 迁移或唤醒时,新主人从桶里恢复数据库,然后继续执行。桶就是持久化的唯一事实来源,节点随时可以替换——机器挂了,换一台,数据从桶里拉回来继续跑。
这个设计有个很实在的好处:不需要维护 etcd、不需要选主、不需要 ZooKeeper,运维面被压缩到"一个 S3 桶 + 一堆节点"。桶的访问凭证就是整个集群的管理员凭证,安全模型很清晰。
快速上手
安装只需要一条命令,二进制产物可以通过 gh attestation verify 验证来源:
curl -fsSL https://celld.dev/install.sh | sh部署 Worker 项目到桶里,然后启动节点:
celld deploy . --bucket s3://my-cells-bucket
celld --bucket s3://my-cells-bucket \
--listen 0.0.0.0:8080 \
--advertise 10.0.0.12:8080用 Docker 跑也很直接,官方镜像同时发布 Linux x86-64 和 ARM64:
docker run --rm --network host \
-e AWS_ACCESS_KEY_ID \
-e AWS_SECRET_ACCESS_KEY \
-e AWS_SESSION_TOKEN \
-e CELLD_WATCH=/var/lib/celld/state \
-v celld-state:/var/lib/celld \
ghcr.io/denoland/celld \
--bucket s3://my-cells-bucket \
--endpoint https://ACCOUNT.r2.cloudflarestorage.com \
--region auto \
--listen 0.0.0.0:8080 \
--advertise node-a.internal:8080去掉 --endpoint/--region 就是标准的 AWS S3。有意思的是官方示例里直接用 Cloudflare R2 当桶——自己的 Workers 生态、自己的存储,还是在 Cloudflare 上,但数据主权回来了,成本结构也完全不同。
集群诊断用 celld diagnose,它会枚举所有节点租约,对每个在线节点做签名直连探测,区分过期记录、畸形地址、不可达节点和不兼容协议,还能打印每个节点的常驻 cell 数、WebSocket、RSS、CPU、文件描述符、压力和卸载样本。
资源压力管理
v0.1.0 重做了负载卸载(load shedding)机制:常驻 cell 上限现在是准入时的硬上限,压力卸载只由 RSS 和 CPU 驱动。RSS 卸载默认开启,阈值是可用内存的 80%(容器里是 cgroup 限制),可以用 CELLD_MAX_RSS_MB 固定上限,设 0 关闭。满负荷的节点会拒绝新部署而不是驱逐已有常驻 cell;一个排队部署最多触发一次驱逐。
在 Linux 上,CELLD_MAX_RSS_MB 和 CELLD_MAX_CPU_PERCENT 提供进程内存和 CPU 触发条件,常驻 cell 水位则跨平台通用。有压力时,celld 会把最久未使用的空闲 cell 持久化复制并隔离(fence),发布为无主状态但不重置其 epoch,直到水位降到低位线才重新认领新 cell。有活跃工作或活跃 WebSocket 的 cell 不会被卸载。
安全模型与注意事项
celld 对安全的态度很明确:节点间 HTTP 不终止 TLS,所有广告地址必须放在可信私有网络或 WireGuard/Tailscale 这类加密 overlay 里,不允许直接暴露对等端口——直接填公网 IP 会被拒绝,除非显式传 --unsafe-public-advertise。所有对等请求都带协议版本、body 绑定、HMAC 认证、时钟限制和重放保护,密钥来自桶里的 fleet/peer-auth.json。
贡献方式也很有意思:PR 被禁用了。维护者的理由很直白——编码 agent 太容易发大而低上下文的改动,花费维护者的时间比省下的还多。想贡献就发 git format-patch 到 ry@deno.com。这在 AI 编码时代算是个旗帜鲜明的立场。
选型建议
适合谁:想在自有基础设施上获得 Durable Objects 编程模型的团队;对数据主权敏感、不想把状态锁死在单一云平台的自托管玩家;喜欢"每个对象一个 SQLite、桶即真相"这种极简架构的人。
不适合谁:想要开箱即用托管服务的团队(这是自托管方案,运维责任在你);对 Cloudflare 平台深度绑定(R2、KV、Queues 全家桶)的应用,迁移成本不低;需要强一致性共识语义的场景——celld 明确选择了"无共识"路线。
还要注意 v0.1.0 的成熟度:运行时和兼容面仍在快速演进,公开测试目前覆盖独立引擎的冒烟路径,对 Workers/Durable Objects 参考行为的符合性测试和故障注入下的分布式协议确定性模拟,是每次发布前才跑的。生产环境大规模部署前,先把 docs/limitations.md 和 docs/security.md 读一遍。
对独立开发者来说,celld 最吸引人的点是它把"Serverless 有状态对象"的成本曲线拉回到了自托管区间——VPS 上跑几个节点,配一个便宜的 S3 兼容存储,就能获得接近 Cloudflare 的开发体验,同时把每月的固定成本从按量计费的平台账单变成一台服务器的钱。
© 2026 四月
原文链接:https://www.aprilzz.com/tools/celld-durable-objects
相关文章
Syncular:离线优先的 SQL 同步方案,客户端本地 SQLite + 服务端单一提交日志
Syncular 是一个开源的 offline-first SQL 同步框架:客户端保留真实本地 SQLite 数据库(浏览器用 OPFS、其他平台用原生 SQLite),写入走乐观 outbox,服务端一条有序提交日志作为唯一事实来源。TypeScript 和 Rust 双核心,支持 Tauri、React Native、Flutter 等绑定。
Files.md:开源、自托管的 Obsidian 替代品 — 你的生活在纯 Markdown 文件中
Files.md 是一个开源、自托管的 Markdown 笔记应用,被称为 Obsidian 的开源替代品。所有笔记就是本地文件夹中的 .md 文件,无数据库、无格式锁定、完全掌控数据。Hacker News 502 点、264 条评论,本周热度第二。
告别 GitHub,投奔 Forgejo:一位开发者的自托管迁移实录
Chris Smith 记录了他从 GitHub 迁移到自托管 Forgejo 的完整历程。不是因为宕机,而是因为谁真正拥有你的代码。