Redis之過期 key 底層邏輯

Redis給我們提供了設(shè)置鍵過期的方式:

  1. EXPIRE <key> <ttl> 命令用于將鍵key的生存時間設(shè)置為ttl秒
  2. PEXPIRE <key> <ttl> 命令用于將鍵key的生存時間設(shè)置為ttl毫秒
  3. EXPIREAT <key> <timestamp> 命令用于將鍵key的過期時間設(shè)置為timestamp
  4. PEXPIREAT <key> <timestamp>命令用于將鍵key的過期時間設(shè)置為timestamp所指定的秒數(shù)時間戳

其實上述命令經(jīng)過轉(zhuǎn)換后的執(zhí)行效果都和PEXPIREAT命令效果一樣:

def EXPIRE(key, ttl_in_sec) :
  #將TTL從秒轉(zhuǎn)換成毫秒
  ttl_in_ms = sec_to_ms(ttl_in_sec)
  PEXPIRE(key, ttl_in_ms)

def PEXPIRE(key, ttl_in_ms):
  now_ms = get_current_unix_timestamp_in_ms()
  PEXPIREAT(key,now_ms+ttl_in_ms)

def EXPIREAT(key, expire_time_in_sec):
  expire_time_in_ms = sec_to_ms(expire_time_in_sec)
  PEXPIREAT(key, expire_time_in_ms)
方法轉(zhuǎn)換

過期時間的底層存儲

image.png

從圖可知,在redis的數(shù)據(jù)庫中,redisDb結(jié)構(gòu)中的expires字典中保存了數(shù)據(jù)庫中所有鍵的過期時間,所以叫過期字典。

  • 過期字典的key是一個指針,指向鍵空間的某個鍵對象(就是數(shù)據(jù)庫鍵)
  • 過期字典的value是一個long類型的整數(shù),這個整數(shù)保存了鍵所指向的數(shù)據(jù)庫鍵的過期時間,一個毫秒精度的UNIX時間戳

過期鍵判定

通過過期字典,我們可以得到一個key是否過期:

  • 判斷key是否存在于過期字典中
  • 通過過期字典拿到key的過期時間,判斷當前UNIX時間戳是否大于key時間

重點:過期鍵的刪除策略

其實刪除策略也比較常見,以下三種:

  • 定時刪除:設(shè)置過期鍵的同時,設(shè)定設(shè)定定時器,通過定時器來主動刪除過期鍵。
    這種方式對內(nèi)存友好,但是對cpu最不友好;定時器的設(shè)定需要使用redis服務(wù)器的時間事件(無序鏈表),查找的事件復(fù)雜度為O(n);故在過期鍵過多時,cpu的大部分占用是用來查找過期鍵和刪除過期鍵的。

  • 惰性刪除:每次對key進行操作時,判斷當前key是否過期,再進行操作。
    這種方式很明顯對內(nèi)存是不友好的,key過期的話仍然會一直存在數(shù)據(jù)庫中,直到下次有對這個key的操作。

  • 定期刪除:每隔一段時間,對redis數(shù)據(jù)庫中的過期字典進行掃描,對于過期的key進行刪除。每次刪除多少過期鍵,以及檢查多少個數(shù)據(jù)庫,需要由我們的算法來決定。
    定期刪除算是上述兩種方式折中的方式,定期刪除的難點在于如何選取定期的時間:
    如果刪除操作太過于頻繁,那么將會退化成定時刪除;
    如果刪除操作執(zhí)行次數(shù)太少或者執(zhí)行的時間太短,就會退化為惰性刪除。

redis實際上選用的是惰性刪除和定期刪除兩種策略。
過期鍵的惰性刪除策略是由db.c/expireIfNeeded函數(shù)實現(xiàn)的,所有讀寫數(shù)據(jù)庫Redis命令在執(zhí)行之前都會先調(diào)用該函數(shù)對輸入鍵進行檢查

image.png

過期鍵的定期刪除策略是由redis.c/activeExpireCycle函數(shù)實現(xiàn)的。Redis服務(wù)器周期性操作redis.c/serverCron函數(shù),activeExpireCycle函數(shù)就會被調(diào)用,在規(guī)定的事件內(nèi),分多次遍歷服務(wù)器中的各個數(shù)據(jù)庫,從數(shù)據(jù)庫的expire字典中隨機檢查一部分鍵的過期時間,并刪除其中過期的鍵。

?著作權(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)容

  • 9.1 服務(wù)器中的數(shù)據(jù)庫 Redis服務(wù)器將所有的數(shù)據(jù)庫都保存在服務(wù)器狀態(tài)redis.h/redisServer結(jié)...
    豬大金閱讀 401評論 0 0
  • 本文對Redis的過期機制簡單的講解一下講解之前我們先拋出一個問題,我們知道很多時候服務(wù)器經(jīng)常會用到redis作為...
    小陳阿飛閱讀 1,367評論 0 0
  • 主要內(nèi)容 1.服務(wù)器保存數(shù)據(jù)庫的方法 2.客戶端切換數(shù)據(jù)庫的方法 3.數(shù)據(jù)庫保存鍵值對的方法 4.針對數(shù)據(jù)庫保存增...
    Felicia1993閱讀 374評論 0 0
  • 簡單直接上圖 實現(xiàn)方式 1.界面布局 wxss最好使用彈性布局,更好適配界面 數(shù)據(jù)結(jié)構(gòu)式采用??樹狀形式,一層一層,...
    我是要成為大神的男人閱讀 1,890評論 1 6
  • 7月4日,江門市工商局舉辦2017年食品安全周宣傳活動,相關(guān)科室的23名黨員義工和工作人員現(xiàn)場接受群眾咨詢及派發(fā)宣...
    消???/span>閱讀 306評論 0 1

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