Redis深度歷險-過期刪除

Redis深度歷險-過期刪除

保存過期時間

Redis支持通過TTLPTTL命令來查詢剩下的存活時間

typedef struct redisDb {
    ......
    dict *expires;              /* Timeout of keys with a timeout set */
        ......
} redisDb;

在Redis中每一個數(shù)據(jù)庫中有一個專門存儲過期時間的字典,不管是通過什么命令設(shè)置的過期時間,內(nèi)部存儲的都是過期的毫秒數(shù)時間戳

Redis的過期刪除策略

常用的刪除策略是惰性刪除和定時刪除,Redis是兩者結(jié)合

惰性刪除

db.c/expireIfNeeded函數(shù)就是用來處理過期鍵,在命令真正執(zhí)行之前會過濾刪除掉過期的鍵

int expireIfNeeded(redisDb *db, robj *key) {
    //如果鍵沒有過期,返回0
    if (!keyIsExpired(db,key)) return 0;

    //非主機(jī)或者pause狀態(tài)則不會進(jìn)行刪除
    if (server.masterhost != NULL) return 1;

    if (checkClientPauseTimeoutAndReturnIfPaused()) return 1;

    //lazyfree_lazy_expire配置決定同步刪除還是異步刪除
    if (server.lazyfree_lazy_expire) {
        dbAsyncDelete(db,key);
    } else {
        dbSyncDelete(db,key);
    }
    server.stat_expiredkeys++;
    propagateExpire(db,key,server.lazyfree_lazy_expire);
    notifyKeyspaceEvent(NOTIFY_EXPIRED,
        "expired",key,db->id);
    signalModifiedKey(NULL,db,key);
    return 1;
}
long long getExpire(redisDb *db, robj *key) {
    dictEntry *de;

    //如果key沒有過期時間返回-1
    if (dictSize(db->expires) == 0 ||
       (de = dictFind(db->expires,key->ptr)) == NULL) return -1;

    //字符串轉(zhuǎn)換為整數(shù)
    serverAssertWithInfo(NULL,key,dictFind(db->dict,key->ptr) != NULL);
    return dictGetSignedIntegerVal(de);
}

在各種命令中最終都會調(diào)用到此函數(shù)中,邏輯上只是從expire中查詢并比較

定時刪除策略

定時刪除的邏輯實現(xiàn)在server.c/activeExpireCycle中,在Redis的定時函數(shù)server.c/serverCron中被調(diào)用

void activeExpireCycle(int type) {
    ......
      //記錄此次操作的是哪個數(shù)據(jù)庫
      static unsigned int current_db = 0; /* Next DB to test. */
      //遍歷16個數(shù)據(jù)庫,對每一個都刪除一定的過期key
            for (j = 0; j < dbs_per_call && timelimit_exit == 0; j++) {
        .......

定時刪除的代碼比較復(fù)雜,這里簡述一下定時刪除的規(guī)則:

  1. 每一次定時刪除都會對嘗試所有的數(shù)據(jù)庫進(jìn)行刪除操作
  2. Redis的定時刪除操作是有時間限制的,超過時間會退出此函數(shù)
  3. Redis會記錄當(dāng)前過期的操作進(jìn)度,包括操作的數(shù)據(jù)庫、操作的過期鍵游標(biāo)

時間事件

??Redis是基于多路復(fù)用的事件模型,是支持實現(xiàn)定時器的;但是Redis中的時間事件是使用一個順序鏈表存儲的,不適用于大量的定時任務(wù)處理

主備模式的刪除策略

在主備的部署模式下,備機(jī)不會刪除過期鍵;但是給客戶端的返回值還是盡量保持一致,視作已過期刪除

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • # 前言 ### 為什么我要嘗試寫作技術(shù)書籍 - 一個人年輕時經(jīng)歷的艱難會在未來成為他的財富 # 第一篇 基礎(chǔ)和應(yīng)...
    zhzosh閱讀 659評論 0 0
  • 設(shè)置過期時間 EXPIRE <key> <ttl> 命令用于將鍵 key 的生存時間設(shè)置為 ttl 秒 PEXPI...
    youngiii閱讀 3,788評論 0 56
  • 前言: 數(shù)據(jù)庫鍵空間 Redis是一個鍵值對(key-value pair)數(shù)據(jù)庫服務(wù)器,服務(wù)器中的每個數(shù)據(jù)庫都由...
    但時間也偷換概念閱讀 1,513評論 0 6
  • 應(yīng)用篇 1、Redis分布式鎖 超時問題 如果在加鎖和釋放鎖之間的邏輯執(zhí)行的太長,以至于超出了鎖的超時限制,就會出...
    技術(shù)滅霸閱讀 699評論 0 3
  • 在Redis的使用過程中,經(jīng)常會遇到一些在特定時間之后就需要刪除的數(shù)據(jù),Redis提供了鍵的過期時間這個功能來解決...
    冷若秋楓閱讀 367評論 0 1

友情鏈接更多精彩內(nèi)容