宣布 Deno KV
我们很高兴推出 Deno KV,这是一个强一致性的键值数据库,在全球 35 个区域 中进行复制,以实现低延迟读取。
Deno Deploy 旨在提供最简单、最快速的方式来部署和运行边缘的 JavaScript、TypeScript 和 Wasm。但是,以前在 Deno Deploy 上创建有状态应用程序需要连接到外部云数据库,这涉及额外的配置步骤、本地测试挑战,并且如果数据存储库没有在全球复制,可能会破坏使用边缘的好处。
随着今天的宣布,我们将一个全球集成的数据库带到 Deno,使您能够轻松开发功能齐全的应用程序,同时克服这些障碍。
在这篇文章中,我们将讨论 Deno KV 的关键方面
如果您有兴趣使用 Deno KV,请加入候补名单。
注意:Deno KV 目前处于测试阶段,长期数据持久性不能保证。在将 Deno KV 用于生产应用程序时,请牢记这一点。
在本地运行或托管
Deno KV 无缝集成到开源 Deno 运行时中,允许您在本地运行它或将其作为零配置的托管服务部署。
在本地运行时,Deno KV 由 SQLite 支持,为本地开发、测试或单区域生产系统提供轻量级且易于使用的解决方案。
当您将应用程序部署到 Deno Deploy 时,Deno KV 数据库将自动由 FoundationDB 支持。这种托管解决方案由 Deno 公司运营,确保高性能和可靠性,而无需您进行手动配置或维护。
简单但强大
Deno KV 是一个一流的原语,只公开少数几种方法,您可以使用这些方法来存储、检索、删除和枚举数据。Deno KV 专为 JavaScript 设计,可以存储任何 JavaScript 结构化可序列化值,例如对象、数组、BigInt、日期等等。
const kv = await Deno.openKv();
const key = ["users", crypto.randomUUID()];
const value = { name: "Alice", created: new Date() };
await kv.set(key, value);
const result = await kv.get(key);
console.log(result.value);
// { name: "Alice", created: 2023-05-01T09:24:07.620Z }
使用 kv.list()
操作列出与特定选择器匹配的所有键。在下面的示例中,选择了以特定前缀开头的所有键。
await kv.set(["users", "alice"], { birthday: "January 1, 1990" });
await kv.set(["users", "sam"], { birthday: "February 14, 1985" });
await kv.set(["users", "taylor"], { birthday: "December 25, 1970" });
// List out all entries with keys starting with `["users"]`
const iter = kv.list({ prefix: ["users"] });
for await (const entry of iter) {
console.log(entry.key);
console.log(entry.value);
}
列表操作以批次从存储库中检索数据,默认值为 500 个键。要实现分页,将 iter.cursor
属性传递回 kv.list()
的后续调用。
原子事务
对于许多应用程序来说,可靠的数据库事务是必需的。这在 Deno KV 中是可能的,使用 kv.atomic()
创建跨多个键的强一致性事务,默认情况下这些事务是立即持久的
const kv = await Deno.openKv();
const change = 10;
const bob = await kv.get(["balance", "bob"]);
const liz = await kv.get(["balance", "liz"]);
if (bob.value < change) {
throw "not enough balance";
}
const success = await kv.atomic()
.check(bob, liz) // balances did not change
.set(["balance", "bob"], bob.value - change)
.set(["balance", "liz"], liz.value + change)
.commit();
一致性和性能
Deno KV 是一个强一致性数据库,提供外部一致性,包括
- 可串行化:事务的最高隔离级别,确保并发事务执行的结果与这些事务的顺序执行等效。
- 线性化:保证操作(如读写)看起来是瞬时发生的并且是实时发生的。一旦写入操作完成,所有后续的读取操作都会返回更新的值,确保强实时排序。
您可以使用 consistency: "eventual"
选项为单个读取操作放宽一致性约束
// Read with eventual consistency from the nearest region
await db.get(["my-key"], { consistency: "eventual" });
// Read with strong consistency from the primary region
await db.get(["my-key"], { consistency: "strong" });
此选项允许系统从全局副本和缓存中提供读取,以实现最小的延迟。
以下是测试版在我们最受欢迎的区域的平均延迟数据。预计公开测试版和 GA 版本将有所改进。
区域 | 延迟(最终一致性) | 延迟(强一致性) |
---|---|---|
北弗吉尼亚(us-east4) | 7 毫秒 | 7 毫秒 |
法兰克福(europe-west3) | 7 毫秒 | 94 毫秒 |
荷兰(europe-west4) | 13 毫秒 | 95 毫秒 |
加利福尼亚(us-west2) | 72 毫秒 | 72 毫秒 |
香港(asia-east2) | 42 毫秒 | 194 毫秒 |
用例和示例
Deno KV 是管理应用程序状态的通用解决方案,使其非常适合各种用例。以下是一些展示 Deno KV 潜力的应用程序示例
- 实时协作:Deno KV 可以跨多个客户端存储和同步数据,从而实现对任务的无缝协作,例如文档编辑或多人游戏。对于实时应用程序,Deno 的
BroadcastChannel
通常用于帮助同步状态。 - 用户数据管理:使用 Deno KV 存储和管理用户生成的内容,例如博客文章和评论。通过使用全球复制的数据库,您可以确保快速访问,无论用户身在何处。
- 身份验证:Deno KV 可以存储用户凭据、角色和权限,从而为您的应用程序提供安全高效的身份验证。
作为一个基本示例,探索 此游乐场,看看使用 Deno KV 创建全局一致的持久计数器是多么简单
import { serve } from "/[email protected]/http/server.ts";
const db = await Deno.openKv();
serve(async (req: Request) => {
await db.atomic().sum(["views"], 1n).commit();
const res = await db.get(["views"]);
const views = res.value.value;
return new Response(`Views: ${views}`);
});
以下是一些我们构建的更高级的演示应用程序,以说明 Deno KV 的功能
- 多人井字棋 (源代码,演示):一个简单的在线多人游戏。
- Pixel-page (源代码,演示):一个协作绘图应用程序,演示了实时同步和用户数据管理。
- 共享待办事项列表 (源代码,演示):一个任务管理应用程序,说明了 Deno KV 存储和管理用户生成数据的能力。
- KV 草图本 (源代码,演示):一个基于 Web 的草图本,突出了 Deno KV 存储和检索用户创建的草图的能力,展示了用户数据管理。
这些示例提供了一窥使用 Deno KV 可以实现什么。凭借其简单性、可扩展性和全局复制,Deno KV 是开发人员想要轻松构建有状态应用程序的强大工具。
下一步
我们的目标是使 Deno Deploy 成为部署和运行 API 服务器、Web 应用程序和边缘功能的首选平台。提供全球复制的持久数据存储是朝着这一目标迈出的重要一步。在接下来的几个月里,我们将引入功能以进一步简化构建和部署应用程序的过程,只需几行代码。
在测试阶段,用户可以免费享受高达 1 GB 的存储空间。我们很快将公布定价详情。
其他资源
如果您有兴趣使用 Deno KV,请加入候补名单。
不要错过任何更新 - 在 Twitter 上关注我们。