最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳細(xì)聊聊Redis的過(guò)期策略

 更新時(shí)間:2022年01月05日 10:59:39   作者:牛逼程序員  
redis 過(guò)期策略是定期刪除+惰性刪除,下面這篇文章主要給大家介紹了關(guān)于Redis過(guò)期策略的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下

保存過(guò)期時(shí)間

Redis可以為每個(gè)key設(shè)置過(guò)期時(shí)間,會(huì)將每個(gè)設(shè)置了過(guò)期時(shí)間的key放入一個(gè)獨(dú)立的字典中。

typedef struct redisDb { 
int id; //id是數(shù)據(jù)庫(kù)序號(hào),為0-15(默認(rèn)Redis有16個(gè)數(shù)據(jù)庫(kù)) 
long avg_ttl; //存儲(chǔ)的數(shù)據(jù)庫(kù)對(duì)象的平均ttl(time to live),用于統(tǒng)計(jì) 
dict *dict; //存儲(chǔ)數(shù)據(jù)庫(kù)所有的key-value 
dict *expires; //存儲(chǔ)key的過(guò)期時(shí)間 
dict *blocking_keys;//blpop 存儲(chǔ)阻塞key和客戶端對(duì)象 
dict *ready_keys;//阻塞后push 響應(yīng)阻塞客戶端 存儲(chǔ)阻塞后push的key和客戶端對(duì)象 dict *watched_keys;//存儲(chǔ)watch監(jiān)控的的key和客戶端對(duì)象 
} redisDb;

dict 用來(lái)維護(hù)一個(gè) Redis 數(shù)據(jù)庫(kù)中包含的所有 Key-Value 鍵值對(duì),expires則用于維護(hù)一個(gè) Redis 數(shù)據(jù)庫(kù)中設(shè)置了失效時(shí)間的鍵(即key與失效時(shí)間的映射)。注意這里的失效時(shí)間是用毫秒的時(shí)間戳表示的,比如2022-01-02 22:45:02過(guò)期則value為1641134702000

當(dāng)我們使用expire命令設(shè)置一個(gè)key的失效時(shí)間時(shí),Redis 首先到 dict 這個(gè)字典表中查找要設(shè)置的key是否存在,如果存在就將這個(gè)key和失效時(shí)間添加到 expires 這個(gè)字典表。

當(dāng)我們使用setex命令向系統(tǒng)插入數(shù)據(jù)時(shí),Redis 首先將 Key 和 Value 添加到 dict 這個(gè)字典表中,然后將 Key 和失效時(shí)間添加到 expires 這個(gè)字典表中。注意setex只能用于字符串。

簡(jiǎn)單地總結(jié)來(lái)說(shuō)就是,設(shè)置了失效時(shí)間的key和具體的失效時(shí)間全部都維護(hù)在 expires 這個(gè)字典表中。

設(shè)置過(guò)期時(shí)間

expire的使用

expire命令的使用方法如下: expire key ttl(單位秒)

127.0.0.1:6379> expire name 2 #2秒失效 
(integer) 1 
127.0.0.1:6379> get name 
(nil) 
127.0.0.1:6379> set name zhangfei 
OK 
127.0.0.1:6379> ttl name #永久有效 
(integer) -1 
127.0.0.1:6379> expire name 30 #30秒失效 
(integer) 1 
127.0.0.1:6379> ttl name #還有24秒失效 
(integer) 24 
127.0.0.1:6379> ttl name #失效 
(integer) -2

Redis有四個(gè)不同的命令可以用于設(shè)置鍵的生存時(shí)間(鍵可以生存多久)或過(guò)期時(shí)間(鍵什么時(shí)候會(huì)被刪除):

expire 命令用于將鍵key的生存時(shí)間設(shè)置為ttl

pexpire 命令用于將鍵key的生存時(shí)間設(shè)置為ttl毫秒

expireat 命令用于將鍵key的過(guò)期時(shí)間設(shè)置為timestamp所指定的數(shù)時(shí)間戳

pexpireat 命令用于將鍵key的過(guò)期時(shí)間設(shè)置為timestamp所指定的毫秒數(shù)時(shí)間戳

注意expire、pexpire、expireat最終實(shí)現(xiàn)都是通過(guò)pexpireat實(shí)現(xiàn)的,也就是說(shuō)無(wú)論客戶端執(zhí)行哪個(gè)命令,都會(huì)Redis都會(huì)轉(zhuǎn)換成pexpireat命令執(zhí)行。所以expires字典中存的時(shí)間是用毫秒時(shí)間戳表示的鍵的過(guò)期時(shí)間。

過(guò)期策略

如果一個(gè)鍵過(guò)期了,那什么時(shí)候被刪除呢?

有三種過(guò)期策略

  • 定時(shí)刪除:在設(shè)置鍵的過(guò)期時(shí)間的同時(shí),創(chuàng)建一個(gè)定時(shí)器,讓定時(shí)器在鍵的過(guò)期時(shí)間來(lái)臨時(shí),立即執(zhí)行對(duì)鍵的刪除操作。(創(chuàng)建定時(shí)器刪除
  • 惰性刪除:放任鍵的過(guò)期不管,但是每次從鍵空間中獲取鍵時(shí),都檢查取得的鍵是否過(guò)期,如果過(guò)期的話,就刪除該鍵;如果沒(méi)有過(guò)期,就返回該鍵。(使用的時(shí)候刪除
  • 定期刪除:每隔一段時(shí)間,程序就對(duì)數(shù)據(jù)庫(kù)進(jìn)行一次檢查,刪除里面過(guò)期的鍵。至于要?jiǎng)h除多少過(guò)期鍵,以及要檢查多少個(gè)數(shù)據(jù)庫(kù),則有算法決定。(定期掃描刪除

定時(shí)刪除

  • 優(yōu)點(diǎn)

1、對(duì)內(nèi)存最友好:通過(guò)使用定時(shí)器,可以保證過(guò)期的鍵會(huì)盡可能快地被刪除,釋放所占內(nèi)存

  • 缺點(diǎn)

1、對(duì)cpu最不友好:在過(guò)期鍵比較多的情況下,刪除過(guò)期鍵這一行為可能會(huì)占用相當(dāng)一部分cpu的時(shí)間,對(duì)服務(wù)器的響應(yīng)時(shí)間和吞吐量造成影響。

惰性刪除

  • 優(yōu)點(diǎn)

1、對(duì)cpu最友好:只有在取出鍵的時(shí)候才會(huì)對(duì)過(guò)期鍵進(jìn)行檢查,即不需要cpu定期掃描,也不需要?jiǎng)?chuàng)建大量的定時(shí)器。

  • 缺點(diǎn)

1、對(duì)內(nèi)存最不友好:如果一個(gè)鍵已經(jīng)過(guò)期,但是后面不會(huì)被訪問(wèn)到的話,那么就一直保留在數(shù)據(jù)庫(kù)中。如果這樣的鍵過(guò)多,無(wú)疑會(huì)占用很大的內(nèi)存。

定期刪除

定期刪除是上面的定時(shí)刪除和惰性刪除的一中折中方案。

  • 優(yōu)點(diǎn)

1、定期刪除每隔一段時(shí)間執(zhí)行一次過(guò)期鍵操作,并通過(guò)限制刪除操作執(zhí)行的時(shí)長(zhǎng)和頻率來(lái)減少刪除操作對(duì)cpu時(shí)間的影響。

2、通過(guò)刪除過(guò)期鍵,能有效的減少因?yàn)檫^(guò)期鍵而帶來(lái)的內(nèi)存浪費(fèi)

  • 缺點(diǎn) 難以確定刪除操作執(zhí)行的時(shí)長(zhǎng)和頻率

1、如果刪除操作執(zhí)行得太頻繁,或者執(zhí)行的時(shí)間太長(zhǎng),定期刪除策略就會(huì)退化成定時(shí)刪除,以至于占用太多cpu的執(zhí)行時(shí)間。

2、如果刪除操作執(zhí)行的時(shí)間太少,或執(zhí)行時(shí)間太短,定期刪除策略又會(huì)和惰性刪除一樣,出現(xiàn)內(nèi)存浪費(fèi)。

Redis的過(guò)期策略

Redis使用是惰性刪除定期刪除兩種策略:通過(guò)配好使用這兩種策略,服務(wù)器可以很好地在合理使用cpu時(shí)間和避免浪費(fèi)內(nèi)存空間之間取得平衡。

惰性刪除策略的實(shí)現(xiàn)

過(guò)期鍵的惰性刪除刪除策略由db.c/expireIfNeeded函數(shù)實(shí)現(xiàn),所有讀寫(xiě)數(shù)據(jù)庫(kù)的Redis命令在執(zhí)行之前都會(huì)調(diào)用expireIfNeed函數(shù)對(duì)輸入鍵進(jìn)行檢查:

  • 如果鍵已經(jīng)過(guò)期,那么expireIfNeeded函數(shù)將鍵刪除
  • 如果鍵未過(guò)期,那么expireIfNeeded函數(shù)不做操作

命令調(diào)用expireIfNeeded函數(shù)過(guò)程如下圖

image.png

另外因?yàn)槊總€(gè)被訪問(wèn)的鍵都可能被刪除,所以每個(gè)命令都必須能同時(shí)處理鍵存在以及不存在的情況。 下圖表示get命令的執(zhí)行過(guò)程

image.png

定期刪除策略的實(shí)現(xiàn)

過(guò)期鍵的定期刪除策略由redis.c/activeExpireCycle函數(shù)實(shí)現(xiàn),每當(dāng)Redis的服務(wù)器周期性操作redis.c/serverCron函數(shù)執(zhí)行時(shí),activeExpireCycle函數(shù)就會(huì)被調(diào)用,它在規(guī)定時(shí)間內(nèi),分多次遍歷服務(wù)器中各個(gè)數(shù)據(jù)庫(kù)。

Redis 默認(rèn)每秒進(jìn)行 10 次過(guò)期掃描,過(guò)期掃描不會(huì)遍歷過(guò)期字典中所有的 key, 而是采用了一種簡(jiǎn)單的貪心策略,步驟如下。

(1)從過(guò)期字典中隨機(jī)選出 20個(gè) key。

(2)刪除這 20 個(gè) key 中已經(jīng)過(guò)期的 key。

(3)如果過(guò)期的 key的比例超過(guò) 1/4,那就重復(fù)步驟 (1)。 同時(shí),為了保證過(guò)期掃描不會(huì)出現(xiàn)循環(huán)過(guò)度,導(dǎo)致結(jié)程卡死的現(xiàn)象,算法還增加了掃描時(shí)間的上限,默認(rèn)不會(huì)超過(guò) 25ms。

假設(shè)一個(gè)大型的 Redis 實(shí)例中所有的 key 在同一時(shí)間過(guò)期了,會(huì)出現(xiàn)怎樣的結(jié)果呢?

消耗cpu

Redis 會(huì)持續(xù)掃描過(guò)期字典(循環(huán)多次),直到過(guò)期字典中過(guò)期的key變得稀疏,才會(huì)停止(循環(huán)次數(shù)明顯下降)。

導(dǎo)致請(qǐng)求卡頓或超時(shí)

當(dāng)客戶端請(qǐng)求到來(lái)時(shí),服務(wù)器如果正好進(jìn)入過(guò)期掃描狀態(tài),客戶端的請(qǐng)求將會(huì)等待至少 25ms 后才會(huì)進(jìn)行處理,如果客戶端將超時(shí)時(shí)間設(shè)置得比較短,比如 10ms,那么就會(huì)出現(xiàn)大量的連接因?yàn)槌瑫r(shí)而關(guān)閉 ,業(yè)務(wù)端就會(huì)出現(xiàn)很多異常

所以一定要注意過(guò)期時(shí)間,如果有大批量的key過(guò)期,要給過(guò)期時(shí)間設(shè)置一個(gè)隨機(jī)范圍,而不能全部在同一時(shí)間過(guò)期。

參考:

《Redis的設(shè)計(jì)與實(shí)現(xiàn)》

《Redis深度歷險(xiǎn)》

總結(jié)

到此這篇關(guān)于Redis過(guò)期策略的文章就介紹到這了,更多相關(guān)Redis過(guò)期策略內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Redis?哈希Hash底層數(shù)據(jù)結(jié)構(gòu)詳解

    Redis?哈希Hash底層數(shù)據(jù)結(jié)構(gòu)詳解

    這篇文章主要介紹了Redis?哈希Hash底層數(shù)據(jù)結(jié)構(gòu)詳解的相關(guān)資料,需要的朋友可以參考下
    2022-08-08
  • redis延時(shí)隊(duì)列zset實(shí)現(xiàn)的示例

    redis延時(shí)隊(duì)列zset實(shí)現(xiàn)的示例

    延時(shí)隊(duì)列是一種常用的設(shè)計(jì)模式,用于處理那些需要在未來(lái)某個(gè)時(shí)間點(diǎn)執(zhí)行的任務(wù),本文主要介紹了redis延時(shí)隊(duì)列zset實(shí)現(xiàn)的示例,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-08-08
  • redis實(shí)現(xiàn)延遲任務(wù)的項(xiàng)目實(shí)踐

    redis實(shí)現(xiàn)延遲任務(wù)的項(xiàng)目實(shí)踐

    本文主要介紹了redis實(shí)現(xiàn)延遲任務(wù)的項(xiàng)目實(shí)踐,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • Redis處理高并發(fā)機(jī)制原理及實(shí)例解析

    Redis處理高并發(fā)機(jī)制原理及實(shí)例解析

    這篇文章主要介紹了Redis處理高并發(fā)機(jī)制原理及實(shí)例解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值析,需要的朋友可以參考下
    2020-08-08
  • 使用Redis實(shí)現(xiàn)分布式鎖的方法

    使用Redis實(shí)現(xiàn)分布式鎖的方法

    為了保證我們線上服務(wù)的并發(fā)性和安全性,目前我們的服務(wù)一般拋棄了單體應(yīng)用,采用的都是擴(kuò)展性很強(qiáng)的分布式架構(gòu),這篇文章主要介紹了使用Redis實(shí)現(xiàn)分布式鎖的方法,需要的朋友可以參考下
    2022-06-06
  • Redis設(shè)置Hash數(shù)據(jù)類(lèi)型的過(guò)期時(shí)間

    Redis設(shè)置Hash數(shù)據(jù)類(lèi)型的過(guò)期時(shí)間

    在Redis中,我們可以使用Hash數(shù)據(jù)結(jié)構(gòu)來(lái)存儲(chǔ)一組鍵值對(duì),而有時(shí)候,我們可能需要設(shè)置這些鍵值對(duì)的過(guò)期時(shí)間,本文主要介紹了Redis設(shè)置Hash數(shù)據(jù)類(lèi)型的過(guò)期時(shí)間,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-01-01
  • Linux中設(shè)置Redis開(kāi)機(jī)啟動(dòng)的方法

    Linux中設(shè)置Redis開(kāi)機(jī)啟動(dòng)的方法

    這篇文章主要給大家介紹了關(guān)于Linux中設(shè)置Redis開(kāi)機(jī)啟動(dòng)的方法,主要包括在CentOS7.0系統(tǒng)和Debian 8.0系統(tǒng)下實(shí)現(xiàn)方法,文中介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來(lái)一起看看吧。
    2017-04-04
  • redis 存儲(chǔ)對(duì)象的方法對(duì)比分析

    redis 存儲(chǔ)對(duì)象的方法對(duì)比分析

    這篇文章主要介紹了redis 存儲(chǔ)對(duì)象的方法對(duì)比分析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • redis通過(guò)pipeline提升吞吐量的方法

    redis通過(guò)pipeline提升吞吐量的方法

    下面小編就為大家分享一篇redis通過(guò)pipeline提升吞吐量的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-02-02
  • Redis持久化與主從復(fù)制的實(shí)踐

    Redis持久化與主從復(fù)制的實(shí)踐

    這篇文章主要介紹了Redis持久化與主從復(fù)制的實(shí)踐,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04

最新評(píng)論

马边| 玉屏| 合阳县| 南皮县| 百色市| 临夏县| 青浦区| 溧阳市| 保德县| 翁牛特旗| 阿鲁科尔沁旗| 苗栗市| 江门市| 抚顺县| 云林县| 平果县| 桃园县| 余干县| 深州市| 松原市| 靖安县| 昂仁县| 繁昌县| 监利县| 六盘水市| 永丰县| 九龙坡区| 灵石县| 台安县| 潞城市| 房产| 甘泉县| 利川市| 伊春市| 上饶市| 长春市| 萨迦县| 琼结县| 大连市| 衡阳县| 诸暨市|