我们很高兴分享 @prisma/extension-read-replicas
Prisma Client 扩展!此扩展使您能够使用 Prisma Client 将工作负载分布到数据库副本上,以应对高流量工作负载。立即试用。
什么是数据库副本,以及为什么使用它们?
数据库副本,也称为副本,是主数据库实例的副本,可以位于与主数据库相同或不同的区域。
数据库复制的主要用途之一是创建读副本。读副本可以分发应用程序的读请求,将主数据库保留用于写操作。

从服务器到读副本数据库的读操作查询流程

从服务器到主数据库的写操作查询流程以及数据同步到读副本数据库
副本可以全球分布,使数据更接近您的应用程序用户。这可以减少响应应用程序请求时的延迟。
副本的另一个重要优势是提高了数据库的弹性(resiliency)和可靠性。这可以防止您的主数据库成为单点故障。在主实例发生数据库故障、数据损坏或数据丢失的情况下,可以将副本提升为主实例。
大多数数据库提供商支持读副本。以下是一些提供读副本支持的示例提供商
将读副本与 Prisma Client 结合使用
有多种方法可以在应用程序中集成读副本。一种连接读副本的方式是设置 DNS 服务,例如 Amazon Route 53,它暴露一个单一的连接字符串。然后,DNS 服务根据传入请求的数量在副本之间平衡负载。
另一种在应用程序中集成读副本的方式是通过数据层,例如数据库驱动程序、查询构建器或对象关系映射器 (ORM)。在这种情况下,您可以向数据层提供多个连接字符串,包括主实例和副本的。然后,数据层通过将查询导向合适的副本来协调请求分发。
在 Node.js 生态系统中,Prisma 是实现应用程序数据层最流行的库之一。在 Prisma Client 中支持读副本是呼声最高的功能之一。
我们很高兴分享 @prisma/extension-read-replicas
扩展,它通过 Prisma Client 扩展实现了这一功能!
在底层,此扩展会为每个数据库副本创建并管理 Prisma Client 实例。默认情况下,该扩展会将每个读请求路由到随机配置的副本。
使用 @prisma/extension-read-replicas
连接到读副本
要利用 @prisma/extension-read-replicas
,请确保您的数据库提供商已设置读复制。完成后,您可以使用读副本配置此扩展。
在本文示例中,我们将使用 Neon 创建并连接到读副本。如果您已经设置了副本,则可以跳到使用 Prisma Client 连接您的读副本。
创建并连接到 Neon 读副本

Neon 不同于传统的 PostgreSQL 提供商,因为它将存储与计算分离。
最近,他们推出了同区域读副本功能,它利用这些计算实例(compute instances)作为读副本,可以扩展副本(扩容、缩容或缩减到零)。这意味着 Neon 在设置主数据库的读副本方面比其他提供商快得多——因为它底层使用相同的数据存储。
计算实例(compute instance)是一种服务,它为您的项目提供虚拟化的计算资源,例如 CPU、内存和存储。如果您想了解更多关于 Neon 读副本的工作原理,我们建议阅读这篇博客文章。
本文的其余部分将使用 Neon 进行读副本设置。您可以选择其他提供商进行读副本设置。
要创建读副本,请导航到 Neon 控制台并登录
- 如果您没有项目,请单击新项目按钮创建一个。
- 填写您的项目详情:项目名称、PostgreSQL 版本和区域。项目创建完成后,您将被重定向到项目控制台。
- 在项目控制台的侧边栏中选择分支。
- 选择数据库所在的分支。
- 选择添加计算。应会弹出一个创建计算端点对话框。
- 在对话框中,选择只读作为计算类型,并为您的工作负载配置计算大小。
- 配置完计算端点后,点击创建。

在 Neon 上创建读副本
接下来,检索刚刚创建的读副本的连接字符串
- 导航到您的项目控制台。
- 在连接详情下,选择要连接数据库的分支、数据库和角色。
- 在计算下拉菜单下,选择您创建的“只读”计算类型端点。
- 从代码示例中复制连接字符串。您将使用此连接字符串连接到您的读副本。

连接到 Neon 上的读副本
在您的应用程序中,为数据库副本创建一个新的环境变量,并粘贴您刚刚从 Neon 控制台复制的值
使用 @prisma/extension-read-replicas
连接到您的读副本
要在您的应用程序中开始使用读副本,请在您的项目中安装此扩展
接下来,通过扩展现有的 Prisma Client 实例并将其指向数据库副本,来初始化此扩展
如果您希望设置多个副本,可以重复上述步骤创建额外的副本。然后,在您的应用程序中更新 readReplicas
配置,如下所示
就这样!
当您运行应用程序时,该扩展会将所有读操作(例如 findMany
)发送到数据库副本。如果您定义了多个副本,将随机选择一个副本。
任何写查询(例如 create
、update
等)以及$transaction
查询都会被转发到数据库的主实例,主实例随后会将更改传播到现有的数据库副本。
如果您想从主数据库读取并绕过读副本,该扩展在您扩展的 Prisma Client 实例上提供了 $primary()
方法
此 Prisma Client 查询将始终路由到您的主数据库,以确保数据是最新的。
为什么我们将读副本支持构建为 Prisma Client 扩展?
目前将此扩展作为一个单独的包而不是 ORM 的一部分,其一个显著优势是它使我们能够独立于 ORM 版本发布来交付对扩展的改进。因此,我们可以根据需要尽可能地改进 API,以确保该扩展能够满足社区的需求。
将其作为一个单独的包/仓库发布的副作用是代码库将保持相对较小且易于管理。这将允许社区成员通过创建拉取请求来贡献并改进此扩展。
虽然Prisma Client 扩展自 Prisma 4.16.0 版本以来已普遍可用(Generally Available),但我们也利用自己构建此扩展的经验,借此机会进一步改进 Prisma Client 扩展 API。例如,在5.2.0 版本中,为了准备此扩展,我们移除了 Prisma Client 构造函数配置中的数据源名称(datasource name),以简化此扩展使用的编程方式覆盖连接字符串。我们还创建了更多 GitHub Issue,用于Client Extensions 未来的改进。如果您对其中任何改进感兴趣,请留下一个赞或评论。
亲自试用
我们鼓励您试用 @prisma/extension-read-replicas
扩展,并期待收到您的反馈!🎉
查看此示例应用程序,了解如何使用 @prisma/extension-read-replicas
扩展开始使用读副本。
也请务必试用Prisma Client 扩展,并在 Twitter 或 Discord 上与我们分享您的构建成果。🙌
不要错过下一篇文章!
订阅 Prisma 新闻通讯