
GitHub 热榜上 Deno 团队的 celld 很安静地点中了一个后端痒点:Cloudflare Durable Objects 好用,但有人就是想把“按名字寻址的小对象 + 强一致单线程执行”搬回自己的机器和自己的桶里。
celld 的定位写得很干脆:self-hosted, distributed Durable Objects。每个 object 是一份自己的 SQLite;状态复制到你控制的 S3 兼容存储;节点之间只靠桶协调,没有单独的控制面,也没有一套共识服务撑场子。空闲 cell 几乎睡死,申请打过来再醒。
这不是又一个“在 K8s 上模拟 Workers”的玩具 README。它把对象存储当成真相源,节点当成可丢的执行器。这套形状,对做过有状态边缘、实时房间、按租户分片的人,会非常眼熟。
模型:一个 cell 一份库
传统做法是共享数据库加分片键。出问题的时候,慢查询、锁、连接池是整库的事。Durable Objects 的思路相反:状态跟对象走,对象名就是分片键。celld 把这点做绝——每个 cell 自带 SQLite,争用和爆炸半径在设计上被拆小,而不是靠更厚的中间件去“治理”。
运行时侧:节点内嵌 V8,跑 Wrangler 打出来的 Worker 包。舰队共享一个 S3 兼容桶,里面是部署物、cell 状态、所有权记录。对象存储上的 compare-and-swap 保证同一时间只有一个节点拥有某个 cell,不靠成员协议或故障检测器选主。
cell 迁移或唤醒时,新主人从桶恢复 SQLite 再继续跑。桶是耐用真相,节点坏了就换节点。这对运维心理是一次翻转:以前你保护的是那台有状态的机器,现在你保护的是桶的权限、版本与区域。
最小可跑通的形状
文档里的路径大致是:
curl -fsSL https://celld.dev/install.sh | sh
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
R2、MinIO 一类需要 --endpoint / --region。容器镜像在 ghcr.io/denoland/celld。多节点时每个实例 --advertise 必须是对等节点真正达得到的地址;前面挂负载均衡时尤其别抄成同一个 VIP 糊弄。
部署物写在桶里的 deploy/current.json 一类指针上,节点拉最新成功提交的版本。Worker 代码依赖 esbuild 在 PATH 里;纯静态资源项目可以例外。协议类型在仓库的 crates/celld/protocol.rs,有心对接的人直接读类型比读营销页快。
图:节点可替换,S3 兼容桶才是 cell 状态的真相源

安全边界比“能跑”更先
README 写得很硬,值得原样记在运维手册里:
- Peer HTTP 不终止 TLS。广告地址只能放在受信私网或 WireGuard/Tailscale 一类叠加网上,不要把 peer 端口裸奔公网
- 字面量公网 IP 默认拒绝,除非显式
--unsafe-public-advertise - 首个节点会在桶里建
fleet/peer-auth.json;对等请求带协议版本、HMAC、时钟窗口和防重放 - 能碰桶凭证 = 舰队管理员。桶策略、密钥轮转、访问日志,优先级高于“再加一台 node”
这和把 Postgres 暴露到 0.0.0.0 是同一类事故预告。celld 把协调做得很薄,薄的代价是:存储与网络的正确配置变成了正确性的一部分。
celld diagnose 会枚举节点租约并对存活 peer 做签名探测,排障从这里开始比先翻应用日志更有用。
适合什么,不适合什么
比较顺的场景:
- 实时协作房间、游戏房间、设备会话:按 room id / device id 建 cell
- 需要单线程串行写的计数器、锁、短工作流,又不想上强依赖云厂商 DO
- 已有 R2/S3,想把“有状态小服务”和对象存储账单绑在一起
- 本地/专有云,合规要求计算与数据都在自己账本下
需要小心的场景:
- 重跨 cell 事务:对象模型天生不爱分布式事务,业务上要能接受最终一致或显式编排
- 超大单 cell 状态:SQLite 按 cell 复制,单对象胖到不合适时要重新切名
- 把 peer 当公网 API:前面必须是你自己的入口与鉴权,celld 不是面向互联网的全家桶 PaaS
- 指望“零运维”:你仍要管桶、节点、叠加网和发布
和 Cloudflare 上的 DO 比,你换来的是可控与可迁出,付出去的是舰队与存储的操作责任。和“整库 Postgres + 自己分片”比,你换来的是更小的爆炸半径和更贴对象的一致性,付出去的是工具链与心智模型切换。
观测与发布节奏
没有中心控制面,不代表没有中心故障。桶延迟飙高时,所有权 CAS、状态恢复、部署指针读取会一起抖。监控至少要有:节点租约是否过期、单 cell 恢复耗时、deploy 指针变更审计、桶 5xx/慢请求。应用层给每个 cell 名打点,比只看机器 CPU 有用。
发布上我倾向小步:先双写或影子流量验证序列化假设,再切读。Worker 包和 cloud DO 不完全同一运行时,API 子集、CPU 限制、I/O 模型都要在预发用真实对象大小压一遍。别在演示环境用空 cell 宣布胜利。
和缓存层别混为一谈
同周 Valkey 社区还在写 AI 推理栈怎么映射到内存原语:语义缓存、KV cache offload、限流计数。那是热数据与协调。celld 是有状态执行单元。可以同时存在:入口用 Valkey 做限流与幂等键,房间真相放 cell。不要因为都是“热”就塞进同一个系统。
小结
celld 把 Durable Objects 的核心赌注开源化了:按名分片、单主执行、SQLite 为单元、S3 为真相、节点可扔。热榜意义不在于明星 star 数,而在于后端可选路径又多了一条——云 DO、自建 celld、或老老实实共享库分片,按合规和操作能力选,不按演示文稿选。
先读 celld.dev 和仓库 README,用诊断命令跑通三节点私网,再让业务 proto 贴上去。桶的 IAM 没收紧之前,不要把生产流量切过去。


