跳到主要内容

缓存

Prisma Postgres 支持内置查询缓存,以减少数据库负载并提高查询性能。您可以使用所有读取查询中提供的 cacheStrategy 选项来配置缓存行为。

此功能由通过 Prisma Accelerate 启用的内部缓存层提供支持,但除非您使用自己的数据库,否则无需直接与 Accelerate 交互。

缓存策略

对于 Prisma Client 中的所有读取查询,您可以定义 cacheStrategy 参数来配置缓存行为。缓存策略允许您定义缓存的两个主要特性

  • 存活时间 (TTL):缓存响应被视为新鲜的持续时间(以秒为单位)。
  • 陈旧时重新验证 (SWR):在后台刷新缓存时,可接受使用陈旧缓存响应的持续时间(以秒为单位)

存活时间 (TTL)

存活时间 (TTL) 决定了缓存数据被视为新鲜的时长。通过指定 ttl 的秒数,您可以控制缓存中数据保持有效的时间。执行读取查询时,如果缓存响应在 ttl 限制内,Prisma Client 会从缓存中检索数据,而无需查询数据库。如果缓存数据不可用或已过期,Prisma Client 会查询数据库并将结果存储到缓存中供将来请求使用。

cacheStrategy 中使用 ttl,并指定查询的 TTL(以秒为单位)

await prisma.user.findMany({
cacheStrategy: {
ttl: 60,
},
});

指定 TTL 为 60 秒时,在整个 TTL 期间,大多数请求都会命中缓存

TTL

TTL 对于减少无需频繁更新的数据的数据库负载和延迟非常有用。

使 TTL 失效并保持缓存查询结果最新

如果您的应用程序需要实时或近实时数据,缓存失效可确保用户看到最新数据,即使使用了较大的 ttl(存活时间)设置。通过使缓存失效,您可以绕过较长的缓存周期,随时显示实时数据。

例如,如果仪表板显示客户信息,并且客户的联系详情发生变化,TTL(存活时间)设置可确保缓存在设定时长后自动过期。这使得系统可以在下次访问时仅刷新更新的数据,确保支持人员始终看到最新信息,而无需手动刷新缓存。

然而,在需要立即更新且 TTL 尚未过期的情况下,缓存失效允许系统主动从缓存中清除特定数据。这会立即强制刷新更新的信息,因此支持人员始终拥有最新的详细信息,而无需等待 TTL 触发。

要使缓存查询结果失效,您可以添加标签,然后使用 $accelerate.invalidate API。

注意

按需缓存失效在我们的付费计划中提供。欲了解更多详情,请参阅我们的定价

要使以下查询失效,您需要在 $accelerate.invalidate API 中提供缓存标签

await prisma.user.findMany({
cacheStrategy: {
ttl: 60,
tags: ["findMany_users"],
},
});

// This is how you would invalidate the cached query above.
await prisma.$accelerate.invalidate({
tags: ["findMany_users"],
});

陈旧时重新验证 (SWR)

陈旧时重新验证 (SWR) 允许您控制 Prisma Postgres 在后台获取新数据时,可以提供陈旧缓存数据的时间长度。执行读取查询时,Prisma Postgres 会根据 swr 时长检查缓存响应的年龄。如果缓存数据在 swr 限制内,Prisma Postgres 会提供陈旧数据,同时通过从数据库获取最新数据来刷新缓存。

cacheStrategy 中使用 swr,并指定查询的 SWR(以秒为单位)

await prisma.user.findMany({
cacheStrategy: {
swr: 60,
},
});

指定 SWR 为 60 秒时,缓存会提供陈旧数据,直到缓存在每次请求后在后台刷新自己

SWR

使 SWR 失效并保持缓存查询结果最新

如果您的应用程序需要实时或近实时数据,缓存失效可确保用户看到最新数据,即使使用了较大的 swr(陈旧时重新验证)设置。通过使缓存失效,您可以绕过较长的缓存周期,随时显示实时数据。

例如,考虑一个显示仓库产品库存水平的仪表板。使用 SWR(陈旧时重新验证)设置,仪表板可以立即显示上次已知的库存数据,即使略有过期,同时在后台获取新数据。这确保了工作人员可以继续使用最新信息而无需等待,库存水平会在重新验证完成后立即更新。

然而,在需要立即更新库存数据的情况下——例如,如果某个产品库存不足且需要实时准确性——缓存失效允许系统主动从缓存中清除特定数据。这会立即强制刷新最新的库存数据,因此工作人员始终拥有最新的信息,而无需等待 SWR 完成重新验证。

要使缓存查询结果失效,您可以添加标签,然后使用 $accelerate.invalidate API。

注意

按需缓存失效在我们的付费计划中提供。欲了解更多详情,请参阅我们的定价

要使以下查询失效,您需要在 $accelerate.invalidate API 中提供缓存标签

await prisma.user.findMany({
cacheStrategy: {
swr: 60,
tags: ["findMany_users"],
},
});

// This is how you would invalidate the cached query above.
await prisma.$accelerate.invalidate({
tags: ["findMany_users"],
});

选择缓存策略

缓存有助于提高查询响应时间并减少数据库负载。然而,这也意味着您可能会向客户端提供陈旧数据。是否以及在多大程度上可以接受提供陈旧数据取决于您的用例。ttlswr 是您可以用来调整缓存行为的参数。

使用 TTL 的缓存策略

在可接受陈旧缓存数据时,使用 TTL 来减少数据库负载。

用例:电子商务应用中的产品目录

考虑一个产品目录不经常变化的电子商务应用。通过设置一个 ttl,例如 1 小时,Prisma Client 可以在该小时内为后续用户请求提供缓存的产品数据,而无需访问数据库。这显著减少了数据库负载并提高了产品列表页面的响应时间。

何时使失效:如果目录有重要更新,例如主要价格变动或产品可用性调整,应立即使缓存失效,以防止客户看到过时信息。

使用 SWR 的缓存策略

使用 SWR 可以快速响应请求并提供最少的陈旧数据。虽然它不会减少数据库负载,但可以显著提高响应时间。

用例:社交媒体平台中的用户个人资料

设想一个用户个人资料经常被访问的社交媒体平台。通过利用设置了 swr 的时长(例如 5 分钟),Prisma Postgres 可以快速提供缓存的用户个人资料信息,从而减少个人资料页面的延迟。同时,在后台,它会在每次请求后刷新缓存,确保对个人资料进行的任何更新最终会反映在后续请求中。

何时使失效:如果用户对其个人资料进行了重大更新,例如更改个人资料图片或个人简介,应立即使缓存失效,以确保关注者无需等待 SWR 刷新即可看到最新更新。

使用 TTL + SWR 的缓存策略

为了获得非常快的响应时间和减少数据库负载,请同时使用 TTL 和 SWR。您可以使用此策略来微调您的应用程序对陈旧数据的容忍度。

cacheStrategy 中使用 ttlswr,并指定查询的 TTL 和 SWR(以秒为单位)

await prisma.user.findMany({
cacheStrategy: {
ttl: 30,
swr: 60,
},
});

指定 TTL 为 30 秒、SWR 为 60 秒时,缓存在最初的 30 秒内提供新鲜数据。随后,它会提供陈旧数据,直到缓存在每次请求后在后台刷新自己

ttl_and_swr.png

用例:新闻文章

考虑一个新闻应用,其中的文章经常被访问但不需要实时更新。通过设置 ttl 为 2 小时和 swr 时长为 5 分钟,Prisma Client 可以快速提供缓存的文章,减少读者的延迟。只要文章在 ttl 范围内,用户就会获得快速响应。ttl 过期后,Prisma Client 会继续提供陈旧文章最多额外 5 分钟,同时响应新查询在后台用数据库中的最新新闻重新验证缓存。这有助于在性能和新鲜度之间保持平衡。

何时使失效:如果发布了重要更新或突发新闻文章,应立即使缓存失效,以确保读者立即看到最新信息。此方法对于某些新闻项目需要覆盖正常缓存周期以保证时效性的应用特别有用。

按需缓存失效

如果您的应用程序需要实时或近实时数据,缓存失效可确保用户看到最新数据,即使使用了较大的 ttl(存活时间)或 swr(陈旧时重新验证)缓存策略。通过使缓存失效,您可以绕过较长的缓存周期,随时显示实时数据。

您可以使用 $accelerate.invalidate API 使缓存失效

注意

要以编程方式使缓存查询失效,需要付费计划。更多详情请参阅我们的定价

await prisma.user.findMany({
where: {
email: {
contains: "alice@prisma.io",
},
},
cacheStrategy: {
swr: 60,
ttl: 60,
tags: ["emails_with_alice"],
},
});

您需要在 $accelerate.invalidate API 中提供缓存标签

try {
await prisma.$accelerate.invalidate({
tags: ["emails_with_alice"],
});
} catch (e) {
if (e instanceof Prisma.PrismaClientKnownRequestError) {
// The .code property can be accessed in a type-safe manner
if (e.code === "P6003") {
console.log(
"The cache invalidation rate limit has been reached. Please try again later."
);
}
}
throw e;
}

浏览演示应用,了解 Prisma Postgres 中的缓存查询结果如何按需失效,并在清晰的时间轴中展示。

默认缓存策略

Prisma Postgres 默认设置为无缓存,以避免意外问题。虽然缓存可以提高性能,但不正确的使用可能导致错误。

例如,如果在关键路径上执行查询时未指定缓存策略,结果可能不正确,且没有明确的解释。当无意中启用了隐式缓存时,经常会出现此问题。

为避免此类问题,您必须明确选择启用缓存。这可确保您知道默认情况下未启用缓存,从而防止潜在错误。

注意

未指定缓存策略或发生缓存未命中时,缓存层会将所有查询通过数据库区域附近的连接池实例路由到数据库。