Redis設(shè)置鍵的生存時(shí)間或過期時(shí)間的方法詳解
鍵的生存時(shí)間或過期時(shí)間
概述
通過EXPIRE命令或者PEXIPIRE命令,客戶端可以以秒或者毫秒精度為數(shù)據(jù)庫(kù)中的某個(gè)鍵設(shè)置生存時(shí)間(Time To Live,TTL),在經(jīng)過指定的秒數(shù)或者毫秒數(shù)之后,服務(wù)器就會(huì)自動(dòng)刪除生存時(shí)間為0的鍵:
127.0.0.1:6379> SET key value OK 127.0.0.1:6379> EXPIRE key 5 (integer) 1 // 5秒之內(nèi) 127.0.0.1:6379> GET key "value" // 5秒之后 127.0.0.1:6379> GET key (nil)
注意:
SETEX命令可以在設(shè)置一個(gè)字符串鍵的同時(shí)為鍵設(shè)置過期時(shí)間,因?yàn)檫@個(gè)命令是一個(gè)類型限定的命令(只能用于字符串鍵)
與EXPIRE命令和PEXPIRE命令類似,客戶端可以通過EXPIREAT命令或PEXPIREAT命令,以秒或者毫秒精度給數(shù)據(jù)庫(kù)中的某個(gè)鍵設(shè)置過期時(shí)間(expire time)過期時(shí)間是一個(gè)UNIX時(shí)間戳,當(dāng)鍵的過期時(shí)間來臨時(shí),服務(wù)器就會(huì)自動(dòng)從數(shù)據(jù)庫(kù)中刪除這個(gè)鍵
127.0.0.1:6379> SET key value OK 127.0.0.1:6379> EXPIREAT key 1710944249 (integer) 1 // 過期時(shí)間之前 127.0.0.1:6379> GET key "value" // 過期時(shí)間之后 127.0.0.1:6379> GET key (nil)
TTL和PTTL
TTL命令和PTTL命令接受一個(gè)帶有生存時(shí)間或者過期時(shí)間的鍵,返回這個(gè)鍵的剩余生存時(shí)間,也就是,返回距離這個(gè)鍵被服務(wù)器自動(dòng)刪除還有多長(zhǎng)時(shí)間
127.0.0.1:6379> SET key value OK 127.0.0.1:6379> EXPIRE key 1000 (integer) 1 127.0.0.1:6379> TTL key (integer) 996
設(shè)置過期時(shí)間
Redis有四個(gè)不同的命令可以用于設(shè)置鍵key的生存時(shí)間(鍵可以存在多久)或過期時(shí)間(鍵什么時(shí)候會(huì)被刪除)
- 1.EXPIRE 命令用于將鍵key的生存時(shí)間設(shè)置為ttl秒
- 2.PEXPIRE命令用于將鍵key的生存時(shí)間設(shè)置為ttl毫秒
- 3.EXPIREAT 命令用于將鍵key的過期時(shí)間設(shè)置為timestamp所指定的秒數(shù)時(shí)間戳
- 4.PEXIREAT命令用于將鍵key的過期時(shí)間設(shè)置為timestamp所指定的毫秒數(shù)時(shí)間戳
雖然有多種不同單位和不同形式的設(shè)置命令,但實(shí)際上EXPIRE、PEXIPIRE、EXPIREAT三個(gè)命令都是使用PEXIPREAT命令來實(shí)現(xiàn)的:無論客戶端執(zhí)行的是以上四個(gè)命令中的哪一個(gè),經(jīng)過轉(zhuǎn)換之后,最終的執(zhí)行效果都和執(zhí)行PEXIPIREAT命令一樣
內(nèi)部實(shí)現(xiàn)
首先,EXPIRE命令可以轉(zhuǎn)換成PEXIPIRE命令
def EXPIRE(key, ttl_in_sec): #將TTL從秒轉(zhuǎn)換成毫秒 ttl_in_ms = sec_to_ms(ttl_in_ec)
接著,PEXIRE命令又可以轉(zhuǎn)換成PEXIREAT命令:
def PEXIPRE(key, ttl_in_ms): # 獲取以毫秒計(jì)算的當(dāng)前UNIX時(shí)間戳 now_ms = get_curent_unix_timestamp_in_ms(); # 當(dāng)前時(shí)間加上TTL,得出毫秒格式的鍵過期時(shí)間 PEXIREAT(key,now_ms+ttl_in_ms)
并且,EXPIREAT命令也可以轉(zhuǎn)換成PEXIREAT命令:
def EXPIREAT (key, expire_time_in_sec): # 將過期時(shí)間從秒轉(zhuǎn)換為毫秒 expire_time_in_ms = sec_to_ms(expire_time_in_sec) PEXPIREAT(key, expire_tiime_in_ms);
最終,EXPIRE、PEXPIRE和EXPIREAT三個(gè)命令都會(huì)轉(zhuǎn)化成PEXIREAT命令來執(zhí)行
保存過期時(shí)間
redisDb結(jié)構(gòu)的expire字典保存了數(shù)據(jù)庫(kù)中所有鍵的過期時(shí)間,我們稱這個(gè)字典為過期字典:
- 1.過期字典的鍵是一個(gè)指針,這個(gè)指針指向鍵是一個(gè)指針,這個(gè)指針指向鍵空間的某個(gè)鍵對(duì)象(也即是某個(gè)數(shù)據(jù)庫(kù)鍵)
- 2.過期字典的值是一個(gè)long long類型的整數(shù)。這個(gè)整數(shù)保存了鍵所指向的數(shù)據(jù)庫(kù)鍵的過期時(shí)間——一個(gè)毫秒精度的UNIX時(shí)間戳。
typedef struct redisDb { // .. // 過期字典,保存著鍵的過期時(shí)間 dict *expire; // ... }redisDb;
例子
舉個(gè)例子,圖中的過期字典保存了兩個(gè)鍵值對(duì):
1.第一個(gè)鍵值對(duì)的鍵為alphabet鍵對(duì)象,值為1385877900000,這表示數(shù)據(jù)庫(kù)鍵alphabet的過期時(shí)間為1385877600000(2013年12月)
2.第二個(gè)鍵值對(duì)的鍵為book鍵對(duì)象,值為1388556000000,這表示數(shù)據(jù)庫(kù)鍵book的過期時(shí)間為1388556000000(2014年1月1日零時(shí))當(dāng)客戶端執(zhí)行PEXPIREAT命令(或者其他三個(gè)會(huì)轉(zhuǎn)換成PEXIPREAT命令的命令)為一個(gè)
數(shù)據(jù)庫(kù)鍵設(shè)置過期時(shí)間時(shí),服務(wù)器會(huì)在數(shù)據(jù)庫(kù)的過期字典中關(guān)聯(lián)給定的數(shù)據(jù)庫(kù)和過期時(shí)間
讀寫鍵空間時(shí)的維護(hù)操作
當(dāng)使用Redis命令對(duì)數(shù)據(jù)庫(kù)進(jìn)行讀寫時(shí),服務(wù)器不僅會(huì)對(duì)鍵空間執(zhí)行指定的讀寫操作還會(huì)執(zhí)行一些額外的維護(hù)操作,其中包括
- 在讀取一個(gè)鍵之后(讀操作和寫操作都要對(duì)鍵進(jìn)行讀取),服務(wù)器會(huì)根據(jù)鍵是否存在來更新服務(wù)器的鍵空間命中(hit)次數(shù)或鍵空間不命中(miss)次數(shù),這兩個(gè)值可以在INFO stats命令的keyspace_hits屬性和keyspace_misses屬性中查看
127.0.0.1:6379> info stats # Stats total_connections_received:15 total_commands_processed:1887 instantaneous_ops_per_sec:0 total_net_input_bytes:9624 total_net_output_bytes:2803 instantaneous_input_kbps:0.00 instantaneous_output_kbps:0.00 rejected_connections:0 sync_full:0 sync_partial_ok:0 sync_partial_err:0 expired_keys:3 evicted_keys:0 keyspace_hits:38 keyspace_misses:11 pubsub_channels:0 pubsub_patterns:0 latest_fork_usec:9925 migrate_cached_sockets:0 127.0.0.1:6379>
- 在讀取一個(gè)鍵之后,服務(wù)器會(huì)更新鍵的LRU(最后一次使用)時(shí)間,這個(gè)值可以用于計(jì)算鍵的閑置時(shí)間,使用OBJECT idle time
key
命令可以查看鍵的閑置時(shí)間。
127.0.0.1:6379> set k v OK 127.0.0.1:6379> OBJECT idletime k (integer) 6
- 如果服務(wù)器在讀取一個(gè)鍵時(shí)發(fā)現(xiàn)該鍵已經(jīng)過期,那么服務(wù)器會(huì)先刪除這個(gè)過期鍵然后才執(zhí)行余下的操作
- 如果又客戶端使用WATCH命令監(jiān)視了某個(gè)鍵,那么服務(wù)器在對(duì)被監(jiān)視的鍵進(jìn)行修改之后,會(huì)將這個(gè)鍵標(biāo)記為臟(dirty),從而讓事務(wù)程序注意到這個(gè)鍵已經(jīng)被修改過
- 服務(wù)器每次修改一個(gè)鍵之后,都會(huì)對(duì)臟(dirty)鍵計(jì)數(shù)器的值增1,這個(gè)計(jì)數(shù)器會(huì)觸發(fā)服務(wù)器的持久化以及復(fù)制操作
- 如果服務(wù)器開啟了數(shù)據(jù)庫(kù)通知功能,那么在對(duì)鍵進(jìn)行修改之后,服務(wù)器將按配置發(fā)送相應(yīng)的數(shù)據(jù)庫(kù)通知
以上就是Redis設(shè)置鍵的生存時(shí)間或過期時(shí)間的方法詳解的詳細(xì)內(nèi)容,更多關(guān)于Redis設(shè)置鍵生存或過期時(shí)間的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Redis權(quán)限和訪問控制的實(shí)現(xiàn)示例
Redis提供了一些機(jī)制來保護(hù)敏感數(shù)據(jù)和限制對(duì)Redis服務(wù)器的訪問,本文主要介紹了Redis權(quán)限和訪問控制的實(shí)現(xiàn)示例,具有一定的參考價(jià)值,感興趣的可以了解一下2023-12-12Redis和數(shù)據(jù)庫(kù) 數(shù)據(jù)同步問題的解決
這篇文章主要介紹了Redis和數(shù)據(jù)庫(kù) 數(shù)據(jù)同步問題的解決操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-01-01mac下設(shè)置redis開機(jī)啟動(dòng)方法步驟
這篇文章主要介紹了mac下設(shè)置redis開機(jī)啟動(dòng),本文詳細(xì)的給出了操作步驟,需要的朋友可以參考下2015-07-07Redis高級(jí)玩法之利用SortedSet實(shí)現(xiàn)多維度排序的方法
Redis的SortedSet是可以根據(jù)score進(jìn)行排序的,以手機(jī)應(yīng)用商店的熱門榜單排序?yàn)槔?,根?jù)下載量倒序排列。接下來通過本文給大家分享Redis高級(jí)玩法之利用SortedSet實(shí)現(xiàn)多維度排序的方法,一起看看吧2019-07-07