行业资讯

Node.js 与 Deno 之父 Ryan Dahl 带队,重写了 Cloudflare Durable Objects|SSP Github Daily

发布时间:2026/8/25 1:24:25
Node.js 与 Deno 之父 Ryan Dahl 带队,重写了 Cloudflare Durable Objects|SSP Github Daily DAILY OPEN SOURCE · 第 124 期denoland/celldRyan Dahl 把 Cloudflare 最强原语解放了——无控制平面、无共识的自托管 Durable ObjectsNode.js 与 Deno 之父 Ryan Dahl 带队用 Rust V8 SQLite 对象存储重写了 Cloudflare Durable Objects每个对象是一个独立 SQLite 数据库节点间只靠 S3 桶里的原子写协调单主——没有控制平面、没有共识协议、没有成员服务。Cloudflare 官方反驳其成本对比但社区已经用脚投票。 GitHub Trending Rust Tokio️ SQLite per Cell S3 CAS 协调 Apache 2.0 平台提示本工具依赖境外公开数据源GitHub 仓库及 S3 / Cloudflare R2 / Google Cloud Storage / Azure Blob 等境外云存储服务部分平台在中国大陆需合规网络环境。生产部署请遵循所在地区的数据安全与合规要求。 项目速览 celld一个把Durable Objects从 Cloudflare 边缘云解放出来的开源守护进程每个 cell 是自带 SQLite 的小型服务器舰队共享一个对象存储桶桶就是唯一的持久真相源——节点随便换、桶不能丢。 Apache 2.0 今日 516 Star Rust 多 crate⚡ V8 内嵌️ 无控制平面2.2kGitHub Stars4 天破 2,60088%成本降幅$415 → $49/月v0.3.02026-08-20write-behind 日志471 KB单个驻留 cellv0.1.0 时 3.4 MB10×写延迟降低S3 操作少 100×5 万休眠 WebSocket128 MB 堆可容纳项目名celldself-hosted, distributed Durable Objects作者Deno Land Inc.Ryan Dahl 领衔Nathan Whitaker / Yusuke Tanaka / Bartek Iwańczuk 等 8 位核心贡献者许可证Apache 2.0v0.1.0 起变更⌨️技术栈RustTokio jemalloc V8 内嵌 SQLite LTX 复制格式仓库github.com/denoland/celld文档celld.dev/docs含 cloudflare-compat / limitations / security / fencing 子页存储后端S3 / Cloudflare R2 / Google Cloud Storage / Azure Blob / Tigris一句话好原语不该被一家云厂锁死——celld 让你用同一套 Workers API把状态和计算搬到自己的机器上。 它解决了什么问题分布式系统里最稀缺的东西一个全局单线程的小服务器。2020 年Cloudflare 工程师 Kenton Varda 设计出 Durable ObjectsDO每个对象有全局唯一 ID、自带一个私有 SQLite 数据库、单线程执行——同一对象的请求永不并发数据和计算在同一处。聊天室、游戏房间、协作文档、AI Agent 记忆全都变成一个可以按名字寻址的活对象。“Durable Objects is one of the best primitives distributed systems has been handed in years.”celld 官网如此评价原作——他们把 celld 称为写给 Durable Objects 的一封情书而非抄袭。但这个好原语有一个问题只能在 Cloudflare 上跑。于是就有了三重痛点痛点 ① 供应商锁定核心状态逻辑写在 Workers API 里数据落在 Cloudflare 的边缘网络中想迁移成本极高。合规要求数据必须在特定地域/自有基础设施的金融、医疗、政企业务直接被排除在外。痛点 ② 成本曲线Cloudflare 2026 年 1 月起对 Durable Objects 启用 SQLite 存储计费长期驻留的对象账单越来越难预测。Ryan Dahl 给出的估算100 个持续驻留的 cellCloudflare 上约 $415/月celld 自托管约 $49/月8GB DigitalOcean Droplet S3 兼容桶规模越大差距越大。⚖️ 争议提示Cloudflare 官方回应称 $415 只适用于对象持续活跃的场景若允许休眠同样 100 个对象只需$20.65/月。两种计费模型各有适用面——持续连接型负载选自托管突发长空闲型负载选托管更划算。痛点 ③ 自建分布式太复杂自己搭一套全局单例 持久状态通常意味着 Kafka Redis 协调服务 一堆共识协议。celld 的答案是这些全都不需要。 七大核心亮点① 无控制平面、无共识S3 桶就是协调者这是 celld 最离经叛道的设计。传统分布式系统需要成员协议、故障检测器、共识服务Raft/Paxos而 celld 的全部节点协调只通过一个共享对象存储桶完成对桶的一次**原子写compare-and-swap**即授予某节点对某 cell 的所有权——保证同一时刻只有一个 owner节点通过桶里的租约记录互相发现没有 join 命令、没有固定成员列表桶是唯一的持久真相源durable source of truth节点是可随意替换的新增节点只需把它指向同一个桶代价是桶的要求很硬必须支持条件写 读后写一致性。合格S3、R2、GCS、Azure Blob、Tigris不合格MinIO 社区版、Backblaze B2、Hetzner、DigitalOcean Spaces。② 每个对象一个 SQLite分片是设计出来的不是运维出来的官方文档的原话值得整段背诵“Because every object is its own small database, applications shard by construction — the contention and blast-radius failures of one shared database aredesigned out, not managed.”每个用户、每个文档、每个聊天室、每个 AI Agent 对应一个 cell天然隔离一个 cell 挂掉不影响其他cell 单线程执行同一 cell 的两个请求绝不并发存储操作同步且永不交错——没有锁、没有竞态cell 之间不共享数据库根本不存在共享数据库争用这个故障模式③ Cell 状态机inactive 的 cell 几乎零成本cell 有三种状态与 Cloudflare DO 完全对齐resident驻留在内存中。干活时是 active等待时是 idlehibernated休眠idle cell 被移出内存但保留可休眠的 WebSocket 客户端、留在原节点上inactive非活动没有节点持有它只是桶里的一个对象成本几乎为零v0.2.0 通过隔离区共享 jemalloc把单个驻留 cell 的内存成本从 ~3.4 MB 压到~471 KB一个 8GB 节点可驻留约 1,000 个 cell单个 resident cell 月成本约$0.05。128 MB 默认 V8 堆可挂约50,000 个休眠 WebSocket 客户端。④ v0.3.0 复制式 write-behind 日志写延迟降 10 倍8 月 20 日刚发布的 v0.3.0 带来舰队级复制创新两个以上节点时写入在 **peer fsync对等节点落盘**后即确认桶上传延后完成。官方测试数据写延迟降低10×S3 Class A 操作减少100 倍以上数据到达桶之前不确认写入RPO0——节点整个丢失也不丢已确认的写入同版还带来Azure Blob 存储az://、D1 数据库 celld d1CLI、cron 定时触发器舰队级调度、失败重试、停机补跑、流式请求体最快70×/ 文本解码最快44×的性能提升。⑤ API 级兼容 Cloudflare你的 Workers 代码不用改每个节点内嵌 V8直接执行Wrangler 打包产物celld deploy调用 PATH 上的 esbuild支持module Workers、Durable Object 绑定、静态资产含_headers/_redirects、RPCentrypoints / callbacks / RpcTarget / promise pipelining、Web Crypto、Wasm 模块、hibernatable WebSocketsV8 堆默认 128 MB——刻意对齐 Cloudflare DO 的上限理论上 Rust / C / C / Zig 编译成 Wasm 也能跑⑥ 运维友好优雅关停、滚动升级、可观测性优雅关停SIGTERM 触发排空节点把每个 resident cell 移交给 peer在途请求完成无接管空窗期滚动升级v0.2.1 → v0.3.0 支持一次重启一个节点v0.1.0 → v0.2.0 必须全停celld diagnose枚举桶中租约、直连探测每个 peer、报告驻留/休眠 cell、RSS、CPU、脱落采样CELLD_OTEL1OpenTelemetry 数据写成 Parquet 进桶用 DuckDB 直接查压力脱落默认开启内存 80%RSS 硬上限 95%⑦ 禁止 AI 提 PR社区治理的一股清流仓库明确写着“Pull requests are disabled”理由原文“Coding agents make it too easy to send a large, low-context change that costs maintainers more time than it saves.”贡献方式回归古典用git format-patch把补丁邮件发给rydeno.com附上 CLA。在 AI 生成代码泛滥的 2026 年这个决定本身就是一份技术宣言。️ 实战场景场景 1****实时协作 / 多人游戏每个房间一个 cell持有 WebSocket 连接和房间状态单线程天然免锁。玩家全部退出后 cell 休眠进桶房间数据一个字节不丢成本归零。相比API 网关 Kafka Redis Lambda的传统全家桶一个编程模型全包了。**场景 2****AI Agent 记忆层承接本栏目 Agent 基础设施线**每个 AI Agent 是一个 cell记忆、调度、收件箱全在专属 SQLite 里。空闲 Agent 休眠大型 Agent 集群在事件之间几乎零成本——这正是 Justin Schroeder 称其为年度最重要架构项目的原因有状态、可迁移的 Agent 计算正缺这么一个原语。场景 3****合规数据驻留金融 / 医疗 / 政企业务要求状态数据留在特定地域或自有机房。celld 区域性 S3 桶是干净答案代码还是 Workers API数据完全在自有基础设施里。欧盟 AI Act 数据驻留条款生效后这类需求只会更多。场景 4****成本敏感的大规模 cell 舰队已有数百个 cell、Cloudflare 月账单四位数切换到 celld 自有节点88% 的降幅是实打实的预算论证。代价是你要自己背监控、备份、升级、网络安全这套运维债——这笔人力成本也要算进总账。 上手指南Step 1 安装二进制带构建证明# 安装脚本可用 gh attestation verify 验证来源curl-fsSLhttps://celld.dev/install.sh|sh# 验证 release 资产的 GitHub Actions 构建证明gh attestation verify--repodenoland/celld# 容器方式Linux x86-64 / ARM64dockerrun--rmghcr.io/denoland/celld--versionWorker 项目部署需要esbuild 在 PATH上纯静态资产项目不需要。卸载走官方守护式卸载脚本别手删目录。Step 2 配置对象存储桶以 Cloudflare R2 为例# S3 兼容桶R2 / AWS / Tigris 均可exportAWS_ACCESS_KEY_ID...exportAWS_SECRET_ACCESS_KEY...exportAWS_REGIONautoexportS3_ENDPOINThttps://ACCOUNT_ID.r2.cloudflarestorage.comexportCELLD_BUCKETs3://YOUR-BUCKET# GCS 用 gs://走 Application Default Credentials# Azure 用 az://账号密钥 / 托管标识 / 工作负载标识三选一⚠️ 安全警告桶凭证 整个集群的完全控制权。桶里存着部署产物、SQLite 副本、所有权记录、节点租约、peer 认证密钥。凭证只授权给这一个 fleet 桶并妥善保管。Step 3 部署官方 counter 示例gitclone https://github.com/denoland/celld.gitcdcelld/examples/counter celld deploy.\--bucket$CELLD_BUCKET\--endpoint$S3_ENDPOINT\--region$AWS_REGIONcelld deploy支持 module Workers、DO 绑定、静态资产wrangler 配置里出现未知 key 会直接报错。部署对象使用crates/celld/protocol.rs中文档化的类型。Step 4 启动节点单机 / 舰队# 本地开发默认监听器即可celld--bucket$CELLD_BUCKET\--endpoint$S3_ENDPOINT\--region$AWS_REGION# 舰队节点公共/内部双监听器分离celld\--bucket$CELLD_BUCKET\--listen0.0.0.0:8080\--internal-listen10.0.0.12:8081\--advertisenode-a.internal:8081# 第二台机器指向同一桶、不同 advertise 即加入无 join 命令8080 给负载均衡器8081 留内网。peer 通信不终止 TLS——把 advertise 地址放进可信私有网络或 WireGuard / Tailscale 加密 overlay绝不暴露公网。内部监听器上还有未认证的 operator API更要锁死。Step 5 诊断与运维# 集群体检枚举租约 签名直连探测每个 peercelld diagnose--bucket$CELLD_BUCKET\--endpoint$S3_ENDPOINT--region$AWS_REGION# 健康检查 / 优雅关停curlhttp://node-a:8080/__celld/healthcurl-XPOST http://node-a:8081/shutdown# 关键环境变量# CELLD_MAX_RESIDENT_CELLS 驻留 cell 硬上限# CELLD_MAX_RSS_MB 压力脱落内存阈值默认可用内存 80%# CELLD_OTEL1 OpenTelemetry 写 Parquet 进桶# CELLD_SHUTDOWN_DRAIN_MS 排空上限须低于编排器 stop grace⚠️ 升级规则v0.1.0 → v0.2.0禁止滚动升级必须全停后启动复制格式不兼容v0.2.1 → v0.3.0 可逐节点滚动但每重启一个节点必须等diagnose报告restoring0再动下一个。 同行对照vs Cloudflare Durable Objects原作全球延迟Cloudflare 330 PoP 对 celld 的你有几台机器——需要东京法兰克福同时 sub-10ms 就留在 Cloudflare运维责任托管 vs 自担监控/备份/升级/网络定位celld 不是 Cloudflare 替代品是长大后的出口匝道——先在 Cloudflare 上用熟悉 API需要时整体搬走vs LitestreamSQLite 复制工具关系不是竞品而是生态——celld 与 Litestream v0.5.16 共享 LTX 块/帧文件格式celld 的 L0→L1 压缩用的就是 LTX v0.5.2 block formatvs Neon Functions同期方案方向相同都在做计算搬到数据旁边Neon 绑定 Postgres 生态celld 绑定 Workers/DO API SQLite per object——一个数据库侧发力一个应用运行时侧发力vs workerdCloudflare 开源运行时分工不同workerd 只管 Worker JS 执行celld 是其上的协调层——per-object SQLite 隔离、S3 持续复制、CAS 单主语义这些 workerd 都不提供 今日总结与互动celld 的意义不止于省钱 88%它把一个被验证了 6 年的分布式原语从单一云厂手里解放出来并且用对象存储 CAS 无共识证明了这件事可以做得极简。3 周 4 个版本、内存成本 7 倍压缩、写延迟 10 倍下降的迭代速度说明 Ryan Dahl 团队是认真要把它做成基础设施。选型建议小项目 / 全球低延迟刚需 / 不想运维 → 留在 Cloudflare数百 cell 的成本敏感负载 / 合规数据驻留 / AI Agent 有状态记忆层 → celld 值得认真评估。先在测试环境跑 counter 示例感受一下桶即集群的极简哲学。互动话题你的业务里有没有全局单例 持久状态的场景协作房间 / Agent 记忆 / 设备影子你现在是用什么方案撑住的——Redis 锁、消息队列还是 Durable Objects评论区聊聊下期见 每日开源 · 第 124 期 · 2026-08-24 · 项目github.com/denoland/celld