跳到主要内容
Deno 2.4 发布,带来 deno bundle、字节/文本导入、OTel 稳定版等新功能
了解更多
Deno KV is in open beta

Deno KV 进入公开测试版

Deno KV 是为您的应用程序添加强一致性数据库的最快、最简单方法。它内置于运行时中,因此您可以跳过配置,直接开始编码

const kv = await Deno.openKv();
只需一行代码即可添加状态——无需配置数据库或复制/粘贴环境变量。

今天,我们很高兴地宣布,Deno Deploy 上的 Deno KV 现已进入开放 Beta 阶段。不再需要等待名单,只需注册 Deno Deploy 即可获得 Deno KV 的访问权限。对于已使用 Deno Deploy 的用户,您的项目将自动更新并获得 KV 访问权限。

您还可以观看我们总结此帖子的 2 分钟视频公告。

除了我们的公告之外,以下是关于 Deno Deploy 上的 Deno KV 的其他一些令人兴奋的更新:

从 Deno Deploy 外部连接到 KV

为了方便探索、导入、迁移和更新 Deno Deploy 上的 KV 数据,您现在可以直接从命令行连接到您的 KV 实例。只需将 Deno Deploy 个人访问令牌 设置为本地环境变量 DENO_KV_ACCESS_TOKEN,并将您的数据库 URL 传递给 Deno.openKv()

const kv = await Deno.openKv(
  "https://api.deno.com/databases/<database-id>/connect",
);

您可以在 Deno Deploy 项目页面上找到您的数据库 ID、URL 以及如何连接到您托管的 KV 数据库的更多信息。

Connecting to your Deno KV locally

现在,将数据导入生产环境、处理数据迁移、手动检查/修改/探索数据以及在不同平台上使用全局 Deno KV 进行存储将变得更加容易。

// This script updates the format of the `createdAt` field of all entries under the prefix
// `["items"]` from UNIX millisecond timestamps to ISO date strings.
import { Semaphore } from "https://deno.land/x/semaphore@v1.1.2/semaphore.ts";

const kv = await Deno.openKv(
  "https://api.deno.com/databases/<database-id>/connect",
);
const concurrencyLimit = 20;
const sem = new Semaphore(concurrencyLimit);

for await (
  const { key, value, versionstamp } of kv.list<any>({ prefix: ["items"] })
) {
  if (typeof value?.createdAt === "number") {
    value.createdAt = new Date(value.createdAt).toISOString();
    const release = await sem.acquire();
    (async () => {
      await kv.atomic().check({ key, versionstamp }).set(key, value).commit();
      release();
    })();
  }
}

for (let i = 0; i < concurrencyLimit; i++) {
  await sem.acquire();
}

console.log("Migration completed!");

了解更多关于从命令行连接到您的全局 Deno KV →

想在 Deno Deploy 上使用 Deno KV,但应用程序托管在 Fly.io 上?这里有一个使用 Deno KV 连接实现此目的的快速指南。

定价

我们很高兴地宣布透明的 Deno KV 定价,可根据您的需求进行扩展。Deno KV 的计费基于三个维度:存储、读取单位和写入单位。

存储是您在一个月内存储在 Deno KV 数据库中的数据量,以千兆字节(GiB)为单位。读取单位和写入单位是您从 Deno KV 数据库读取和写入数据的次数,分别以 4 KiB 读取单位和 1 KiB 写入单位衡量。如果您执行 3 次每次 1 KiB 的读取事务,您将被计费 3 个读取单位。如果您执行 1 次 4 KiB 的写入事务,您将被计费 4 个写入单位。

写入单位的使用量还会乘以您为数据库启用的区域数量。如果您启用了主区域和两个读取副本,则每写入 1 KiB 数据,您将被计费 3 个写入单位。

对于每个用户,Deno Deploy 的免费套餐包含 1 GiB 存储、每天 1.5 万个读取单位和每天 1 万个写入单位。每日用量在 UTC 00:00 重置。

对于使用 Deno KV 和 Deno Deploy 进行扩展的用户,我们的专业版(Pro tier)提供:

  • 每月 5 GiB 存储,每增加 1 GiB 收费 $0.75
  • 每天 4.5 万个读取单位,每增加一百万次读取收费 $1
  • 每天 3 万个写入单位,每增加一百万次写入收费 $2.5

以下是完整的定价表,供您了解更多详情:

免费版 专业版 自定义
KV 存储 1 GB 5GB (之后每 GB $0.50) 自定义
KV 读取单位/天 (4kb) 15,000 45,000 (之后每百万次 $1) 自定义
KV 写入单位/天 (1kb) 10,000 30,000 (之后每百万次 $2.50) 自定义
数据库区域数量 1 自定义 自定义
选择您的写入区域
每月最大用量 免费版 $250 不适用
您的应用程序或业务是否有独特的扩展或全球数据存储需求?我们很乐意了解更多

提醒一下,在本地使用 Deno KV 而不使用 Deno Deploy 将是免费的。

了解更多关于我们的 Deno Deploy 和 Deno KV 定价计划 →

更多读取区域以降低延迟

默认情况下,每个 Deno KV 数据库都带有一个写入区域和一个读取区域。如果您的用户遍布全球,由于单一读取区域,部分用户可能会遇到较长的延迟。

现在,您可以启用更多读取区域,以在全球范围内扩展您的数据库,从而进一步降低延迟。

Screenshot of selecting read regions

通过一键启用多个读取区域,在全球范围内扩展您的数据库。

更强大的原子操作

原子操作是 Deno KV 的一个强大功能,它允许您在单个事务中执行多个操作。如果其中任何一个操作失败,整个事务都将回滚,确保您的数据始终保持一致性。

此前,您在单个事务中最多只能执行 10 个修改操作。许多用户告诉我们,这个限制太低,特别是在处理需要大量二级索引的复杂数据时。

我们听取了您的意见!原子操作的限制已增加到每次原子操作 1000 个修改,或总原子操作大小为 800 KiB,以先达到者为准。

OAuth 变得简单

用户身份验证是任何现代网络应用程序的必备功能。为了尽可能简单地在您的 Deno Deploy 项目中实现身份验证,我们构建了 Deno KV OAuth,这是一个高级 OAuth 2.0 封装器,以 Deno KV 作为后端,并预配置了大量常见的 OAuth 2.0 提供商,如 GitHub、Google、Facebook、Slack、Discord 等。

您可以使用 新插件 为您的 Fresh 项目添加 OAuth 功能。

// main.ts
import { start } from "$fresh/server.ts";
import { createGitHubOAuth2Client } from "https://deno.land/x/deno_kv_oauth/mod.ts";
import { kvOAuthPlugin } from "https://deno.land/x/deno_kv_oauth/fresh.ts";
import manifest from "./fresh.gen.ts";

await start(manifest, {
  plugins: [
    kvOAuthPlugin(createGitHubOAuth2Client()),
  ],
});

或者,如果使用其他框架,则使用 Web API

// Sign-in, callback and sign-out handlers
import {
  createGitHubOAuth2Client,
  handleCallback,
  signIn,
  signOut,
} from "https://deno.land/x/deno_kv_oauth/mod.ts";

const oauth2Client = createGitHubOAuth2Client();

async function handleSignIn(request: Request) {
  return await signIn(request, oauth2Client);
}

async function handleOAuth2Callback(request: Request) {
  return await handleCallback(request, oauth2Client);
}

async function handleSignOut(request: Request) {
  return await signOut(request);
}
这个高级封装器提供了许多辅助函数,使您可以轻松地将身份验证、登录等功能添加到您的应用程序中。

已有项目正在使用 Deno KV OAuth 进行身份验证,例如 SaaSKitKV Sketchbook 以及 更多

即将推出

我们已收到您的反馈,并正在努力添加有用的功能,使 Deno Deploy 上的 Deno KV 成为您在全球托管项目中添加状态的最简单、最快方式。

以下是即将推出功能的部分预览列表。

expireIn 的键 TTL

键的生存时间(TTL)过期是 Redis 中的一个重要功能,它允许您轻松管理用户会话或创建自己的缓存系统。很快,您也可以在 Deno KV 中使用 expireIn 选项实现同样的功能,该选项接受一个以毫秒为单位的数字。

const db = await Deno.openKv();

await db.set(["a"], 1, { expireIn: 1000 });

expireIn 中指定的毫秒数过去后,键将从数据库中删除。如果未指定 expireIn,则键将不会过期。

请注意,此功能已在 Deno 运行时中可用

S3 备份

每个生产应用程序都需要数据备份以防万一。很快,您将能够将 Deno KV 数据备份到您自己的 S3 存储桶。

Enabling S3 backups for your Deno KV data

备份是实时进行的,支持您数据的即时恢复。最初,您将能够将备份恢复到本地 Deno KV 数据库,之后很快将支持恢复到托管的 Deno KV 数据库。

主区域选择

Deno KV 使用单个主区域处理写入,并使用多个读取区域处理读取。当发送 write 事务时,它首先在主区域处理,然后复制到所有读取区域,从而实现所有区域的最终数据一致性。因此,您的 write 延迟受用户与主区域距离的影响,而使用 consistency: "eventual" 时的 read 延迟则受用户与任何读取区域距离的影响。

很快,您将能够通过选择您的主区域来优化用户的延迟和性能。

Selecting your primary region in Deno KV

由于没有一劳永逸的配置适用于所有应用程序或业务,因此完全控制数据的存储和检索方式和位置对于优化用户性能至关重要。

主区域切换在 5 秒内生效,并且不会导致您的应用程序停机。我们将在未来几周内向 Deno Deploy 用户推出此功能。

下一步是什么?

我们对 Deno Deploy 的愿景是使其成为通过内置云原语(如 Deno KV 等,敬请期待!)托管 JavaScript 的最简单平台。在 Deno KV 和 Deno Deploy 的正式发布过程中,我们将继续添加功能,使其尽可能简单地构建和托管生产级 JavaScript 应用程序。

我们始终欢迎您的反馈和功能请求!欢迎加入我们不断壮大的 Discord 社区在此创建问题

立即将项目部署到 Deno Deploy — 只需不到 5 分钟。