欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Redis中過(guò)期鍵刪除的三種方法

 更新時(shí)間:2024年05月19日 09:04:52   作者:物與我皆無(wú)盡也  
Redis中可以設(shè)置鍵的過(guò)期時(shí)間,并且通過(guò)取出過(guò)期字典(expires dict)中鍵的過(guò)期時(shí)間和當(dāng)前時(shí)間比較來(lái)判斷是否過(guò)期,那么一個(gè)過(guò)期的鍵是怎么被刪除的呢?本文給大家總結(jié)了三種方法,選了其中兩種給大家詳細(xì)的介紹一下,需要的朋友可以參考下

Redis中可以設(shè)置鍵的過(guò)期時(shí)間,并且通過(guò)取出過(guò)期字典(expires dict)中鍵的過(guò)期時(shí)間和當(dāng)前時(shí)間比較來(lái)判斷是否過(guò)期。

那么一個(gè)過(guò)期的鍵是怎么被刪除的呢?

定時(shí)刪除

定時(shí)刪除:在設(shè)置鍵的過(guò)期時(shí)間時(shí),創(chuàng)建一個(gè)定時(shí)器(timer),讓定時(shí)器在鍵的過(guò)期時(shí)間來(lái)臨時(shí),立即執(zhí)行對(duì)鍵的刪除操作。

這是對(duì)內(nèi)存最友好的,因?yàn)樗ㄟ^(guò)定時(shí)器保證了過(guò)期即會(huì)刪除,并釋放過(guò)期鍵占用的內(nèi)存。但是這是對(duì)CPU最不友好的,在過(guò)期鍵比較多的情況下,刪除大量過(guò)期鍵會(huì)占用相當(dāng)一部分CPU時(shí)間,會(huì)對(duì)服務(wù)器的的響應(yīng)時(shí)間和吞吐量造成影響。

如果服務(wù)器當(dāng)前不缺少內(nèi)存,那么服務(wù)器應(yīng)該優(yōu)先將CPU時(shí)間用在處理客戶端的命令請(qǐng)求上面,而不是用在刪除過(guò)期鍵上面。
而且,創(chuàng)建一個(gè)定時(shí)器需要用到Redis服務(wù)器中的時(shí)間事件,而其實(shí)現(xiàn)方式是無(wú)序鏈表,所以查找一個(gè)事件的時(shí)間復(fù)雜度為O(N),并不能高效地處理大量時(shí)間事件。

惰性刪除

惰性刪除:放任鍵過(guò)期不管,但是每次從鍵空間中獲取鍵時(shí),都檢查取得的鍵是否過(guò)期,如果過(guò)期的話,就刪除該鍵;如果沒(méi)有過(guò)期,就返回該鍵。

惰性刪除策略對(duì)CPU時(shí)間來(lái)說(shuō)是最友好的:程序只會(huì)在取出鍵時(shí)才對(duì)鍵進(jìn)行過(guò)期檢查。但它對(duì)內(nèi)存是最不友好的,如果一個(gè)鍵已經(jīng)過(guò)期,那么只要這個(gè)過(guò)期鍵不被訪問(wèn),它所占用的內(nèi)存就不會(huì)釋放。(甚至可以將這種情況看作是一種內(nèi)存泄漏,這對(duì)于運(yùn)行狀態(tài)非常依賴于內(nèi)存的Redis服務(wù)器來(lái)說(shuō),肯定不是一個(gè)好消息)

定期刪除

定期刪除:每隔一段時(shí)間,程序就對(duì)數(shù)據(jù)庫(kù)進(jìn)行一次檢查,刪除里面的過(guò)期鍵。至于要?jiǎng)h除多少過(guò)期鍵,以及要檢查多少個(gè)數(shù)據(jù)庫(kù),則由算法決定。

定期刪除策略是前兩種策略的一種整合和折中,它的難點(diǎn)是確定刪除操作執(zhí)行的時(shí)長(zhǎng)和頻率:

  • 如果刪除操作執(zhí)行得太頻繁,或者執(zhí)行的時(shí)間太長(zhǎng),定期刪除策略就會(huì)退化成定時(shí)
    刪除策略,以至于將CPU時(shí)間過(guò)多地消耗在刪除過(guò)期鍵上面。
  • 如果刪除操作執(zhí)行得太少,或者執(zhí)行的時(shí)間太短,定期刪除策略又會(huì)和惰性刪除策
    略一樣,出現(xiàn)浪費(fèi)內(nèi)存的情況

因此,如果采用定期刪除策略的話,服務(wù)器必須根據(jù)情況合理地設(shè)置刪除操作的執(zhí)行時(shí)長(zhǎng)和執(zhí)行頻率。

Redis的實(shí)現(xiàn)

Redis 選擇「惰性刪除+定期刪除」這兩種策略配和使用

惰性刪除

惰性刪除策略由db.c/expireIfNeeded函數(shù)實(shí)現(xiàn),所有讀寫數(shù)據(jù)庫(kù)的Redis命令在執(zhí)行之前都會(huì)調(diào)用expireIfNeeded函數(shù)對(duì)輸入鍵進(jìn)行檢查:如果輸人鍵已經(jīng)過(guò)期,那么將輸人鍵從數(shù)據(jù)庫(kù)中刪除;如果輸人鍵未過(guò)期,則不做動(dòng)作。

Redis 的惰性刪除策略由db.c文件中的 expireIfNeeded 函數(shù)實(shí)現(xiàn),代碼如下:

int expireIfNeeded(redisDb *db, robj *key) {
    // 判斷 key 是否過(guò)期
    if (!keyIsExpired(db,key)) 
        return 0;

    // 刪除過(guò)期鍵 
    // 如果 server.lazyfree_lazy_expire 為 1 表示異步刪除,反之同步刪除;
    return server.lazyfree_lazy_expire ? dbAsyncDelete(db,key) :
                                         dbSyncDelete(db,key);
}

Redis 在訪問(wèn)或者修改 key 之前,都會(huì)調(diào)用 expireIfNeeded 函數(shù)對(duì)其進(jìn)行檢查,檢查 key 是否過(guò)期:

  • 如果過(guò)期,則刪除該 key,至于選擇異步刪除,還是選擇同步刪除,根據(jù) lazyfree_lazy_expire 參數(shù)配置決定(Redis 4.0版本開(kāi)始提供參數(shù)),然后返回 null 客戶端
  • 如果沒(méi)有過(guò)期,正常處理指令

定期刪除

在 Redis 中,默認(rèn)每秒進(jìn)行 10 次過(guò)期檢查一次數(shù)據(jù)庫(kù),此配置可通過(guò) Redis 的配置文件 redis.conf 進(jìn)行配置(hz),它的默認(rèn)值是10。

過(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ù),從數(shù)據(jù)庫(kù)的過(guò)期字典(expires dict)中隨機(jī)檢查一部分鍵的過(guò)期時(shí)間,并刪除其中的過(guò)期鍵。

過(guò)程用偽代碼表示為:

#代碼來(lái)自《Redis設(shè)計(jì)與實(shí)現(xiàn)》,版本是Redis 2.9。跟新版redis應(yīng)該有所偏差

#默認(rèn)每次檢查的數(shù)據(jù)庫(kù)數(shù)量
DEFAULT_ DB_ NUMBERS = 16
#默認(rèn)每個(gè)數(shù)據(jù)庫(kù)檢查的鍵數(shù)量
DEFAULT KEY_ NUMBERS = 20
#全局變量,記錄檢查進(jìn)度.
current_ db = 0

def activeExpireCycle() :
    #遍歷各個(gè)數(shù)據(jù)庫(kù)
    for i in range (db_numbers) :
        #已經(jīng)遍歷一輪,將current_ db重置為0,開(kāi)始新的一輪遍歷
        if current_db == server.dbnum:
            current_db = 0
            
        #獲取當(dāng)前要處理的數(shù)據(jù)庫(kù)
        redisDb = server.db[current__db]
        #將數(shù)據(jù)庫(kù)索引增1,指向下一個(gè)要處理的數(shù)據(jù)庫(kù)
        current_db += 1
        
        #檢查數(shù)據(jù)庫(kù)鍵
        for j in range (DEFAULT_KEY_NUMBERS) :
            #如果數(shù)據(jù)庫(kù)中沒(méi)有一個(gè)鍵帶有過(guò)期時(shí)間,那么跳過(guò)這個(gè)數(shù)據(jù)庫(kù)
            if redisDb.expires.size() == 0: 
                break
                
            #隨機(jī)獲取一個(gè)帶有過(guò)期時(shí)間的鍵
        	key_with_ttl = redisDb.expires.get_random_key ()
            #檢查鍵是否過(guò)期,如果過(guò)期就刪除它.
            if is_expired(key_with_ttl) :
            	delete_key(key_with_ttl)
            
            #已達(dá)到時(shí)間上限,停止處理
            if reach_time_limit() : return

總的來(lái)說(shuō)就是,定期刪除會(huì)在規(guī)定時(shí)間(時(shí)間不超過(guò)上限,25ms)內(nèi)依次遍歷所有數(shù)據(jù)庫(kù),對(duì)于每個(gè)數(shù)據(jù)庫(kù)會(huì)依次隨機(jī)獲取20個(gè)鍵并刪除過(guò)期的鍵,如果過(guò)期鍵超過(guò)25%會(huì)繼續(xù)隨機(jī)獲取20個(gè)鍵。

以上就是Redis中過(guò)期鍵刪除的三種方法的詳細(xì)內(nèi)容,更多關(guān)于Redis過(guò)期鍵刪除的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Redis實(shí)現(xiàn)接口防抖的示例代碼

    Redis實(shí)現(xiàn)接口防抖的示例代碼

    本文介紹了一種通過(guò)AOP、自定義注解和Redis實(shí)現(xiàn)的接口防抖技術(shù),這種方法能有效避免因網(wǎng)絡(luò)波動(dòng)等原因短時(shí)間內(nèi)發(fā)送多個(gè)請(qǐng)求導(dǎo)致的數(shù)據(jù)重復(fù)添加問(wèn)題,感興趣的可以了解一下
    2024-10-10
  • redis搭建哨兵集群的實(shí)現(xiàn)步驟

    redis搭建哨兵集群的實(shí)現(xiàn)步驟

    本文主要介紹了redis搭建哨兵集群的實(shí)現(xiàn)步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • Redis高并發(fā)情況下并發(fā)扣減庫(kù)存項(xiàng)目實(shí)戰(zhàn)

    Redis高并發(fā)情況下并發(fā)扣減庫(kù)存項(xiàng)目實(shí)戰(zhàn)

    本文主要介紹了Redis高并發(fā)情況下并發(fā)扣減庫(kù)存項(xiàng)目實(shí)戰(zhàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04
  • 啟動(dòng)redis出現(xiàn)閃退情況的解決辦法

    啟動(dòng)redis出現(xiàn)閃退情況的解決辦法

    最近使用Redis遇到啟動(dòng)閃退的問(wèn)題,查閱資料后在一位大神的文章中找到了答案,這篇文章主要給大家介紹了關(guān)于啟動(dòng)redis出現(xiàn)閃退情況的解決辦法,需要的朋友可以參考下
    2023-11-11
  • Redis2.8配置文件中文詳解

    Redis2.8配置文件中文詳解

    這篇文章主要介紹了Redis2.8配置文件中文詳解,本文提供的是是Redis2.8.9的配置文件各項(xiàng)的中文解釋,需要的朋友可以參考下
    2015-06-06
  • Redis Key的數(shù)量上限及優(yōu)化策略分享

    Redis Key的數(shù)量上限及優(yōu)化策略分享

    Redis 作為高性能的鍵值存儲(chǔ)數(shù)據(jù)庫(kù),廣泛應(yīng)用于緩存、會(huì)話存儲(chǔ)、排行榜等場(chǎng)景,但在實(shí)際使用中,開(kāi)發(fā)者常常會(huì)關(guān)心一個(gè)問(wèn)題:Redis 的 Key 數(shù)量是否有上限?本文將從 Redis Key 的理論上限 出發(fā),深入探討 Redis Key 的管理策略,需要的朋友可以參考下
    2025-03-03
  • Redis高可用之持久化

    Redis高可用之持久化

    在web服務(wù)器中,高可用是指服務(wù)器可以正常訪問(wèn)的時(shí)間,衡量的標(biāo)準(zhǔn)是在多長(zhǎng)時(shí)間內(nèi)可以提供正常服務(wù)(99.9%、99.99%、99.999%等等),Redis中,實(shí)現(xiàn)高可用的技術(shù)主要包括持久化、主從復(fù)制、哨兵和cluster集群,感興趣的同學(xué)可以閱讀本文
    2023-04-04
  • Redis全局ID生成器的實(shí)現(xiàn)

    Redis全局ID生成器的實(shí)現(xiàn)

    全局ID生成器,是一種在分布式系統(tǒng)下用來(lái)生成全局唯一ID的工具,本文主要介紹了Redis全局ID生成器的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-06-06
  • redis keys與scan命令的區(qū)別說(shuō)明

    redis keys與scan命令的區(qū)別說(shuō)明

    這篇文章主要介紹了redis keys與scan命令的區(qū)別說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-03-03
  • 關(guān)于redis Key淘汰策略的實(shí)現(xiàn)方法

    關(guān)于redis Key淘汰策略的實(shí)現(xiàn)方法

    下面小編就為大家?guī)?lái)一篇關(guān)于redis Key淘汰策略的實(shí)現(xiàn)方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-03-03

最新評(píng)論