
Redis EXPIRETIME 命令詳細教程EXPIRETIME用于獲取 Key 的過期時間對應(yīng)的 Unix 時間戳秒。與TTL返回剩余秒數(shù)不同EXPIRETIME返回的是絕對時間點便于在應(yīng)用端直接判斷 Key 何時過期、進行倒計時或與定時任務(wù)結(jié)合使用。本文基于 Redis 通用 Key 操作介紹EXPIRETIME。Redis 命令本身不區(qū)分大小寫因此EXPIRETIME、expiretime和Expiretime的效果相同文檔統(tǒng)一使用大寫形式。EXPIRETIME自 Redis 7.0 起可用。資料合集https://pan.quark.cn/s/10e98d308913、https://pan.quark.cn/s/f56bc69c5338一、命令概覽1. 基本語法EXPIRETIME key參數(shù)說明參數(shù)說明key要查詢過期時間戳的 Key返回值場景返回值Key 存在且有過期時間過期時間的 Unix 時間戳正整數(shù)秒Key 存在但無過期時間永久有效-1Key 不存在-22. 最簡單的示例先寫入一個值并設(shè)置過期時間再查看過期時間戳SET mykey Hello EX 3600 EXPIRETIME mykey返回類似(integer) 1724719123返回值是該 Key 過期時刻的 Unix 時間戳秒。用當前時間戳減去它結(jié)果等于TTL的值。二、EXPIRETIME 的返回結(jié)果1. Key 存在且有過期時間SET session:user:1001 active EX 1800 EXPIRETIME session:user:1001返回一個正整數(shù)如(integer) 1724722723表示該 Key 將在該 Unix 時間戳對應(yīng)的時刻過期。2. Key 存在但無過期時間永久有效SET permanent-key forever EXPIRETIME permanent-key返回(integer) -1-1表示 Key 存在但沒有設(shè)置過期時間永遠不會自動過期。3. Key 不存在EXPIRETIME no-such-key返回(integer) -2-2表示 Key 不存在可能從未創(chuàng)建、已被刪除或已過期被清理。4. 已過期的 Key已經(jīng)過期但尚未被惰性/定期刪除清理的 KeyEXPIRETIME返回-2視為不存在SET temp-key value EX 1等待 1 秒后執(zhí)行EXPIRETIME temp-key返回(integer) -2Redis 在訪問時進行惰性過期檢查因此即使 Key 尚在內(nèi)存中EXPIRETIME也會正確返回-2。5. 用絕對時間戳設(shè)置過期的 Key使用EXPIREAT或SET ... EXAT設(shè)置的 KeyEXPIRETIME返回的值就是設(shè)置時指定的時間戳SET promo:key summer-sale EXAT 1735689600 EXPIRETIME promo:key返回(integer) 1735689600用相對時間設(shè)置的 Key返回值也是絕對時間戳而非相對秒數(shù)SET cache:key value EX 3600 EXPIRETIME cache:key返回的是當前時間 3600 秒對應(yīng)的絕對時間戳。三、EXPIRETIME 與 TTL 的關(guān)系EXPIRETIME返回過期時刻的絕對時間戳TTL返回剩余生存秒數(shù)。兩者存在數(shù)學(xué)關(guān)系TTL(key) EXPIRETIME(key) - 當前Unix時間戳1. 對比示例SET mykey value EX 3600 TTL mykey EXPIRETIME mykey TIME返回類似TTL mykey - (integer) 3600 EXPIRETIME mykey - (integer) 1724722723 TIME - 1) 1724719123 2) 456789驗證1724722723 - 1724719123 3600與TTL返回值一致。2. 何時使用 EXPIRETIME何時使用 TTL需求推薦命令原因判斷 Key 是否快過期TTL直接得到剩余秒數(shù)顯示倒計時TTL剩余秒數(shù)可直接用于倒計時獲取 Key 何時過期絕對時間EXPIRETIME返回絕對時間戳與外部定時任務(wù)結(jié)合EXPIRETIME絕對時間便于跨系統(tǒng)對齊判斷 Key 是永久還是臨時TTL或EXPIRETIME均可返回-1即永久四、EXPIRETIME 與相關(guān)命令的區(qū)別1. EXPIRETIME 與 PEXPIRETIMEEXPIRETIME返回秒級時間戳PEXPIRETIME返回毫秒級時間戳SET mykey value PEX 3600000 EXPIRETIME mykey # 返回秒級時間戳如 1724722723 PEXPIRETIME mykey # 返回毫秒級時間戳如 1724722723456命令精度返回值示例EXPIRETIME key秒1724722723PEXPIRETIME key毫秒1724722723456需要毫秒精度時使用PEXPIRETIME。2. EXPIRETIME 與 TTL / PTTL命令返回內(nèi)容單位EXPIRETIME key過期時刻的絕對時間戳秒PEXPIRETIME key過期時刻的絕對時間戳毫秒TTL key剩余生存時間秒PTTL key剩余生存時間毫秒SET mykey value EX 3600 EXPIRETIME mykey # 過期時間戳 TTL mykey # 剩余秒數(shù) PTTL mykey # 剩余毫秒數(shù) PEXPIRETIME mykey # 過期毫秒時間戳3. EXPIRETIME 與 EXPIREAT / EXPIRE 的區(qū)別EXPIREAT和EXPIRE是寫命令用于設(shè)置過期時間EXPIRETIME是只讀命令用于查詢過期時間戳。命令操作類型作用EXPIREAT key timestamp寫設(shè)置絕對過期時間EXPIRE key seconds寫設(shè)置相對過期時間EXPIRETIME key只讀查詢過期時間戳4. 返回值對比總表狀態(tài)EXPIRETIMETTLPTTLPEXPIRETIMEKey 存在且有過期過期秒級時間戳剩余秒數(shù)剩余毫秒數(shù)過期毫秒級時間戳Key 存在無過期-1-1-1-1Key 不存在-2-2-2-2五、EXPIRETIME 與不同數(shù)據(jù)類型EXPIRETIME作用于整個 Key所有數(shù)據(jù)類型String、Hash、List、Set、Sorted Set、Stream 等的行為一致。HSET user:1001 name Alice age 30 EXPIRE user:1001 3600 EXPIRETIME user:1001RPUSH queue:jobs job-a job-b EXPIRE queue:jobs 1800 EXPIRETIME queue:jobsSADD tags redis python EXPIRE tags 7200 EXPIRETIME tags返回值都是 Key 的過期時間戳與數(shù)據(jù)類型無關(guān)。六、過期時間的刷新與 EXPIRETIME1. 覆蓋式更新后的反映對已有過期時間的 Key 再次執(zhí)行EXPIRE或EXPIREATEXPIRETIME返回的值會更新為新的過期時間戳SET mykey value EX 3600 EXPIRETIME mykey # 返回 timestamp1 EXPIREAT mykey 1767225600 EXPIRETIME mykey # 返回 17672256002. SET 會清除過期時間使用SET命令覆蓋 Key 的值時不帶EX/PX/EXAT/PXAT過期時間被清除EXPIRETIME返回-1SET mykey old EX 3600 EXPIRETIME mykey # 返回正數(shù) SET mykey new EXPIRETIME mykey # 返回 -13. PERSIST 后的反映PERSIST移除過期時間后EXPIRETIME返回-1SET mykey value EX 3600 PERSIST mykey EXPIRETIME mykey # 返回 -14. 各命令對 EXPIRETIME 結(jié)果的影響操作EXPIRETIME 返回值變化EXPIRE key seconds更新為新的過期時間戳EXPIREAT key timestamp更新為指定的時間戳PEXPIRE key ms更新為新的過期時間戳PEXPIREAT key timestamp更新為指定的時間戳SET key value無選項變?yōu)?1清除過期SET key value EX seconds更新為新的過期時間戳SET key value EXAT timestamp更新為指定的時間戳PERSIST key變?yōu)?1移除過期INCR/LPUSH/HSET等不影響保持原值GETEX key取決于參數(shù)可修改或清除過期時間七、事務(wù)、Pipeline 與并發(fā)場景1. 在事務(wù)中使用EXPIRETIME可以放入事務(wù)隊列MULTI SET mykey value EX 3600 EXPIRETIME mykey TTL mykey EXECEXEC執(zhí)行后返回各命令的結(jié)果。2. 只讀特性與并發(fā)安全EXPIRETIME是只讀命令不修改任何數(shù)據(jù)不會影響其他客戶端的操作。多個客戶端同時調(diào)用EXPIRETIME是安全的。3. 并發(fā)場景下的注意事項由于EXPIRETIME返回的是查詢時刻的過期時間戳如果在兩次查詢之間有其他客戶端修改了 Key 的過期時間如EXPIRE、SET、PERSIST返回值可能不同。這屬于正常的并發(fā)行為先查再判斷的多步流程不是原子操作。需要原子地檢查過期時間并執(zhí)行操作時使用 Lua 腳本localexpireredis.call(EXPIRETIME,KEYS[1])ifexpire0thenreturnexpireelsereturnredis.call(EXPIRE,KEYS[1],ARGV[1])end4. Pipeline 批量查詢需要查詢大量 Key 的過期時間戳?xí)r可以使用 Pipeline 批量發(fā)送EXPIRETIME命令減少網(wǎng)絡(luò)往返。八、在常見客戶端中的使用方式1. redis-cliredis-cli SET mykeyvalueEX3600redis-cli EXPIRETIME mykey redis-cli SET permanentforeverredis-cli EXPIRETIME permanent redis-cli EXPIRETIME no-such-key分別返回正數(shù)時間戳、-1、-2。2. Pythonredis-pyimportredis clientredis.Redis(hostlocalhost,port6379,decode_responsesTrue)client.set(mykey,value,ex3600)# 獲取過期時間戳expire_timeclient.expiretime(mykey)print(expire_time)# 如 1724722723# 永久 Keyclient.set(permanent,forever)print(client.expiretime(permanent))# -1# 不存在的 Keyprint(client.expiretime(no-such-key))# -23. Node.jsnode-redisimport{createClient}fromredis;constclientcreateClient();awaitclient.connect();awaitclient.set(mykey,value,{EX:3600});constexpireTimeawaitclient.expireTime(mykey);console.log(expireTime);// 如 1724722723awaitclient.set(permanent,forever);console.log(awaitclient.expireTime(permanent));// -1console.log(awaitclient.expireTime(no-such-key));// -2awaitclient.quit();4. JavaJedistry(JedisjedisnewJedis(localhost,6379)){jedis.set(mykey,value,SetParams.setParams().ex(3600));// 獲取過期時間戳longexpireTimejedis.expireTime(mykey);System.out.println(expireTime);// 如 1724722723// 永久 Keyjedis.set(permanent,forever);System.out.println(jedis.expireTime(permanent));// -1// 不存在的 KeySystem.out.println(jedis.expireTime(no-such-key));// -2}九、典型使用場景1. 倒計時顯示獲取 Key 的絕對過期時間戳在客戶端計算剩余時間并顯示倒計時SET flash-sale:product active EX 3600 EXPIRETIME flash-sale:product客戶端用EXPIRETIME返回的時間戳減去當前時間戳得到剩余秒數(shù)并顯示。2. 過期時間對齊多個 Key 需要在同一時刻過期時用EXPIRETIME確認是否已對齊EXPIRETIME cache:a EXPIRETIME cache:b EXPIRETIME cache:c如果返回值不同用EXPIREAT統(tǒng)一調(diào)整EXPIREAT cache:a 1735689600 EXPIREAT cache:b 1735689600 EXPIREAT cache:c 17356896003. 監(jiān)控與告警監(jiān)控系統(tǒng)查詢 Key 的過期時間戳判斷是否即將過期并提前告警EXPIRETIME session:critical如果返回的時間戳接近當前時間戳觸發(fā)告警提醒續(xù)期。4. 與外部定時任務(wù)結(jié)合應(yīng)用端獲取 Key 的過期時間戳后在對應(yīng)時刻注冊定時任務(wù)處理過期事件EXPIRETIME task:cleanup5. 數(shù)據(jù)生命周期審計定期掃描設(shè)置了過期時間的 Key審計過期時間是否合理SCAN 0 EXPIRETIME key1 EXPIRETIME key2十、性能與使用建議時間復(fù)雜度O(1)。EXPIRETIME是只讀命令A(yù)CL 類別為keyspace、read、fast不會修改數(shù)據(jù)不會觸發(fā)通知。性能優(yōu)異頻繁調(diào)用不會對 Redis 造成壓力。只需判斷 Key 是否存在時用EXISTS語義更清晰需要過期時間信息時用EXPIRETIME。需要剩余秒數(shù)時用TTL需要絕對時間戳?xí)r用EXPIRETIME兩者可互相換算。EXPIRETIME對永久 Key 返回-1、對不存在的 Key 返回-2與TTL的返回值約定一致便于統(tǒng)一處理。集群模式下EXPIRETIME作用于單個 Key不受哈希槽限制。Redis 7.0 以下版本不支持EXPIRETIME調(diào)用會返回錯誤。低版本場景可用TTL加上當前時間戳間接計算。十一、常見問題排查問題 1EXPIRETIME 返回 -2 但 Key 應(yīng)該存在按以下順序檢查是否連接到了正確的 Redis 實例、端口和邏輯數(shù)據(jù)庫不同SELECT庫中 Key 相互獨立。Key 是否已經(jīng)過期用TTL確認返回-2表示不存在。Key 名稱是否包含不可見字符、前后空格或大小寫差異。Key 是否被其他客戶端刪除或覆蓋SET不帶選項會清除過期時間但 Key 仍存在如果返回-2則 Key 本身不存在。EXISTS mykey TTL mykey TYPE mykey問題 2EXPIRETIME 返回 -1 但預(yù)期有過期時間可能的原因在設(shè)置過期時間后執(zhí)行了SET不帶EX/EXAT等選項覆蓋了 Key 的值導(dǎo)致過期時間被清除。執(zhí)行了PERSIST命令移除了過期時間。查詢的 Key 與設(shè)置過期的 Key 不是同一個名稱差異。問題 3EXPIRETIME 返回的時間戳與預(yù)期不符可能的原因使用了EXPIRE相對秒數(shù)而非EXPIREAT絕對時間戳設(shè)置過期返回的時間戳是設(shè)置時刻 相對秒數(shù)。過期時間被其他客戶端用EXPIRE、EXPIREAT或SET ... EX更新過。時區(qū)理解錯誤返回的是 UTC Unix 時間戳不是本地時間。問題 4Redis 7.0 以下版本報錯EXPIRETIME從 Redis 7.0 開始支持。低版本調(diào)用會返回錯誤ERR unknown command EXPIRETIME替代方案使用TTL key獲取剩余秒數(shù)加上當前時間戳得到過期時間戳redis-cli TTL mykey# 獲取剩余秒數(shù)redis-cli TIME# 獲取當前時間戳# 過期時間戳 當前時間戳 TTL問題 5EXPIRETIME 與 PEXPIRETIME 返回值不一致EXPIRETIME返回秒級時間戳PEXPIRETIME返回毫秒級時間戳。兩者數(shù)值相差約 1000 倍但表示的是同一過期時刻EXPIRETIME mykey # 如 1724722723 PEXPIRETIME mykey # 如 1724722723456PEXPIRETIME EXPIRETIME * 1000 毫秒部分。十二、完整練習(xí)下面的示例演示從設(shè)置過期時間、查詢過期時間戳、對比 TTL 與 EXPIRETIME、驗證不同狀態(tài)返回值到與SET、PERSIST、EXPIREAT等命令配合使用的完整流程DEL demo:key DEL demo:perm DEL demo:short # 基本用法設(shè)置相對過期查詢絕對時間戳 SET demo:key hello EX 3600 EXPIRETIME demo:key TTL demo:key TIME # 驗證關(guān)系EXPIRETIME 當前時間戳 TTL # 如 EXPIRETIME1724722723, TIME1724719123, TTL3600 # 永久 Key 返回 -1 SET demo:perm forever EXPIRETIME demo:perm TTL demo:perm # 不存在的 Key 返回 -2 EXPIRETIME demo:noexist TTL demo:noexist # 用絕對時間戳設(shè)置過期 EXPIREAT demo:key 1767225600 EXPIRETIME demo:key # SET 清除過期時間 SET demo:key new value EXPIRETIME demo:key # SET ... EXAT 設(shè)置過期時間戳 SET demo:key with ttl EXAT 1735689600 EXPIRETIME demo:key # PERSIST 后返回 -1 PERSIST demo:key EXPIRETIME demo:key # 過期后返回 -2 SET demo:short gone EX 1 # 等待 1 秒后執(zhí)行 # EXPIRETIME demo:short # TTL demo:short # 對比 EXPIRETIME 與 PEXPIRETIME SET demo:precision value EX 3600 EXPIRETIME demo:precision PEXPIRETIME demo:precision預(yù)期結(jié)果EXPIRETIME demo:key返回正數(shù)時間戳TTL demo:key返回約3600EXPIRETIME - TIME約等于TTL。EXPIRETIME demo:perm返回-1TTL demo:perm返回-1。EXPIRETIME demo:noexist返回-2TTL demo:noexist返回-2。EXPIREAT demo:key 1767225600后EXPIRETIME demo:key返回1767225600。SET demo:key new value后EXPIRETIME demo:key返回-1。SET demo:key with ttl EXAT 1735689600后EXPIRETIME demo:key返回1735689600。PERSIST demo:key后EXPIRETIME demo:key返回-1。過期后EXPIRETIME demo:short返回-2。EXPIRETIME與PEXPIRETIME返回值相差約 1000 倍表示同一過期時刻。十三、命令速查表需求命令返回值類型獲取過期時間戳秒EXPIRETIME key秒級 Unix 時間戳獲取過期時間戳毫秒PEXPIRETIME key毫秒級 Unix 時間戳獲取剩余生存時間秒TTL key剩余秒數(shù)獲取剩余生存時間毫秒PTTL key剩余毫秒數(shù)判斷 Key 是否存在EXISTS key0 或 1獲取 Key 的數(shù)據(jù)類型TYPE key類型字符串設(shè)置秒級過期時間EXPIRE key seconds0 或 1設(shè)置絕對過期時間秒EXPIREAT key timestamp0 或 1設(shè)置毫秒級過期時間PEXPIRE key ms0 或 1設(shè)置絕對過期時間毫秒PEXPIREAT key timestamp0 或 1原子設(shè)置值和過期時間戳SET key value EXAT timestampOK移除過期時間PERSIST key0 或 1獲取服務(wù)器當前時間TIME秒 微秒總結(jié)EXPIRETIME的核心作用是返回 Key 過期時刻的 Unix 時間戳秒便于應(yīng)用端獲取絕對過期時間點EXPIRETIME key使用時重點注意四點返回值約定與TTL一致正數(shù)表示過期時間戳-1表示永久有效-2表示 Key 不存在。EXPIRETIME返回的是絕對時間戳TTL返回的是剩余秒數(shù)兩者可互相換算。SET不帶選項會清除過期時間EXPIRE/EXPIREAT會更新過期時間PERSIST會移除過期時間EXPIRETIME能反映這些變化。EXPIRETIME從 Redis 7.0 開始支持低版本可用TTL加當前時間戳間接計算過期時間戳。