Redis不支持按key前缀设置淘汰策略,因其maxmemory-policy是实例级全局配置,仅依据key是否过期、TTL剩余时长或访问频次等底层属性决策,完全不识别前缀语义;volatile-ttl策略配合差异化EXPIRE设置可实现前缀级“软优先级”,即让低优先级key设置更短TTL,使其在采样中更易被淘汰。

Redis 本身不支持按 key 前缀设置淘汰优先级,所有淘汰策略都是全局生效的;但你可以通过 volatile-ttl 策略 + 差异化 EXPIRE 设置,让带前缀的 key 在内存紧张时更大概率被优先淘汰。
为什么不能直接按前缀配置淘汰策略
Redis 的 maxmemory-policy 是实例级配置,对所有 database、所有 key 一视同仁。即使你用 user:123、cache:recommend、tmp:session 这样的前缀组织数据,Redis 也完全感知不到“前缀语义”。它只认 key 是否带过期时间、TTL 剩余多少、最近是否被访问等底层属性。
常见错误现象包括:以为在 redis.conf 里加个 prefix-policy user:* volatile-lru 就能生效 —— 实际上这个配置项根本不存在,Redis 启动会报错或静默忽略。
用 volatile-ttl + TTL 分级实现前缀级“软优先级”
这是目前最可行、线上验证过的间接方案。核心逻辑是:让低优先级前缀的 key 拥有明显更短的 TTL,配合 volatile-ttl 策略,在采样中更容易被选中淘汰。
- 必须启用
volatile-ttl策略:CONFIG SET maxmemory-policy volatile-ttl - 所有参与“优先级分级”的 key 必须显式设置过期时间,否则不进入候选池
- TTL 差异要足够大:比如
tmp:类设EXPIRE key 60,cache:类设EXPIRE key 1800,user:类设EXPIRE key 3600;避免只差几十秒(如 300 vs 310),实际淘汰倾向几乎无差别 - 注意
PTTL返回值边界:-2表示 key 不存在,-1表示未设过期 —— 监控脚本里误把-1当成“即将淘汰”,会导致告警误报
容易踩的坑:TTL 设置不当反而害了核心数据
很多团队上线后发现用户登录态(session:user:xxx)比临时计算结果(tmp:calc:xxx)还先被淘汰,原因往往是:
- 误给高优先级 key 设置了短 TTL,比如
EXPIRE session:user:123 300,而tmp:calc:xxx却设了 600 —— 结果volatile-ttl反而保护了临时数据 - 混用了策略:全局开了
allkeys-lru,又试图靠 TTL 控制优先级 —— 此时 TTL 完全不影响淘汰逻辑 - key 总量太少:整个实例只有 4 个带过期的 key,而采样数默认是 5,导致每次采样都覆盖全部,TTL 差异失去意义
- 忘了
maxmemory没设:Redis 默认不限内存,OOM Killer 直接干掉进程,根本轮不到淘汰策略介入
替代方案:多实例比单实例前缀隔离更可靠
如果业务维度隔离要求极高(比如金融类缓存和日志类缓存绝对不能互相影响),硬靠 TTL 分级风险太大。更稳妥的做法是:
- 为不同优先级业务部署独立 Redis 实例,各自配
maxmemory和策略 - 用代理层(如 Twemproxy、Codis 或自研路由)按 key 前缀分发到不同实例
- 避免使用
SELECT切库来模拟“多 DB 隔离”—— 因为所有 DB 共享同一内存池,淘汰仍是全局的
真正难的不是写几行 EXPIRE,而是判断哪些 key 能容忍短 TTL、哪些必须长驻、以及当采样机制遇上小数据集时,你的“优先级设计”是否还成立。


















