GETEX 是读操作,不创建键,仅在键存在时读取并重设过期时间,从而更新 LRU 时钟、间接影响淘汰行为,但无法替代 SET 实现初始化写入。

GETEX 本身不改变淘汰优先级,但能间接影响 LRU/LFU 行为
Redis 的淘汰策略(如 allkeys-lru、volatile-lfu)依赖于键的“最后访问时间”或“访问频次”来决定谁该被删。而 GETEX 在读取值的同时设置新过期时间,会触发一次“键访问”,从而更新该键在 LRU/LFU 淘汰池中的位置——这相当于一次隐式的“触摸续期”。它不是直接调用 TOUCH,但效果类似:让这个键在内存中“显得更活跃”。
注意:GETEX 不会修改键的底层淘汰元数据(比如 LFU 的计数器只在 GET/SET 等读写命令中递增),但它重置了 LRU 时钟,对 allkeys-lru 和 volatile-lru 类型最有效。
GETEX key EX n 和 GETEX key PX m 的实际行为差异
两者都更新过期时间并返回原值,但单位和精度不同,直接影响淘汰时机判断:
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
-
EX 30:设为 30 秒后过期,Redis 内部转为秒级时间戳存入expires字典;适用于会话、配置类缓存 -
PX 30000:设为 30000 毫秒后过期,精度更高,且避免因整数秒舍入导致多个键集中在同一秒失效(缓解“过期风暴”) - 误用
EX 30000本意是 30 秒,结果变成 30000 秒(约 8.3 小时),键长期滞留,可能挤占淘汰空间
为什么 GETEX 不能替代 SET key value EX n 做初始化设置
GETEX 是读操作,不是写操作。它的核心限制在于:
- 若
key不存在,GETEX key EX 60直接返回nil,**不会创建 key,也不会设置过期时间** - 它无法像
SET key value EX 60或SETEX key 60 value那样完成“写入+设过期”的原子初始化 - 想实现“有则续期、无则跳过”,必须配合业务逻辑判断返回值;若需“无则创建”,得改用
SET ... NX EX+ Lua 或客户端重试
高并发下 GETEX 续期的真实风险点
在热点 key 场景(如商品库存计数器、用户购物车),频繁用 GETEX cart:123 EX 1800 续期看似简单,但要注意:
- 每次调用都会触发
expireIfNeeded()检查——即使没过期,也要查expires字典,增加常量级开销 - 如果大量 key 同时被
GETEX访问,会加剧定期删除任务(默认每 100ms 抽样)的扫描压力 - 它不保证“值未被并发修改”:A 读到值 v1 并续期,B 同时用
SET覆盖为 v2,A 的续期动作对 v2 生效,但业务上可能已不适用 - 真正需要原子续期+校验的场景(如分布式锁续期),应使用
GETEX+ Lua 脚本封装,或直接上PEXPIREAT配合时间戳判断
最关键的细节往往被忽略:GETEX 的“续期”只是延长生存时间,它不感知值内容变化,也不参与任何 CAS 逻辑。把它当万能触摸指令用,容易掩盖数据一致性漏洞。

















