跳转到内容
搜索文档

KV 支持的 Durable Object 存储(旧版)

最后更新 查看 MarkdownAgent 设置

Durable Object Storage API 允许 Durable Objects 访问事务性且强一致的存储。Durable Object 的附加存储对其唯一实例私有,其他对象无法访问。

Durable Object Storage API 提供多种方法,包括 SQL、时间点恢复(PITR)、键值(KV)和 alarm API。可用 API 方法取决于 Durable Objects 类的存储后端,即 SQLiteKV

方法 1 SQLite 支持的 Durable Object 类 KV 支持的 Durable Object 类
SQL API
PITR API
同步 KV API 2, 3
异步 KV API 3
Alarms API

脚注

1 每个方法都隐式包装在事务中,使其结果具有原子性,并与所有其他存储操作隔离,即使访问多个键值对也是如此。

2get()put()delete()list() 这样的 KV API 方法将数据存储在隐藏的 SQLite 表 __cf_kv 中。请注意,列出所有表时可以查看此表,但无法通过 SQL API 访问其内容。

3 SQLite 支持的 Durable Objects 还使用 ctx.storage.kv同步 KV API 方法,而 KV 支持的 Durable Objects 仅提供异步 KV API 方法

访问存储

Durable Objects 通过 DurableObjectStorage 接口访问 Storage API,并通过 DurableObjectState::storage 属性访问。通常通过传递给 Durable Object 构造函数的 ctx 参数的 this.ctx.storage 访问。

以下代码片段展示如何使用 Durable Object Storage API 存储和检索数据。

export class Counter extends DurableObject {
	constructor(ctx, env) {
		super(ctx, env);
	}

	async increment() {
		let value = (await this.ctx.storage.get("value")) || 0;
		value += 1;
		await this.ctx.storage.put("value", value);
		return value;
	}
}
export class Counter extends DurableObject {
  constructor(ctx: DurableObjectState, env: Env) {
    super(ctx, env);
  }

  async increment(): Promise<number> {
    let value: number = (await this.ctx.storage.get("value")) || 0;
    value += 1;
    await this.ctx.storage.put("value", value);
    return value;
  }
}
from workers import DurableObject

class Counter(DurableObject):
  def __init__(self, ctx, env):
    super().__init__(ctx, env)

  async def increment(self):
    value = (await self.ctx.storage.get("value")) or 0
    value += 1
    await self.ctx.storage.put("value", value)
    return value

JavaScript 是一种单线程和事件驱动的编程语言。这意味着 JavaScript 运行时默认允许请求相互交错,可能导致并发 bug。Durable Objects 运行时使用 input gateoutput gate 的组合,在执行存储操作时避免此类并发 bug。在我们的博客文章中了解更多。

异步 KV API

KV 支持的 Durable Objects 提供异步的 KV API 方法。

get

  • ctx.storage.get(key string, options Object optional): Promise<any>

    • 检索与给定键关联的值。返回值的类型将是先前为该键写入的任何类型,如果键不存在则为 undefined。
  • ctx.storage.get(keys Array<string>, options Objectoptional): Promise<Map<string, any>>

    • 检索与每个提供的键关联的值。Map 中每个返回值的类型将是先前为对应键写入的任何类型。Map 中的结果按 UTF-8 编码升序排序,任何不存在的请求键将被省略。一次最多支持 128 个键。

支持的 options

  • allowConcurrency: boolean

    • 默认情况下,系统在存储操作进行时暂停向 Object 传递 I/O 事件,以避免意外的竞态条件。传递 allowConcurrency: true 以选择退出此行为并允许传递并发事件。
  • noCache: boolean

    • 如果为 true,则键/值不会插入内存缓存。如果键已在缓存中,将返回缓存值,但其 last-used 时间不会更新。当你预期此键在近期不会再次使用时使用。此标志仅为提示。此标志永远不会改变代码的语义,但可能影响性能。

put

delete

  • delete(key string, options Objectoptional): Promise<boolean>

    • 删除键及关联值。如果键存在则返回 true,否则返回 false
  • delete(keys Array<string>, options Objectoptional): Promise<number>

    • 删除提供的键及其关联值。一次最多支持 128 个键。返回删除的键值对数量。

支持的 options

  • put()delete()deleteAll() 支持以下 options:

  • allowUnconfirmed boolean

    • 默认情况下,系统将暂停 Durable Object 的传出网络消息,直到所有先前的写入都已确认刷新到磁盘。如果写入失败,系统将重置 Object、丢弃所有传出消息,并向任何客户端返回错误。

    • 这样,Durable Objects 可以与写入操作并行继续执行,而无需担心过早确认写入,因为除非写入实际成功,否则任何外部方都无法观察 Object 的操作。

    • 任何写入后,后续网络消息可能会略有延迟。某些应用可能认为基于未确认写入进行通信是可以接受的。某些程序可能希望立即允许网络流量。在这种情况下,将 allowUnconfirmed 设置为 true 以选择退出默认行为。

    • 如果你希望某些传出网络消息立即继续但不希望其他消息继续,可以使用 allowUnconfirmed 选项避免阻塞你希望继续的消息,然后单独调用 sync() 方法,该方法返回的 promise 仅在所有先前的写入成功持久化到磁盘后才 resolve。

  • noCache boolean

    • 如果为 true,则键/值在完成写入磁盘后立即从内存中丢弃。

    • 如果键在近期不会再次使用,请使用 noCachenoCache 永远不会改变代码的语义,但可能影响性能。

    • 如果你在写入完成之前使用 get() 检索键,将返回写入缓冲区中的副本,从而确保与最新 put() 调用的一致性。

list

  • list(options Objectoptional): Promise<Map<string, any>>
    • 返回与当前 Durable Object 关联的所有键和值,按键的 UTF-8 编码升序排序。

    • Map 中每个返回值的类型将是先前为对应键写入的任何类型。

    • 在调用不带 options 的 list 版本之前,请注意 Durable Object 中可能存储的数据量,因为所有数据都将加载到 Durable Object 的内存中,可能达到其限制。如果这是顾虑,请按以下文档向 list 传递 options。

支持的 options

  • start string

    • list 结果应开始的键(含)。
  • startAfter string

    • list 结果应在其后开始的第一键(不含)。不能与 start 同时使用。
  • end string

    • list 结果应结束的键(不含)。
  • prefix string

    • 将结果限制为仅包含键以该前缀开头的键值对。
  • reverse boolean

    • 如果为 true,以降序而非默认升序返回结果。
    • 启用 reverse 不会改变 startstartKeyendKey 的含义。start 仍定义可按字典序返回的最小键(含), effectively 作为逆序 list 的端点。end 仍定义 list 应考虑的最大键(不含), effectively 作为逆序 list 的起点。
  • limit number

    • 返回的最大键值对数量。
  • allowConcurrency boolean

    • 与上述 get() 的 option 相同。
  • noCache boolean

    • 与上述 get() 的 option 相同。

Alarms

getAlarm

  • getAlarm(options Objectoptional): Promise<Number | null>
    • 获取当前 alarm 时间(如果已设置),以自 epoch 起的整数毫秒表示。如果 alarm 尚未开始,或已失败且任何重试尚未开始,则视为已设置 alarm。如果未设置 alarm,getAlarm() 返回 null

支持的选项

  • get() 相同的选项,但不包含 noCache

setAlarm

  • setAlarm(scheduledTime Date | number, options Objectoptional): Promise

    • 设置当前 alarm 时间,接受 JavaScript Date 或自 epoch 起的整数毫秒。

    如果使用等于或早于 Date.now() 的时间调用 setAlarm(),alarm 将被安排在近期异步执行。如果此时 alarm 处理程序正在执行,它不会被取消。Alarm 可精确到毫秒级,通常会在设定时间后几毫秒内执行,但由于维护或故障转移期间的故障,可能会延迟最多一分钟。

deleteAlarm

  • deleteAlarm(options Objectoptional): Promise
    • 如果存在 alarm 则删除。如果 alarm 处理程序当前正在执行,不会取消该处理程序。

支持的选项

  • setAlarm()deleteAlarm() 支持与 put() 相同的选项,但不包含 noCache

其他

deleteAll

  • deleteAll(options Objectoptional): Promise
    • 删除所有存储的数据,实际释放 Durable Object 使用的所有存储。对于键值存储后端的 Durable Objects,deleteAll() 删除单个 Durable Object 的所有键和关联值。对于 SQLite 存储后端 的 Durable Objects,deleteAll() 删除 Durable Object 私有 SQLite 数据库的全部内容,包括 SQL 数据和键值数据。
    • 对于键值存储后端的 Durable Objects,进行中的 deleteAll() 操作可能失败,可能留下部分未删除的数据。SQLite 存储后端的 Durable Objects 没有部分 deleteAll() 问题,因为 deleteAll() 操作是原子的(全有或全无)。
    • 对于兼容日期为 2026-02-24 或更晚的 Workers,deleteAll() 还会删除任何活动的 alarm。对于较早的兼容日期,deleteAll() 不会删除 alarm。请单独使用 deleteAlarm(),或启用 delete_all_deletes_alarm 兼容性标志

transactionSync

  • transactionSync(callback): any
    • 仅在使用 SQLite 支持的 Durable Objects 时可用。

    • 在事务中包装 callback() 并调用,返回其结果。

    • 如果 callback() 抛出异常,事务将回滚。

    • 回调必须同步完成,即不应声明为 async 或以其他方式返回 Promise。只有同步存储操作可以是事务的一部分。这旨在与使用 ctx.storage.sql.exec() 的 SQL 查询一起使用,这些查询同步完成。

transaction

  • transaction(closureFunction(txn)): Promise

    • 在单个事务中运行 txn 上调用的存储操作序列,该事务要么成功提交要么中止。

    • 显式事务不再必要。在没有中间 await 的情况下调用的任何一系列写入操作将自动原子提交,系统在 await 读取操作时将阻止并发事件执行(除非你使用 allowConcurrency: true)。因此,一系列读取后接一系列写入(中间没有其他 I/O)自动具有原子性,行为类似事务。

  • txn

    • 提供对上面记录的 put()get()delete()list() 方法的访问,以在当前事务上下文中运行。要在事务闭包中获得事务行为,必须在 txn Object 上调用方法,而不是在顶层 ctx.storage Object 上。

      还支持 rollback() 函数,确保事务期间所做的任何更改将被回滚而非提交。调用 rollback() 后,txn Object 上的任何后续操作都将失败并抛出异常。rollback() 不接受参数且不向调用方返回任何内容。

    • 使用 SQLite 存储引擎 时,txn 对象已过时。直接在 ctx.storage Object 上执行的任何存储操作,包括使用 ctx.storage.sql.exec() 的 SQL 查询,都将被视为事务的一部分。

sync

  • sync(): Promise
    • 将任何待处理的写入同步到磁盘。

    • 这类似于自动写入合并的正常行为。如果写入缓冲区中有任何待处理的写入(包括通过 allowUnconfirmed 选项 提交的写入),返回的 promise 将在它们完成时 resolve。如果没有待处理的写入,返回的 promise 将已 resolve。

相关资源

这篇文档对您有帮助吗?