如何在NestJS中使用Cache Manager配置Redis缓存自动超时失效
实现NestJS Cache Manager缓存自动过期(30秒)
问题描述
我正在开发一个提供天气API的NestJS项目,使用NestJS Cache Manager而非原生Redis驱动。目前缓存中的数据会永久存储,希望配置Redis和/或Cache Manager,使存储超过30秒的缓存数据自动失效。
当前代码实现
Cache模块(AppCacheModule)
import { Module } from '@nestjs/common'; import { CacheModule } from '@nestjs/cache-manager'; import { RedisOptions } from './config/redis.config'; @Module({ imports: [CacheModule.registerAsync(RedisOptions)] }) export class AppCacheModule {}
Redis配置(RedisOptions)
import { CacheModuleAsyncOptions } from '@nestjs/cache-manager'; import { ConfigModule, ConfigService } from '@nestjs/config'; import { redisStore } from 'cache-manager-redis-store'; export const RedisOptions: CacheModuleAsyncOptions = { isGlobal: true, imports: [ConfigModule], useFactory: async (configService: ConfigService) => { const store = await redisStore({ socket: { host: configService.get<string>('REDIS_HOST'), port: parseInt(configService.get<string>('REDIS_PORT')) } }); return { store: () => store }; }, inject: [ConfigService] };
天气服务(WeatherService)
import { CACHE_MANAGER } from '@nestjs/cache-manager'; import { Inject, Injectable } from '@nestjs/common'; import { Cache } from 'cache-manager'; import { FullWeatherData } from 'src/weather/api/types'; import { WeatherApiService } from 'src/weather/provider/weather.provider.interface'; /** * Service handling weather-related business logic. * * @class */ @Injectable() export class WeatherService { /** * Creates an instance of WeatherService. * * @constructor * @param {WeatherApiService} weatherApi - An instance of the weather API provider. * Injected based on the configured provider token. */ constructor( @Inject('WeatherApiService') private weatherApi: WeatherApiService, @Inject(CACHE_MANAGER) private cacheManager: Cache ) {} /** * Retrieves weather data by latitude and longitude. * * @public * @async * @param {number} lat - The latitude coordinate. * @param {number} lon - The longitude coordinate. * @returns {Promise<FullWeatherData>} A promise that resolves to the retrieved weather data. */ public async getWeatherData(lat: number, lon: number): Promise<FullWeatherData> { const cacheKey = this.getCacheKey(lat, lon); const cachedData = await this.cacheManager.get<FullWeatherData | undefined>( cacheKey ); if (cachedData) { return cachedData; } const data: FullWeatherData = await this.weatherApi.getWeatherData(lat, lon); this.cacheManager.set(cacheKey, data); return data; } /** * Constructs a cache key based on provided latitude and longitude. * * @param {number} lat – Latitude. * @param {number} lon – Longitude. * @returns {string} Cache key. */ private getCacheKey(lat: number, lon: number): string { return `${lat}:${lon}`; } }
解决方案
有两种方式可以实现缓存自动失效,可根据需求选择:
方式一:全局配置默认TTL(推荐)
在Redis配置中添加全局默认的过期时间(TTL,单位:秒),这样所有缓存键都会自动应用这个过期时间。
修改RedisOptions的useFactory返回值,添加ttl: 30:
import { CacheModuleAsyncOptions } from '@nestjs/cache-manager'; import { ConfigModule, ConfigService } from '@nestjs/config'; import { redisStore } from 'cache-manager-redis-store'; export const RedisOptions: CacheModuleAsyncOptions = { isGlobal: true, imports: [ConfigModule], useFactory: async (configService: ConfigService) => { const store = await redisStore({ socket: { host: configService.get<string>('REDIS_HOST'), port: parseInt(configService.get<string>('REDIS_PORT')) } }); return { store: () => store, ttl: 30 // 全局默认缓存过期时间:30秒 }; }, inject: [ConfigService] };
方式二:单个缓存键指定TTL
如果只需要特定缓存键设置过期时间,可以在调用cacheManager.set时传入TTL参数:
修改WeatherService中的getWeatherData方法,在set方法中添加ttl选项:
public async getWeatherData(lat: number, lon: number): Promise<FullWeatherData> { const cacheKey = this.getCacheKey(lat, lon); const cachedData = await this.cacheManager.get<FullWeatherData | undefined>( cacheKey ); if (cachedData) { return cachedData; } const data: FullWeatherData = await this.weatherApi.getWeatherData(lat, lon); // 设置缓存并指定30秒后过期 await this.cacheManager.set(cacheKey, data, { ttl: 30 }); return data; }
注意:这里要加上
await确保缓存设置完成,避免异步操作导致的潜在问题。
两种方式可以结合使用:全局设置默认TTL,特定缓存键可以通过传入不同的TTL值覆盖全局配置。
内容的提问来源于stack exchange,提问作者Serhii Chernikov
相关产品推荐
相关产品推荐

