日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

【干货】在Redis中设置了过期时间的Key怎么办?

發(fā)布時(shí)間:2025/3/20 数据库 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【干货】在Redis中设置了过期时间的Key怎么办? 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

熟悉Redis的同學(xué)應(yīng)該知道,Redis的每個(gè)Key都可以設(shè)置一個(gè)過期時(shí)間,當(dāng)達(dá)到過期時(shí)間的時(shí)候,這個(gè)key就會(huì)被自動(dòng)刪除。
在為key設(shè)置過期時(shí)間需要注意的事項(xiàng)

1、 DEL/SET/GETSET等命令會(huì)清除過期時(shí)間

在使用DEL、SET、GETSET等會(huì)覆蓋key對(duì)應(yīng)value的命令操作一個(gè)設(shè)置了過期時(shí)間的key的時(shí)候,會(huì)導(dǎo)致對(duì)應(yīng)的key的過期時(shí)間被清除。

//設(shè)置mykey的過期時(shí)間為300s
127.0.0.1:6379> set mykey hello ex 300
OK
//查看過期時(shí)間
127.0.0.1:6379> ttl mykey
(integer) 294
//使用set命令覆蓋mykey的內(nèi)容
127.0.0.1:6379> set mykey olleh
OK
//過期時(shí)間被清除
127.0.0.1:6379> ttl mykey
(integer) -1
2、INCR/LPUSH/HSET等命令則不會(huì)清除過期時(shí)間

而在使用INCR/LPUSH/HSET這種只是修改一個(gè)key的value,而不是覆蓋整個(gè)value的命令,則不會(huì)清除key的過期時(shí)間。

INCR:

//設(shè)置incr_key的過期時(shí)間為300s
127.0.0.1:6379> set incr_key 1 ex 300
OK
127.0.0.1:6379> ttl incr_key
(integer) 291
//進(jìn)行自增操作
127.0.0.1:6379> incr incr_key
(integer) 2
127.0.0.1:6379> get incr_key
“2”
//查詢過期時(shí)間,發(fā)現(xiàn)過期時(shí)間沒有被清除
127.0.0.1:6379> ttl incr_key
(integer) 277
LPUSH:

//新增一個(gè)list類型的key,并添加一個(gè)為1的值
127.0.0.1:6379> LPUSH list 1
(integer) 1
//為list設(shè)置300s的過期時(shí)間
127.0.0.1:6379> expire list 300
(integer) 1
//查看過期時(shí)間
127.0.0.1:6379> ttl list
(integer) 292
//往list里面添加值2
127.0.0.1:6379> lpush list 2
(integer) 2
//查看list的所有值
127.0.0.1:6379> lrange list 0 1

  • “2”
  • “1”
    //能看到往list里面添加值并沒有使過期時(shí)間清除
    127.0.0.1:6379> ttl list
    (integer) 252
    3、PERSIST命令會(huì)清除過期時(shí)間
  • 當(dāng)使用PERSIST命令將一個(gè)設(shè)置了過期時(shí)間的key轉(zhuǎn)變成一個(gè)持久化的key的時(shí)候,也會(huì)清除過期時(shí)間。

    127.0.0.1:6379> set persist_key haha ex 300
    OK
    127.0.0.1:6379> ttl persist_key
    (integer) 296
    //將key變?yōu)槌志没?br /> 127.0.0.1:6379> persist persist_key
    (integer) 1
    //過期時(shí)間被清除
    127.0.0.1:6379> ttl persist_key
    (integer) -1
    4、使用RENAME命令,老key的過期時(shí)間將會(huì)轉(zhuǎn)到新key上

    在使用例如:RENAME KEY_A KEY_B命令將KEY_A重命名為KEY_B,不管KEY_B有沒有設(shè)置過期時(shí)間,新的key KEY_B將會(huì)繼承KEY_A的所有特性。

    //設(shè)置key_a的過期時(shí)間為300s
    127.0.0.1:6379> set key_a value_a ex 300
    OK
    //設(shè)置key_b的過期時(shí)間為600s
    127.0.0.1:6379> set key_b value_b ex 600
    OK
    127.0.0.1:6379> ttl key_a
    (integer) 279
    127.0.0.1:6379> ttl key_b
    (integer) 591
    //將key_a重命名為key_b
    127.0.0.1:6379> rename key_a key_b
    OK
    //新的key_b繼承了key_a的過期時(shí)間
    127.0.0.1:6379> ttl key_b
    (integer) 248
    這里篇幅有限,我就不一一將key_a重命名到key_b的各個(gè)情況列出來,大家可以在自己電腦上試一下key_a設(shè)置了過期時(shí)間,key_b沒設(shè)置過期時(shí)間這種情況。

    5、使用EXPIRE/PEXPIRE設(shè)置的過期時(shí)間為負(fù)數(shù)或者使用EXPIREAT/PEXPIREAT設(shè)置過期時(shí)間戳為過去的時(shí)間會(huì)導(dǎo)致key被刪除

    EXPIRE:

    127.0.0.1:6379> set key_1 value_1
    OK
    127.0.0.1:6379> get key_1
    “value_1”
    //設(shè)置過期時(shí)間為-1
    127.0.0.1:6379> expire key_1 -1
    (integer) 1
    //發(fā)現(xiàn)key被刪除
    127.0.0.1:6379> get key_1
    (nil)
    EXPIREAT:

    127.0.0.1:6379> set key_2 value_2
    OK
    127.0.0.1:6379> get key_2
    “value_2”
    //設(shè)置的時(shí)間戳為過去的時(shí)間
    127.0.0.1:6379> expireat key_2 10000
    (integer) 1
    //key被刪除
    127.0.0.1:6379> get key_2
    (nil)
    6、EXPIRE命令可以更新過期時(shí)間

    對(duì)一個(gè)已經(jīng)設(shè)置了過期時(shí)間的key使用expire命令,可以更新其過期時(shí)間。

    //設(shè)置key_1的過期時(shí)間為100s
    127.0.0.1:6379> set key_1 value_1 ex 100
    OK
    127.0.0.1:6379> ttl key_1
    (integer) 95
    //更新key_1的過期時(shí)間為300s
    127.0.0.1:6379> expire key_1 300
    (integer) 1
    127.0.0.1:6379> ttl key_1
    (integer) 295
    在Redis2.1.3以下的版本中,使用expire命令更新一個(gè)已經(jīng)設(shè)置了過期時(shí)間的key的過期時(shí)間會(huì)失敗。并且對(duì)一個(gè)設(shè)置了過期時(shí)間的key使用LPUSH/HSET等命令修改其value的時(shí)候,會(huì)導(dǎo)致Redis刪除該key。

    Redis的過期策略

    那你有沒有想過一個(gè)問題,Redis里面如果有大量的key,怎樣才能高效的找出過期的key并將其刪除呢,難道是遍歷每一個(gè)key嗎?假如同一時(shí)期過期的key非常多,Redis會(huì)不會(huì)因?yàn)橐恢碧幚磉^期事件,而導(dǎo)致讀寫指令的卡頓。

    這里說明一下,Redis是單線程的,所以一些耗時(shí)的操作會(huì)導(dǎo)致Redis卡頓,比如當(dāng)Redis數(shù)據(jù)量特別大的時(shí)候,使用keys * 命令列出所有的key。

    實(shí)際上Redis使用懶惰刪除+定期刪除相結(jié)合的方式處理過期的key。

    懶惰刪除

    所謂懶惰刪除就是在客戶端訪問該key的時(shí)候,redis會(huì)對(duì)key的過期時(shí)間進(jìn)行檢查,如果過期了就立即刪除。

    這種方式看似很完美,在訪問的時(shí)候檢查key的過期時(shí)間,不會(huì)占用太多的額外CPU資源。但是如果一個(gè)key已經(jīng)過期了,如果長(zhǎng)時(shí)間沒有被訪問,那么這個(gè)key就會(huì)一直存留在內(nèi)存之中,嚴(yán)重消耗了內(nèi)存資源。

    定期刪除

    定期刪除的原理是,Redis會(huì)將所有設(shè)置了過期時(shí)間的key放入一個(gè)字典中,然后每隔一段時(shí)間從字典中隨機(jī)一些key檢查過期時(shí)間并刪除已過期的key。

    Redis默認(rèn)每秒進(jìn)行10次過期掃描:

    從過期字典中隨機(jī)20個(gè)key
    刪除這20個(gè)key中已過期的
    如果超過25%的key過期,則重復(fù)第一步
    同時(shí),為了保證不出現(xiàn)循環(huán)過度的情況,Redis還設(shè)置了掃描的時(shí)間上限,默認(rèn)不會(huì)超過25ms。

    參考資料

    https://redis.io/commands/expire#expire-accuracy

    《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

    總結(jié)

    以上是生活随笔為你收集整理的【干货】在Redis中设置了过期时间的Key怎么办?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。