Durable Objects 的存储怎么用,限额是多少?
DO 存储是每个对象一份:你没法对“所有房间”写一条 SQL。
答案是:新对象用 SQLite 后端,通过 ctx.storage.sql.exec 写 SQL,或用键值接口;每个对象一份,需要跨对象聚合就放进 D1 或由外部汇总。限额以官方文档为准,Free 账户的上限官方页面自己就有矛盾。
下面分别讲两套 API、限额,以及本地和线上的差距。对象模型见 Durable Objects 为什么能让一千个请求排队改同一份状态?。
有哪些存储 API?
SQLite 后端是官方推荐的新对象默认选择,两套 API 并存:
ctx.storage.sql.exec(query, ...bindings)返回游标,可用toArray()、one()、raw()。游标应在下一个await之前消费完。- 键值接口:同步的
ctx.storage.kv,以及异步的ctx.storage.get/put/delete/list(批量最多 128 个键)。
限额是多少?
官方文档列出的几个限额:Paid 账户每个 DO 最多 10 GB;键加值合计 2 MB,SQL 单行或单个字符串 2 MB,单条语句 100 KB,绑定参数最多 100 个。单对象的软上限约为每秒 1000 个请求,超过会收到“overloaded”错误;复杂处理通常只能到几百。另外 SQLite 后端支持 30 天内的时间点恢复,本地开发不可用。
Free 账户的存储上限到底是多少?
官方页面自相矛盾:限额表写单对象 10 GB、Free 账户合计 5 GB,同一页的 FAQ 却写 Free 每个对象 1 GB。以官方为准;规划 Free 账户时保守地按“合计 5 GB、单对象别指望超过 1 GB”处理。
本地跑得通,线上就没问题吗?
不一定。本地模拟不执行这些大小限制:我在本地往 SQL 里写入 2.1 MB 的单个字符串并没有报错,别用本地结果判断自己有没有超限。而 101 个绑定参数在本地会被拒绝。
要跨对象查询怎么办?
存储是每个对象一份,所以不能对所有房间做一条 SQL 查询。需要跨对象的聚合,要么放进 D1(见 D1:迁移、事务与批处理),要么由父对象或外部系统汇总。
2.1 MB 字符串不报错、101 个绑定参数被拒绝这两点在本地 wrangler dev 上跑过。所有限额数字、时间点恢复、软上限和 Free 账户的矛盾说法来自官方文档,我没有在线上验证。限额与计费会变化,以官方文档为准。