NestJS提供内置的缓存模块 (@nestjs/cache-manager),使用统一API跨多个存储工作 — 默认为in-memory,或使用Redis进行跨多个实例的分布式缓存。缓存通过避免重复的昂贵操作,大幅提高性能。
设置缓存模块
({
: [
.({
: ,
: ,
: ,
}),
],
})
{}
NestJS提供内置的缓存模块 (@nestjs/cache-manager),使用统一API跨多个存储工作 — 默认为in-memory,或使用Redis进行跨多个实例的分布式缓存。缓存通过避免重复的昂贵操作,大幅提高性能。
({
: [
.({
: ,
: ,
: ,
}),
],
})
{}
@Controller("products")
@UseInterceptors(CacheInterceptor) // automatically caches GET responses
export class ProductsController {
@Get()
@CacheTTL(30000) // override TTL for this route
findAll() {
return this.productsService.findAll(); // result cached; subsequent GETs are instant
}
}
CacheInterceptor自动缓存GET端点的响应(以URL为key),并在重复请求时提供缓存结果 — 缓存读操作繁重端点的最简单方法。
@Injectable()
export class ProductsService {
constructor(@Inject(CACHE_MANAGER) private cache: Cache) {}
async getProduct(id: string) {
const cached = await this.cache.get(`product:${id}`); // check cache first
if (cached) return cached; // cache HIT
const product = await this.db.findProduct(id); // cache MISS — fetch
await this.cache.set(`product:${id}`, product, 3600000); // store (1h TTL)
return product;
}
}
注入CACHE_MANAGER提供完全控制 — get-or-fetch模式(检查缓存、回退到源、存储结果)用于缓存特定的昂贵操作。
CacheModule.registerAsync({
useFactory: async () => ({
store: await redisStore({ url: process.env.REDIS_URL }), // use Redis as the store
ttl: 60000,
}),
});
同一API,由Redis支持,在所有应用实例间提供共享缓存 — 在运行多个实例时必不可少(in-memory缓存不在实例间共享)。
async updateProduct(id: string, data) {
await this.db.update(id, data);
await this.cache.del(`product:${id}`); // INVALIDATE on change → avoid stale data
}
The biggest caching challenge: INVALIDATION. When data changes, the cache must be
cleared/updated, or users see stale data. Strategies: TTL (accept brief staleness),
explicit deletion on writes (cache.del), or cache tags.
缓存是后端应用最高影响性能优化之一,NestJS的内置缓存模块使其简洁一致。
理解它很重要,因为读操作繁重的API从缓存昂贵操作(数据库查询、外部API调用、计算)中受益巨大 — 显著降低延迟和负载。
NestJS提供简单的自动缓存(用于GET端点的CacheInterceptor)和细粒度的手动控制(用于特定操作的CACHE_MANAGER get-or-fetch模式)两种方式。
至关重要的是,统一API适用于不同的存储,因此相同的代码可以使用in-memory缓存(快速、单实例)或Redis(跨多个实例的共享缓存) — 并且了解in-memory缓存在水平扩展时不共享(需要Redis进行分布式缓存)是一个重要的架构要点。
同样重要的是理解缓存的中心难点 — 失效 (当数据变化时清除或更新缓存,通过TTL或显式删除,以避免提供过时数据) — 因为处理不当是典型的缓存失败。
知道如何以及何时应用缓存、为部署选择正确的存储,以及正确处理失效是构建快速、可扩展NestJS服务的宝贵高级知识。