跳至主要内容

缓存

缓存策略

对于 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 对于减少数据库负载和延迟非常有用,适用于不需要频繁更新的数据。

陈旧时重新验证 (SWR)

陈旧时重新验证 (SWR) 允许您控制 Accelerate 在后台获取新鲜数据的同时,可以服务陈旧缓存数据的持续时间。当执行读取查询时,Accelerate 会将缓存响应的年龄与 swr 持续时间进行比较。如果缓存数据在 swr 限制范围内,Accelerate 会服务陈旧数据,同时通过从数据库获取最新数据来刷新缓存。

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

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

如果指定 SWR 为 60 秒,缓存会服务陈旧数据,直到缓存每次请求后在后台自行刷新。

SWR

选择缓存策略

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

使用 TTL 的缓存策略

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

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

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

使用 SWR 的缓存策略

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

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

想象一个社交媒体平台,用户资料会被频繁访问。通过利用 swr 以及例如 5 分钟的持续时间,Accelerate 可以快速提供缓存的用户资料信息,减少资料页面的延迟。同时,它会在每次请求后在后台刷新缓存,确保对资料进行的任何更新最终会反映到后续请求中。

使用 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 分钟,并在响应新查询时使用来自数据库的最新新闻重新验证缓存。这有助于在性能和新鲜度之间取得平衡。

按需缓存失效

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

注意

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

await prisma.user.findMany({
where: {
email: {
contains: "[email protected]",
},
},
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;
}

默认缓存策略 

为了避免出现意外问题,Accelerate 默认不使用缓存。虽然缓存可以提高性能,但使用不当可能会导致错误。

例如,如果在关键路径上执行查询时未指定缓存策略,则结果可能不正确,而且没有清晰的解释。当无意中将隐式缓存保留为启用状态时,通常会发生此问题。

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

如果未指定缓存策略或发生缓存未命中,使用 Accelerate 扩展的 Prisma Client 会通过靠近数据库区域的连接池实例将所有查询路由到数据库。