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

Redis 過期鍵刪除策略的實(shí)現(xiàn)示例

 更新時(shí)間:2024年03月19日 09:14:58   作者:lordky  
Redis的過期數(shù)據(jù)刪除策略主要有三種,包括定時(shí)刪除、惰性刪除和定期刪除,本文主要介紹了Redis 過期鍵刪除策略的實(shí)現(xiàn)示例,具有一定的參考價(jià)值,感興趣的可以了解一下

(一)關(guān)于鍵的過期時(shí)間或生存時(shí)間

我們知道,Redis數(shù)據(jù)庫是基于內(nèi)存的,但是如果一些不用的鍵在內(nèi)存中一直存在,那么久而久之,就有可能會發(fā)生oom的情況。所以,redis數(shù)據(jù)庫提供了常用的EXPIRE命令或者PEXPIRE命令,用戶可以使用這兩個(gè)命令以秒或者毫秒為精度為數(shù)據(jù)庫中的某個(gè)鍵設(shè)置生存時(shí)間。在經(jīng)過指定的時(shí)間后,redis服務(wù)器就會自動刪除生存時(shí)間為0的鍵。

可以設(shè)置鍵的生存時(shí)間的命令如下:

  • EXPIRE  <key>  <ttl>
    該命令用于將鍵Key的生存時(shí)間設(shè)置為ttl秒
  • PEXPIRE  <key>  <ttl>
    該命令用于將鍵Key的生存時(shí)間設(shè)置為ttl毫秒
  • EXPIREAT  <key>  <timstamp>
    該命令用于將鍵Key的生存時(shí)間設(shè)置為timstamp所指定的秒數(shù)時(shí)間戳
  • PEXPIREAT <key>  <timstamp>
    該命令用于將鍵Key的生存時(shí)間設(shè)置為timstamp所指定的毫秒數(shù)時(shí)間戳。

雖然有四種不同的命令用于指定過期時(shí)間,但是實(shí)際上,無論使用哪一種命令,最終都會轉(zhuǎn)換為PEXPIREAT命令來執(zhí)行

那么,redis是如何存儲過期時(shí)間的呢?

typedef struct redisDb {
    dict *dict;                 /* The keyspace for this DB */
    dict *expires;              /* Timeout of keys with a timeout set */
    dict *blocking_keys;        /* Keys with clients waiting for data (BLPOP)*/
    dict *ready_keys;           /* Blocked keys that received a PUSH */
    dict *watched_keys;         /* WATCHED keys for MULTI/EXEC CAS */
    int id;                     /* Database ID */
    long long avg_ttl;          /* Average TTL, just for stats */
    unsigned long expires_cursor; /* Cursor of the active expire cycle. */
    list *defrag_later;         /* List of key names to attempt to defrag one by one, gradually. */
} redisDb;

我們可以通過以上源碼看出,redisDb結(jié)構(gòu)的expires這個(gè)字典保存了數(shù)據(jù)庫中所有的過期時(shí)間,我們叫這個(gè)字典為過期字典。

每當(dāng)我們?yōu)橐粋€(gè)數(shù)據(jù)庫的某一個(gè)鍵添加過期時(shí)間就會在該字典中添加一個(gè)鍵值對,鍵為這個(gè)需要添加過期時(shí)間的鍵,值為過期時(shí)間的時(shí)間戳。相反,如果刪除一個(gè)鍵的過期時(shí)間,也會相應(yīng)的操作這個(gè)字典,刪除該鍵對應(yīng)的過期時(shí)間鍵值對。如圖所示:

在這里插入圖片描述

(二)過期刪除策略

我們知道了,redis數(shù)據(jù)庫如何設(shè)置,如何存儲過期時(shí)間。那么這現(xiàn)在的問題是,如果一個(gè)鍵過期了,那么什么時(shí)候被刪除呢?

關(guān)于這個(gè)問題,可以實(shí)現(xiàn)的有一下三種方案(redis只采用了其中兩種):

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

下面我們來瞅瞅這三種策略的優(yōu)缺點(diǎn):

1.定時(shí)刪除

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

這種刪除策略對于內(nèi)存來說是友好的,因?yàn)檫@種刪除方式可以保證過期的鍵盡可能快的被刪除掉,并釋放過期鍵所占用的內(nèi)存

缺點(diǎn):

1.這種刪除策略對CPU時(shí)間不友好,在過期鍵比較多的情況下,刪除過期鍵這一行為可能會占用相當(dāng)一部分的CPU時(shí)間,在內(nèi)存不緊張的但是CPU時(shí)間緊張的情況下,這無疑會對服務(wù)器的響應(yīng)時(shí)間和吞吐量造成影響。

2.創(chuàng)建一個(gè)定時(shí)器需要用到redis服務(wù)器中的時(shí)間時(shí)間,而當(dāng)前時(shí)間時(shí)間的實(shí)現(xiàn)方式為無序鏈表,查找一個(gè)事件的時(shí)間復(fù)雜度為O(N),所以說,如果采用這種策略,并不能高效的處理大量的時(shí)間事件。

2.惰性刪除

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

這種刪除策略對于CPU來說是友好的,程序只會在取出鍵的時(shí)候才會對鍵進(jìn)行過期檢查,這樣可以保證對鍵的刪除操作僅限于當(dāng)前處理的鍵,這個(gè)策略不會在刪除其他過期的鍵上花費(fèi)任何的時(shí)間

缺點(diǎn)

顯而易見的,這種刪除策略對于內(nèi)存來說是十分不友好的。因?yàn)槿绻罅康倪^期鍵,長期不使用的情況下,就會造成大量的內(nèi)存被無效的鍵占用。我們甚至可以將這中情況看作是內(nèi)存泄露

3.定期刪除

針對定期刪除來說,這種策略實(shí)際上是定時(shí)刪除和惰性刪除這兩種策略的折中和整合。定期刪除策略每隔一段時(shí)間執(zhí)行一次刪除過期鍵操作,并通過限制刪除操作執(zhí)行時(shí)長和頻率來減少刪除操作對CPU時(shí)間的影響。除此之外,通過定期刪除過期鍵,定期刪除策略有效的減少了因?yàn)檫^期鍵而帶來的內(nèi)存浪費(fèi)。

當(dāng)然,這種策略的難點(diǎn)就在于如何確定刪除的時(shí)長和頻率。比如,如果設(shè)定的刪除太頻繁或者執(zhí)行刪除的時(shí)間太長,就直接回退化為定時(shí)刪除。如果刪除的頻率過低或者指定的時(shí)間太短,定期刪除又會和惰性刪除一樣,造成內(nèi)存浪費(fèi)的情況。

(三)Redis采用的過期鍵刪除策略

Redis數(shù)據(jù)庫實(shí)際上采用了兩種刪除策略:定期刪除和惰性刪除。通過這兩種刪除策略的配合使用,服務(wù)器可以很好的在合理使用CPU時(shí)間和避免內(nèi)存空間浪費(fèi)之間取得平衡。

那么,Redis數(shù)據(jù)庫是如何實(shí)現(xiàn)這兩種刪除策略的呢?

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

過期鍵的刪除策略由expireIfNeeded函數(shù)實(shí)現(xiàn),所有讀寫數(shù)據(jù)庫的Redis命令都會在執(zhí)行錢調(diào)用該函數(shù)進(jìn)行檢查。

int expireIfNeeded(redisDb *db, robj *key) {
    if (!keyIsExpired(db,key)) return 0;
    if (server.masterhost != NULL) return 1;
    /* Delete the key */
    server.stat_expiredkeys++;
    propagateExpire(db,key,server.lazyfree_lazy_expire);
    
    notifyKeyspaceEvent(NOTIFY_EXPIRED,
        "expired",key,db->id);
        
    int retval = server.lazyfree_lazy_expire ? dbAsyncDelete(db,key) :
                                               dbSyncDelete(db,key);
    if (retval) signalModifiedKey(NULL,db,key);
    return retval;
}

我們可以看出,如果輸入鍵已經(jīng)過期,那么expireIfNeed函數(shù)將輸入鍵從數(shù)據(jù)庫刪除。如果輸入鍵沒有過期,則不會做其他動作。所以,每個(gè)命令的實(shí)現(xiàn)函數(shù)都必須能同時(shí)處理鍵存在和不存在兩種情況。

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

該策略由activeExpireCycle函數(shù)實(shí)現(xiàn),每當(dāng)服務(wù)器周期性的操作serverCron函數(shù)執(zhí)行的時(shí)候,activeExpireCycle函數(shù)就會被調(diào)用,在規(guī)定的時(shí)間內(nèi),分多次遍歷服務(wù)器中的各個(gè)數(shù)據(jù)庫,從數(shù)據(jù)庫的expires字典中隨你檢查一部分的過期時(shí)間,并刪除其中的過期鍵。具體代碼實(shí)現(xiàn)由于太多,有感興趣可以去看一下,redis6在expire.c中,redis3在redis.c中。

(四)關(guān)于AOF、RDB對過期鍵的處理

1.生成RDB文件

在執(zhí)行SAVE或者BGSAVE命令創(chuàng)建一個(gè)新的RDB文件的時(shí)候,程序會對數(shù)據(jù)庫中的過期鍵進(jìn)行檢查,過期的鍵不會被保存到新創(chuàng)建的RDB文件中。

2.載入RDB文件

載入的時(shí)候分為兩種情況

(1)服務(wù)器以主服務(wù)器運(yùn)行

當(dāng)服務(wù)器以主服務(wù)器運(yùn)行的時(shí)候,會對文件中保存的鍵進(jìn)行檢查,未過期的鍵會被載入到數(shù)據(jù)庫中,而過期的鍵則會被忽略,所以過期鍵對載入RDB文件的主服務(wù)器不會造成影響。

(2)服務(wù)器以從服務(wù)器運(yùn)行。

當(dāng)服務(wù)器以從服務(wù)器運(yùn)行的時(shí)候,會將文件中保存的所有鍵進(jìn)行保存,不論是否過期。但是由于主從服務(wù)器進(jìn)行數(shù)據(jù)同步的時(shí)候,從服務(wù)器的數(shù)據(jù)庫就會被清空,所以一般來講,過期鍵載入RDB文件的從高服務(wù)器也不會造成影響

3.AOF文件的寫入

當(dāng)數(shù)據(jù)庫中某個(gè)鍵已經(jīng)過期,但是它還沒有被惰性刪除或者定期刪除,那么AOF文件不會因?yàn)檫@個(gè)過期鍵而產(chǎn)生任何影響。當(dāng)過期鍵被惰性刪除或者定期刪除之后,程序會向AOF文件追加一條DEL命令進(jìn)行顯示的刪除。

4.AOF文件的重寫:

重寫的時(shí)候程序會對數(shù)據(jù)庫中的鍵進(jìn)行檢查,已過期的鍵不會被保存到重寫后的AOF文件中

這里有一個(gè)有意思的東西,當(dāng)服務(wù)器運(yùn)行在主從復(fù)制模式下的時(shí)候,從服務(wù)器的過期鍵刪除動作是由主服務(wù)器控制的。

主服務(wù)器在刪除一個(gè)過期鍵后,會顯示的向所有從服務(wù)器發(fā)送一個(gè)DEL命令,命令從服務(wù)器刪除這個(gè)鍵;

從服務(wù)器在執(zhí)行客戶端發(fā)送的命令的時(shí)候,即使遇到過期的鍵也不會將過期的鍵進(jìn)行刪除,是繼續(xù)像處理未過期的鍵一樣來處理過期鍵;

從服務(wù)器只有在接到主服務(wù)器發(fā)送來的DEL命令的時(shí)候才會刪除過期鍵。

到此這篇關(guān)于Redis 過期鍵刪除策略的實(shí)現(xiàn)示例的文章就介紹到這了,更多相關(guān)Redis 過期鍵刪除內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Redis配置文件代碼講解

    Redis配置文件代碼講解

    在本篇文章里小編給大家整理的是一篇關(guān)于Redis配置文件的說明內(nèi)容,需要的朋友們可以學(xué)習(xí)下。
    2020-03-03
  • 詳解redis在服務(wù)器linux下啟動的相關(guān)命令(安裝和配置)

    詳解redis在服務(wù)器linux下啟動的相關(guān)命令(安裝和配置)

    這篇文章主要介紹了redis在服務(wù)器linux下的啟動的相關(guān)命令(安裝和配置),本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-08-08
  • Redis三種特殊數(shù)據(jù)類型的具體使用

    Redis三種特殊數(shù)據(jù)類型的具體使用

    本文主要介紹了Redis三種特殊數(shù)據(jù)類型的具體使用,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • Redis中pipeline(管道)的實(shí)現(xiàn)示例

    Redis中pipeline(管道)的實(shí)現(xiàn)示例

    Redis管道(Pipeline)技術(shù)是一種提高數(shù)據(jù)處理效率的機(jī)制,允許客戶端通過一次網(wǎng)絡(luò)往返(RTT)發(fā)送多個(gè)命令到服務(wù)端,并一次性接收所有響應(yīng),本文就來實(shí)現(xiàn)管道,感興趣的可以了解一下
    2024-10-10
  • Redis高可用集群redis-cluster詳解

    Redis高可用集群redis-cluster詳解

    redis?cluster?是redis官方提供的分布式解決方案,在3.0版本后推出的,有效地解決了redis分布式的需求,當(dāng)一個(gè)redis節(jié)點(diǎn)掛了可以快速的切換到另一個(gè)節(jié)點(diǎn),對redis-cluster高可用集群相關(guān)知識感興趣的朋友一起看看吧
    2022-03-03
  • Redis 2.8-4.0過期鍵優(yōu)化過程全紀(jì)錄

    Redis 2.8-4.0過期鍵優(yōu)化過程全紀(jì)錄

    這篇文章主要給大家介紹了關(guān)于Redis 2.8-4.0過期鍵優(yōu)化的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用Redis具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • Redis 緩存使用的熱點(diǎn)Key問題的解決

    Redis 緩存使用的熱點(diǎn)Key問題的解決

    Redis熱點(diǎn)Key因高并發(fā)導(dǎo)致性能問題,可通過監(jiān)控發(fā)現(xiàn)并利用本地緩存、分片、讀寫分離及限流熔斷等策略分散壓力,下面就來了解一下
    2025-05-05
  • redis模糊批量刪除key的方法

    redis模糊批量刪除key的方法

    這篇文章主要介紹了redis模糊批量清除key的操作方法,包括命令行刪除和golang代碼刪除,本文結(jié)合示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-12-12
  • Redis?RESP?協(xié)議實(shí)現(xiàn)實(shí)例詳解

    Redis?RESP?協(xié)議實(shí)現(xiàn)實(shí)例詳解

    這篇文章主要為大家介紹了Redis?RESP?協(xié)議實(shí)現(xiàn)實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • 關(guān)于redis可視化工具讀取數(shù)據(jù)亂碼問題

    關(guān)于redis可視化工具讀取數(shù)據(jù)亂碼問題

    大家來聊一聊在日常操作redis時(shí)用的是什么工具,redis提供的一些命令你都了解了嗎,今天通過本文給大家介紹redis可視化工具讀取數(shù)據(jù)亂碼問題,感興趣的朋友跟隨小編一起看看吧
    2021-07-07

最新評論

韩城市| 会同县| 新晃| 昌宁县| 贵德县| 宝丰县| 兴仁县| 天等县| 大新县| 高邮市| 神池县| 白河县| 衡东县| 满洲里市| 长子县| 长武县| 郓城县| 西华县| 谷城县| 隆昌县| 绍兴市| 噶尔县| 宣城市| 旬邑县| 丽水市| 洛隆县| 北宁市| 资中县| 邮箱| 武功县| 克东县| 修文县| 崇礼县| 永宁县| 临颍县| 长春市| 青神县| 阜康市| 建始县| 视频| 资源县|