Redis對(duì)鍵提供生存時(shí)間,在不指定生存時(shí)間時(shí),生存時(shí)間是永久。時(shí)間到期后Redis會(huì)自動(dòng)刪除這個(gè)鍵??梢杂肊XPIRE命令,時(shí)間單位時(shí)秒,如果一個(gè)鍵是被設(shè)為有限的生存時(shí)間,那么在SET key進(jìn)行重新賦值的時(shí)候會(huì)被再次設(shè)為永久:
SET session:captcha sd2a EXPIRE session:captcha 600
取消生存時(shí)間,將鍵的生存時(shí)間設(shè)為永久,是PERSIST:
PERSIST session:captcha
查看一個(gè)鍵的生存時(shí)間用TTL命令,-1表示永久或者以及到期被刪除。
TTL session:captcha
在Redis的INCR,LPUSH,HSET,ZREM等命令時(shí)不會(huì)改變生存時(shí)間的。
(推薦:redis視頻教程)
想要精確到毫米來控制時(shí)間,就需要PEXPIRE即可,使用PTTL查看剩余時(shí)間。
如果想要給定一個(gè)到期的時(shí)間而不是多少秒后到期呢?就需要EXPIREAT和PEXPIREAT。EXPIREAT的參數(shù)是到期時(shí)的時(shí)間戳(秒),PEXPIREAT的參數(shù)是到期時(shí)間是時(shí)間戳(毫秒)
SET session:captcha sd2a EXPIREAT session:captcha 1399902009 PEXPIREAT session:captcha 1399902009000
應(yīng)用場(chǎng)景一:訪問頻率限制:我們限定每個(gè)用戶1分鐘只能瀏覽10個(gè)頁面。偽代碼如下:
$isExists = EXISTS limit:user1:192.168.1.2 if($isExists){ $num = INCR limit:user1:192.168.1.2 if($num > 10){ print '超過限制' exit } }else{ MULTI INCR limit:user1:192.168.1.2 EXPIRE limit:user1:192.168.1.2 60 EXEC }
我們用了事務(wù)的原因是因?yàn)?,加入在?zhí)行了INCR limit:user1:192.168.1.2之后,在執(zhí)行EXPIRE limit:user1:192.168.1.2 60之前,客戶端被關(guān)閉了。那么這個(gè)鍵和值就會(huì)被持久化保存。且該ID終身只能訪問10次了。這就太糟糕了。
應(yīng)用場(chǎng)景二:實(shí)現(xiàn)緩存。計(jì)算一萬名用戶的排行榜,是很耗費(fèi)資源的,那么我們把數(shù)據(jù)在第一次計(jì)算后存進(jìn)一個(gè)key,然后對(duì)這個(gè)key設(shè)置生存時(shí)間。在1個(gè)小時(shí)后生存時(shí)間到期,key被刪除,再次進(jìn)行計(jì)算新排名并保存的一個(gè)臨時(shí)key。我們用偽代碼實(shí)現(xiàn):
//戰(zhàn)斗排行榜 $rank = GET cache:rank:fight if not $rank $rank = 計(jì)算排名() MULTI SET cache:rank:fight $rank EXPIRE cache:rank:fight 3600 EXEC
Redis是內(nèi)存存儲(chǔ)的數(shù)據(jù)庫,假如內(nèi)存被緩存占滿了,Redis會(huì)根據(jù)配置文件來刪除一定的緩存。配置項(xiàng)是Redis的配置文件中的maxmemory參數(shù),單位是字節(jié)。超過這個(gè)限制之后,會(huì)根據(jù)配置文件的maxmemory-policy參數(shù)來刪除不需要的鍵。maxmemory-policy的可選規(guī)則是如下四種:
1、volatile-lru:使用LRU算法刪除一個(gè)鍵(設(shè)置了生存時(shí)間的鍵)。
2、allkey-lru:使用LRU算法刪除一個(gè)鍵。
3、volatile-random:隨即刪除一個(gè)鍵(設(shè)置了生存時(shí)間的鍵)。
4、allkey-random:隨即刪除一個(gè)鍵。
5、volatile-ttl:刪除生存時(shí)間即將過期的一個(gè)鍵。是隨即取出來N個(gè)鍵,然后刪除N個(gè)鍵中即將過期的鍵,而不是遍歷所有的鍵刪除即將過期的。N是幾?配置文件配的。
6、nevication:不刪除,返回錯(cuò)誤。
Redis設(shè)置Key的過期時(shí)間 – EXPIRE命令
EXPIRE key seconds
為給定 key 設(shè)置生存時(shí)間,當(dāng) key 過期時(shí)(生存時(shí)間為 0 ),它會(huì)被自動(dòng)刪除。
在 Redis 中,帶有生存時(shí)間的 key 被稱為『易失的』(volatile)。
生存時(shí)間可以通過使用 DEL 命令來刪除整個(gè) key 來移除,或者被 SET 和 GETSET 命令覆寫(overwrite),這意味著,如果一個(gè)命令只是修改(alter)一個(gè)帶生存時(shí)間的 key 的值而不是用一個(gè)新的 key 值來代替(replace)它的話,那么生存時(shí)間不會(huì)被改變。
比如說,對(duì)一個(gè) key 執(zhí)行 INCR 命令,對(duì)一個(gè)列表進(jìn)行 LPUSH 命令,或者對(duì)一個(gè)哈希表執(zhí)行 HSET 命令,這類操作都不會(huì)修改 key 本身的生存時(shí)間。
另一方面,如果使用 RENAME 對(duì)一個(gè) key 進(jìn)行改名,那么改名后的 key 的生存時(shí)間和改名前一樣。
RENAME 命令的另一種可能是,嘗試將一個(gè)帶生存時(shí)間的 key 改名成另一個(gè)帶生存時(shí)間的another_key ,這時(shí)舊的 another_key (以及它的生存時(shí)間)會(huì)被刪除,然后舊的 key 會(huì)改名為 another_key ,因此,新的 another_key 的生存時(shí)間也和原本的 key 一樣。
使用 PERSIST 命令可以在不刪除 key 的情況下,移除 key 的生存時(shí)間,讓 key 重新成為一個(gè)『持久的』(persistent) key 。
更新生存時(shí)間
可以對(duì)一個(gè)已經(jīng)帶有生存時(shí)間的 key 執(zhí)行 EXPIRE 命令,新指定的生存時(shí)間會(huì)取代舊的生存時(shí)間。
過期時(shí)間的精確度
在 Redis 2.4 版本中,過期時(shí)間的延遲在 1 秒鐘之內(nèi) —— 也即是,就算 key 已經(jīng)過期,但它還是可能在過期之后一秒鐘之內(nèi)被訪問到,而在新的 Redis 2.6 版本中,延遲被降低到 1 毫秒之內(nèi)。
Redis 2.1.3 之前的不同之處
在 Redis 2.1.3 之前的版本中,修改一個(gè)帶有生存時(shí)間的 key 會(huì)導(dǎo)致整個(gè) key 被刪除,這一行為是受當(dāng)時(shí)復(fù)制(replication)層的限制而作出的,現(xiàn)在這一限制已經(jīng)被修復(fù)??捎冒姹荆?/p>
>= 1.0.0
時(shí)間復(fù)雜度:
O(1)
返回值:
設(shè)置成功返回 1 。
當(dāng) key 不存在或者不能為 key 設(shè)置生存時(shí)間時(shí)(比如在低于 2.1.3 版本的 Redis 中你嘗試更新 key 的生存時(shí)間),返回 0 。
redis> SET cache_page "www.google.com" OK redis> EXPIRE cache_page 30 # 設(shè)置過期時(shí)間為 30 秒 (integer) 1 redis> TTL cache_page # 查看剩余生存時(shí)間 (integer) 23 redis> EXPIRE cache_page 30000 # 更新過期時(shí)間 (integer) 1 redis> TTL cache_page (integer) 29996
1、在小于2.1.3的redis版本里,只能對(duì)key設(shè)置一次expire。redis2.1.3和之后的版本里,可以多次對(duì)key使用expire命令,更新key的expire time。
2、redis術(shù)語里面,把設(shè)置了expire time的key 叫做:volatile keys。 意思就是不穩(wěn)定的key。
3、如果對(duì)key使用set或del命令,那么也會(huì)移除expire time。尤其是set命令,這個(gè)在編寫程序的時(shí)候需要注意一下。
4、redis2.1.3之前的老版本里,如果對(duì)volatile keys 做相關(guān)寫入操作(LPUSH,LSET),和其他一些觸發(fā)修改value的操作時(shí),redis會(huì)刪除 該key。
也就是說 :
redis.expire(key,expiration); redis.lpush(key,field,value); redis.get(key) //return null
redis2.1.3之后的版本里面沒有這個(gè)約束,可以任意修改。
redis.set(key,100); redis.expire(key,expiration); redis.incr(key) redis.get(key) //redis2.2.2 return 101; redis<2.1.3 return 1;
5、redis對(duì)過期鍵采用了lazy expiration:在訪問key的時(shí)候判定key是否過期,如果過期,則進(jìn)行過期處理。其次,每秒對(duì)volatile keys 進(jìn)行抽樣測(cè)試,如果有過期鍵,那么對(duì)所有過期key進(jìn)行處理。
更多redis知識(shí)請(qǐng)關(guān)注redis入門教程欄目。
聲明:本網(wǎng)頁內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com