redis设置键的生存时间或过期时间
設置鍵的生存時間或過期時間
通過EXPIRE 命令或者PEXPIRE 命令,客戶端可以以秒或者毫秒精度為數據庫中的某個鍵設置生存時間( Time To Live , TTL) ,在經過指定的秒數或者毫秒數之后,服務器就會自動刪除生存時間為0的鍵:
redis> SET key value OK redis> EXP 工RE key 5 (integer) 1 redis> GET key // 5 秒之內 "value" redis> GET key // 5 秒之后 (nil)注意
SETEX 命令可以在設直一個字符串鍵的同時為鍵設直過期時間,因為這個命令是一個類型限定的命令(只能用于字符串鍵),但SETEX 命令設置過期時間的原理和EXPIRE命令設置過期時間的原理是完全一樣的。
與EXPlRE 命令和PEXPIRE 命令類似,客戶端可以通過EXPlREAT 命令或PEXPlREAT命令,以秒或者毫秒精度給數據庫中的某個鍵設置過期時間(expire time)。
過期時間是一個UNIX時間戳,當鍵的過期時間來臨時,服務器就會自動從數據庫中刪除這個鍵:
?
redis> SET key value OK redis> EXPIREAT key 1377257300 (integer) 1 redis> TIME1)"1377257296" 2)"296543" redis> GET key // 1377257300 之前 "value" redis> TIME 1)"1377257303" 2)"230656 " redis> GET key // 1377257300 之后 (nil)?
TTL 命令和PTTL 命令接受一個帶有生存時間或者過期時間的鍵,返回這個鍵的剩余生存時間,也就是,返回距離這個鍵被服務器自動刪除還有多長時間:
redis> SET key va1ue OK redis> EXPlRE key 1000 (integer) 1 redis> TTL key (integer) 997 redis> SET another_key another_value OK redis> TIME 1) "1377333070 " 2) "761687 " redis> EXPlREAT another key 1377333100 (integer ) 1 redis> TTL another key (integer) 10設置過期時間
?
Redis 有四個不同的命令可以用于設置鍵的生存時間(鍵可以存在多久)或過期時間(鍵什么時候會被刪除) :
EXPlRE <key> <ttl> 命令用于將鍵key 的生存時間設置為ttl 秒。
PEXPIRE <key> <ttl> 命令用于將鍵key 的生存時間設置為ttl 毫秒。
EXPIREAT <key> < timestamp> 命令用于將鍵key 的過期時間設置為timestamp所指定的秒數時間戳。
PEXPIREAT <key> < timestamp > 命令用于將鍵key 的過期時間設置為timestamp所指定的毫秒數時間戳。
雖然有多種不同單位和不同形式的設置命令,但實際上EXPlRE、PEXPlRE 、EXPIREAT三個命令都是使用PEXPlREAT 命令來實現的:無論客戶端執行的是以上四個命令中的哪一個, 經過轉換之后,最終的執行效果都和執行PEXPlREAT 命令一樣。
首先, EXPIRE 命令可以轉換成PEXPlRE 命令:
接著,PEXPlRE 命令又可以轉換成PEXPlREAT 命令:
def PEXPIRE(key,ttl_in_ms) : #獲取以毫秒計算的當前UNIX 時間戳 now_ms = get_current_unix_timestamp_in_ms() #當前時間加上TTL,得出毫秒格式的鍵過期時間 PEXPlREAT(key,now_ms+ttl_in_ms)并且,EXPlREAT命令也可以轉換成PEXPlREAT命令:
def EXPIREAT (key,expire_time_in_ sec): #將過期時間從秒轉換為毫秒 expire_time_ in_ms = sec_to_ms (expire_time_in_sec) PEXPlREAT(key, expire_time_in_ms)?
保存過期時間
redisDB結構的expires字典保存了數據庫中所有鍵的過期時間,我們稱這個字典為過期字典:
過期字典的鍵是一個指針,這個指針指向鍵空間中的某個鍵對象( 也即是某個數據庫鍵)。
過期字典的值是一個long long 類型的整數,這個整數保存了鍵所指向的數據庫鍵的過期時間:一個毫秒精度的UNIX 時間戳。
如下圖展示了一個帶有過期字典的數據庫例子,在這個例子中,鍵空間保存了數據庫中的所有鍵值對,而過期字典則保存了數據庫鍵的過期時間。
過期字典將新增一個鍵值對, 其中鍵為message 鍵對象,而值則為1391234400000(2014年2月1日零時) ,如圖9-13 所示。
圖9-12 中的過期字典保存了兩個鍵值對:
第一個鍵值對的鍵為alphabet 鍵對象,值為1385877600000 ,這表示數據庫鍵alphabet 的過期時間為1385877600000 (2013年12月1日零時)。
第二個鍵值對的鍵為book鍵對象,值為1388556000000,這表示數據庫鍵book的過期時間為1388556000000(2014年1月1日零時)。
當客戶端執行PEXPIREAT 命令(或者其他三個會轉換成PEXPIREAT命令的命令)為一個數據庫鍵設置過期時間時,服務器會在數據庫的過期字典中關聯給定的數據庫鍵和過期時間。
舉個例子, 如果數據庫當前的狀態如圖9-12 所示, 那么在服務器執行以下命令之后:
過期字典將新增一個鍵值對,其中鍵為message鍵對象,而值則為1391234400000(2014年2月1日零時),如圖9-13 所示。
?以下是PEXPlREAT 命令的偽代碼定義:
def PEXPIREAT(key,expire_time_in_ms) : #如果給定的鍵不存在于鍵空間,那么不能設置過期時間 if key not in redisDB.dict : return 0 #在過期字典中關聯鍵和過期時間 redisDB.expires[key]=expire_tirne_in_ms #過期時間設置成功 return 1移除過期時間
PERSIST命令可以移除一個鍵的過期時間:
redis>PEXPlREAT message 1391234400000 (integer) 1 redis>TTL message (integer) 13893281 redis> PERSIST message (integer) 1 redis> TTL message (integer) - 1PERSIST命令就是PEXPIREAT命令的反操作: PERSIST 命令在過期字典中查找給定的鍵,并解除鍵和值(過期時間)在過期字典中的關聯。
舉個例子,如果數據庫當前的狀態如圖9-12所示,那么當服務器執行以下命令之后:
數據庫將更新成圖9-14 所示的狀態。
可以看到,當PERSIST命令執行之后,過期字典中原來的book鍵值對消失了,這代表數據庫鍵book的過期時間已經被移除。
以下是PERSIST 命令的偽代碼定義:
計算并返回剩余生存時間
TTL 命令以秒為單位返回鍵的剩余生存時間, 而P TTL 命令則以毫秒為單位返回鍵的剩余生存時間:
redis> PEXPIREAT alphabet 1385877600000 (integer) 1 redis> TTL alphabet (integer) 85 49007 redis> PTTL alphabet (integer) 8549001011TTL 和PTTL 兩個命令都是通過計算鍵的過期時間和當前時間之間的差來實現的,以下
是這兩個命令的偽代碼實現:
舉個例子,對于一個過期時間為1385877600000(2013年12月1日零時)的鍵alphabet來說:
如果當前時間為1383282000000 (2013年11月1日零時),那么對鍵alphabet執行PTTL命令將返回2595600000 ,這個值是通過用a1phabet 鍵的過期時間減去當前時間計算得出的: 1385877600000-1383282000000=25956000000
另一方面,如果當前時間為1383282000000 ( 2013年11月1日零時),那么對鍵alphabet執行TTL命令將返回2595600,這個值是通過計算alphabet 鍵的過期時間減去當前時間的差,然后將差值從毫秒轉換為秒之后得出的。
過期鍵的判定
通過過期字典,程序可以用以下步驟檢查一個給定鍵是否過期:
1 )檢查給定鍵是否存在于過期字典:如果存在,那么取得鍵的過期時間。
2 )檢查當前UNIX 時間戳是否大于鍵的過期時間: 如果是的話,那么鍵已經過期;否則的話,鍵未過期。
可以用偽代碼來描述這一過程:
舉個例子,對于一個過期時間為1385877600000 (2013年12月1日零時)的鍵alphabet來說:
如果當前時間為1383282000000 (2013 年II 月1 日零時),那么調用is_expired ( alphabet ) 將返回False ,因為當前時間小于alphabet 鍵的過期時間。
另一方面,如果當前時間為1385964000000 (2013年12月2日零時),那么調用is_expired(alphabet) 將返回True. 因為當前時間大于alphabet 鍵的過期時間。
注意
實現過期鍵判定的另一種方法是使用TTL 命令或者PTTL 命令,比如說,如采對某個鍵執行TTL 命令,并且命令返回的位大于等于0 ,那么說明該鍵未過期。在實際中, Redis檢查鍵是否過期的方法和is_expired函數所描述的方法一致,因為直接訪問字典比執行一個命令稍微快一些。
總結
以上是生活随笔為你收集整理的redis设置键的生存时间或过期时间的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: redis 延时任务 看一篇成高手系列
- 下一篇: github生成密钥