尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Redis命令:GETEX

Redis命令:GETEX Redis GETEX 命令详细教程GETEX用于读取指定 Key 的字符串值同时可附带设置、更新或移除该 Key 的过期时间。它把读取和过期时间管理合并为一条原子命令返回值与GET一致。常用于会话续期、缓存刷新 TTL、原子地读取并延长有效期等场景避免先 GET 再 EXPIRE两步操作的竞态。本文基于 Redis String 数据类型介绍GETEX。Redis 命令本身不区分大小写因此GETEX、getex和Getex的效果相同文档统一使用大写形式。GETEX自 Redis 6.2.0 起可用。资料合集https://pan.quark.cn/s/10e98d308913、https://pan.quark.cn/s/f56bc69c5338一、命令概览1. 基本语法GETEX key [EX seconds | PX milliseconds | EXAT unix-time-seconds | PXAT unix-time-milliseconds | PERSIST]参数说明参数说明key要读取的 Key 名称EX seconds设置相对过期时间秒PX milliseconds设置相对过期时间毫秒EXAT unix-time-seconds设置绝对过期时间Unix 秒级时间戳PXAT unix-time-milliseconds设置绝对过期时间Unix 毫秒级时间戳PERSIST移除 Key 的过期时间使其永不过期返回值场景返回值Key 存在且类型为 String返回字符串值Key 不存在返回空值(nil)Key 类型不是 String返回WRONGTYPE错误过期参数是可选的不带任何选项的GETEX key行为等同于GET key仅读取不改变 TTL。2. 最简单的示例先写入一个值SET session:abc data读取并设置 60 秒过期时间GETEX session:abc EX 60返回data检查过期时间TTL session:abc返回不超过60的剩余秒数。3. 命令特性GETEX是读取 设置过期时间的原子操作。只作用于 String 类型其他类型返回WRONGTYPE错误。不带过期选项时行为等同GET只读取不改变 TTL。Key 不存在时无论是否带选项都返回空值且不会创建 Key。完整复制Full Replication时 TTL 会传播到从节点。时间复杂度为 O(1)。ACL 类别为write、string、fast。自 Redis 6.2.0 起可用更早版本无此命令。二、GETEX 的返回结果1. Key 存在且类型为 StringSET session:abc data GETEX session:abc EX 60返回data返回值与被读 Key 的值一致即使设置了过期时间返回的也是值本身。2. Key 不存在GETEX never-exists EX 60返回(nil)Key 不存在时返回空值且不会为了设置过期时间而创建该 Key。3. 不带过期选项SET key value EX 100 GETEX key TTL keyGETEX key返回valueTTL 保持不变继续递减。不带选项时等价于GET。4. Key 值为空字符串SET empty-val GETEX empty-val EX 60返回空字符串区别于空值Key 存在且值为空时返回Key 不存在返回(nil)。5. Key 类型不是 StringHSET user:1001 name Alice GETEX user:1001 EX 60返回(error) WRONGTYPE Operation against a key holding the wrong kind of value非 String 类型不会被设置过期时间。6. PERSIST 移除过期时间SET key value EX 100 GETEX key PERSIST TTL keyGETEX key PERSIST返回value并移除过期时间TTL返回-1永不过期。三、过期时间选项详解1. EX / PX相对过期GETEX key EX 3600 # 3600 秒后过期 GETEX key PX 3600000 # 3600000 毫秒后过期以当前时刻为基准向后推适用于从现在起再活多久的续期场景。2. EXAT / PXAT绝对过期GETEX key EXAT 1735689600 # 到指定 Unix 秒级时间戳过期 GETEX key PXAT 1735689600000 # 到指定 Unix 毫秒级时间戳过期以绝对时间点为过期时刻适用于统一在某个时刻全部过期的场景。3. PERSIST移除过期GETEX key PERSIST移除 Key 的 TTL使其永不自动过期。4. 四种选项不可混用GETEX一次只能指定 EX、PX、EXAT、PXAT、PERSIST 中的一种同时给出多个会返回语法错误。四、与相关命令的区别1. GETEX 与 GETGET只读取不改变 TTLGETEX可在读取的同时管理过期时间SET session:1 data EX 100 GET session:1 # 读值TTL 不变 GETEX session:1 EX 600 # 读值并把 TTL 重置为 600 秒不含选项的GETEX key与GET key等价。2. GETEX 与 SET … EX / GETSET key value EX seconds是写入并设置过期GETEX是读取并设置过期SET cache:1 new EX 60 GET # 写入新值、设置过期、返回旧值 GETEX cache:1 EX 300 # 读取现有值并刷新过期需要写入时用SET只需读取并调整过期时用GETEX。3. GETEX 与 EXPIRE / PEXPIREEXPIRE/PEXPIRE只设置过期不读取值是独立的两步GET session:1 # 先读 EXPIRE session:1 600 # 再设置过期GETEX把这两步合并为原子命令避免读取和续期之间 Key 被并发修改或删除。4. GETEX 与 GETDELGETEX读取并设置过期Key 保留GETDEL读取并删除Key 消失GETEX session:1 EX 300 # 读后仍存在TTL 刷新 GETDEL token:1 # 读后删除5. GETEX 与 PERSIST / TTLPERSIST只移除过期时间不读值GETEX key PERSIST在读取的同时移除过期。TTL/PTTL只查询剩余时间不改动。五、原子性、事务、Pipeline 与并发1. 原子性价值传统GET 后 EXPIRE是两步非原子操作GET session:1 # 读 EXPIRE session:1 600 # 续期两步之间 Key 可能被过期删除、被其他请求刷新。GETEX把读取和过期管理合并为一条原子命令续期与读取强一致。2. 在事务中使用MULTI GETEX session:1 EX 300 GET user:1:name EXECEXEC返回GETEX读到的值和后续读命令的结果。3. Pipeline 批量续期GETEX session:1 EX 300 GETEX session:2 EX 300 GETEX session:3 EX 300Pipeline 减少网络往返各命令语义与单独执行一致。4. 会话续期的并发安全多请求同时刷新同一会话时GETEX保证每个请求读到的都是当前值并原子地刷新 TTL不会出现读出旧值却把 TTL 设置到错误状态的问题。六、常见客户端用法1. redis-cliredis-cli SET session:abcdataredis-cli GETEX session:abc EX60redis-cli TTL session:abcGETEX返回dataTTL返回不超过60的值。2. Pythonredis-pyimportredis clientredis.Redis(hostlocalhost,port6379,decode_responsesTrue)client.set(session:abc,data)print(client.getex(session:abc,ex60))# dataprint(client.getex(session:abc,px60000))# data# 移除过期时间# print(client.getex(session:abc, persistTrue))redis-py 的getex(name, exNone, pxNone, exatNone, pxatNone, persistFalse)支持对应选项。检查所用版本是否支持getex。3. Node.jsnode-redisimport{createClient}fromredis;constclientcreateClient();awaitclient.connect();awaitclient.set(session:abc,data);console.log(awaitclient.getEx(session:abc,{EX:60}));// dataawaitclient.quit();node-redis 的方法是getEx驼峰过期选项以对象形式传入如{ EX: 60 }、{ PERSIST: true }。4. JavaJedisimportredis.clients.jedis.Jedis;importredis.clients.jedis.args.GetExParam;try(JedisjedisnewJedis(localhost,6379)){jedis.set(session:abc,data);System.out.println(jedis.getEx(session:abc,GetExParam.EX,60));// data}Jedis 通过GetExParam.EX/PX/EXAT/PXAT/PERSIST指定过期选项。七、典型业务场景1. 会话续期滑动过期GETEX session:4f8a9c EX 1800用户每次活跃时读取会话并顺带把 TTL 滑动到 30 分钟后天然实现最后活跃起算的过期策略。2. 缓存的惰性刷新 TTLGETEX cache:user:1001 EX 600命中缓存的同时延长有效期让热点数据持续存活、冷数据自然过期。3. 验证码/临时凭证续期GETEX code:user:1001 EX 300读取验证码时延长其有效窗口配合限制读取次数使用。4. 原子转永久GETEX temp-key PERSIST读取某个临时 Key 并一次性移除过期让它在被首次读取后转为永久保存。5. 统一到期时间GETEX daily:counter EXAT 1735689600读取时把过期时间收敛到某个绝对时刻实现当天结束时统一过期。八、性能与使用建议时间复杂度为 O(1)读取与过期管理一次完成比GET 后 EXPIRE少一次往返。只适用于 String 类型其他类型会WRONGTYPE。不带选项的GETEX key就是GET不要为了高级感滥用。Key 不存在时返回空值且不创建 Key避免误以为它会像SET ... EX一样写入。一次只能指定一种过期选项EX/PX/EXAT/PXAT/PERSIST 不可混用。GETEX是写命令设置 TTL 属于写语义会记录到 AOF 并传播到从节点纯读取请用GET。会话续期等高频场景建议使用GETEX原子续期替代读 EXPIRE的竞态方案。需要同时读取并删除时用GETDEL需要读取并续期时用GETEX两者用途不同。版本低于 6.2.0 无此命令需升级或用 Lua 脚本模拟原子读 续期EVAL local v redis.call(GET, KEYS[1]) if v then redis.call(EXPIRE, KEYS[1], ARGV[1]) end return v 1 key 300九、常见问题排查问题 1GETEX 返回 nil / nullKey 不存在。检查EXISTS key TTL key确认 Key 名、数据库编号、是否过期。GETEX 不会因 Key 不存在而创建它。问题 2报 WRONGTYPEKey 不是 String 类型TYPE key非 String 类型改用对应命令读取过期时间用EXPIRE/PEXPIRE单独设置。问题 3报 “unknown command ‘GETEX’”Redis 版本低于 6.2.0。升级 Redis或改用GETEXPIRE组合注意非原子。问题 4TTL 没有按预期变化不带过期选项时GETEX不会改变 TTLPERSIST 会移除 TTLEX/PX 会重置 TTL。确认是否传了正确的选项与单位秒 vs 毫秒EXAT 需传绝对时间戳。问题 5多选项同时传入报语法错误GETEX key EX 60 PERSIST这类写法无效。一次只保留一个过期选项。问题 6EXAT/PXAT 传了相对秒数导致立即过期EXAT需要 Unix 绝对时间戳。误把 300 当成300 秒后会得到一个过去的绝对时刻Key 立即过期。相对过期请用EX 300/PX 300000。十、完整练习下面的示例覆盖 EX/PX、EXAT/PXAT、PERSIST、无选项、Key 不存在、类型错误与续期对比。请在测试数据库执行FLUSHDB会清空当前逻辑数据库中的全部 Key。FLUSHDB # 1. 读取并设置 EX SET demo:session data GETEX demo:session EX 60 TTL demo:session # 2. 读取并设置 PX GETEX demo:session PX 60000 PTTL demo:session # 3. 不带选项等价 GETTTL 不变 GETEX demo:session TTL demo:session # 4. PERSIST 移除过期 GETEX demo:session PERSIST TTL demo:session # 5. EXAT 绝对过期需替换为未来的时间戳 # 例如 2030-01-01 00:00:00 UTC 的秒级时间戳为 1893456000 GETEX demo:session EXAT 1893456000 TTL demo:session # 6. Key 不存在 GETEX demo:none EX 60 # 7. 空字符串 SET demo:empty GETEX demo:empty EX 60 # 8. 类型错误 HSET demo:hash name Alice GETEX demo:hash EX 60 # 9. 多选项并存报错 SET demo:multi v GETEX demo:multi EX 60 PERSIST # 10. 与 GET/EXPIRE 的差异对比 SET demo:cmp v EX 100 GET demo:cmp TTL demo:cmp GETEX demo:cmp EX 300 TTL demo:cmp # 11. Lua 模拟读 续期6.2 以下版本 EVAL local v redis.call(GET, KEYS[1]) if v then redis.call(EXPIRE, KEYS[1], ARGV[1]) end return v 1 demo:cmp 600 TTL demo:cmp预期结果GETEX demo:session EX 60返回dataTTL返回约60。GETEX demo:session PX 60000返回dataPTTL返回约60000。不带选项的GETEX返回dataTTL 继续递减不重置。GETEX demo:session PERSIST返回dataTTL返回-1。GETEX demo:session EXAT 1893456000返回dataTTL返回到 2030-01-01 的剩余秒数较大整数。GETEX demo:none EX 60返回(nil)不创建 Key。GETEX demo:empty EX 60返回。对 Hash 的GETEX返回(error) WRONGTYPE ...。GETEX demo:multi EX 60 PERSIST返回语法错误。对比示例GET后 TTL 不变GETEX ... EX 300后 TTL 重置为约300。Lua 脚本返回vTTL demo:cmp返回约600。十一、命令速查表需求命令读取并设置秒级过期GETEX key EX seconds读取并设置毫秒级过期GETEX key PX milliseconds读取并设置秒级绝对过期GETEX key EXAT timestamp读取并设置毫秒级绝对过期GETEX key PXAT timestamp读取并移除过期GETEX key PERSIST只读取GET key读取并删除GETDEL key只设置过期秒EXPIRE key seconds只设置过期毫秒PEXPIRE key milliseconds查看剩余时间秒TTL key查看剩余时间毫秒PTTL key写入并设置过期SET key value EX seconds总结GETEX的核心作用是读取 String Key 的值并可同时设置、更新或移除过期时间基本语法为GETEX key [EX seconds | PX milliseconds | EXAT ts | PXAT ts | PERSIST]使用时重点注意六点是读取 过期时间管理的原子命令避免GET 后 EXPIRE的竞态。返回值是值本身Key 不存在返回空值且不创建 Key。不带选项时等价于GET不改变 TTL。一次只能指定 EX/PX/EXAT/PXAT/PERSIST 中的一种。只适用于 String 类型其他类型返回WRONGTYPE。自 Redis 6.2.0 起可用更早版本需升级或用 Lua 脚本模拟。
返回列表