You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NestJS Cache Manager全局TTL生效,自定义TTL不生效问题求助

问题解决:NestJS中Redis缓存自定义TTL不生效(全局TTL为0时)

问题原因

  1. cache-manager API版本变更:cache-manager v5+ 里,set方法的第三个参数不再是直接传TTL数字,必须传入包含ttl字段的配置对象。你当前直接传500的写法不符合新版本规范,导致自定义TTL未被识别。
  2. 全局TTL优先级问题:当全局TTL设为0(永不过期)时,cache-manager-redis-store会默认优先使用全局配置,忽略单个请求的自定义TTL,必须通过正确的参数格式强制覆盖。

解决方案

1. 修正set方法的参数格式

修改RedisService中的setWithTtl方法,把TTL包装成对象传入:

import { CACHE_MANAGER, Inject, Injectable } from '@nestjs/common';
import { Cache } from 'cache-manager';

@Injectable()
export class RedisService {
  constructor(@Inject(CACHE_MANAGER) private cache: Cache) {}

  async setWithTtl(
    key: string | number,
    value: any,
  ): Promise<void> {
    try {
      await this.cache.set(
        JSON.stringify(key),
        JSON.stringify(value),
        { ttl: 500 } // 改为对象格式传递TTL
      );
      return;
    } catch (err) {
      throw err;
    }
  }
}

2. 确保全局配置兼容

在CacheModule注册时,保持现有配置的同时,可添加可选配置确保自定义TTL优先级:

@Module({
  imports: [
    CacheModule.registerAsync({
      imports: [],
      useFactory: async (
        config: ConfigType<typeof configuration>,
      ): RedisClientOptions => ({
        store: redisStore,
        socket: {
          host: config.redis.host,
          port: config.redis.port,
          tls: config.redis.tls,
        },
        ttl: parseInt(config.redis.ttl, 10),
        // 可选:确保所有值都能被缓存,避免自定义TTL被拦截
        isCacheableValue: () => true,
      }),
      inject: [configuration.KEY],
    }),
  ],
  providers: [RedisService],
  exports: [RedisService],
})
export class RedisModule {}

3. 验证生效

调用setWithTtl后,用redis-cli执行TTL <你的缓存键>命令,查看返回值是否为500,确认自定义TTL已生效。

内容的提问来源于stack exchange,提问作者dibinantonyjose

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 10:33:15