7.Redis過期策略底層是如何實現的?

過期策略

如果我們對key設置了失效時間1分鐘,1分鐘后,Redis 是如何對這個 key 進行刪除的呢?

Redis過期策略采用的是惰性刪除+定期刪除策略。

1.惰性刪除

當某個key被設置了過期時間之后,客戶端每次對該key的訪問(讀寫)都會事先檢測該key是否過期,如果過期就直接刪除。

2.定期刪除

當某個key被設置了過期時間之后,客戶端每次對該key的訪問(讀寫)都會事先檢測該key是否過期,如果過期就直接刪除(這種是被動刪除);但有一些鍵只訪問一次或者是冷數據,因此需要主動刪除,默認情況下Redis每秒檢測10次,檢測的對象是所有設置了過期時間的鍵集合,每次從這個集合中隨機檢測20個鍵查看他們是否過期,如果過期就直接刪除,如果過期的key比例超過1/4,那就把上述操作重復一次(貪心算法)。同時為了保證過期掃描不會出現循環過度,導致線程卡死現象,算法還增加了掃描時間的上限,默認不會超過25ms。

如果一個大型的 Redis 實例中所有的 key 在同一時間過期了,會引發什么問題?

這個主動過期 key 的定時任務,是在 Redis 主線程中執行的,也就是說如果在執行主動過期的過程中,出現了需要大量刪除過期 key 的情況,那么此時應用程序在訪問 Redis 時,必須要等待這個過期任務執行結束,Redis 才可以服務這個客戶端請求。此時就會出現,應用訪問 Redis 延時變大。

有小伙伴問,掃描不是有 25ms 的時間上限了么,怎么會導致卡頓呢?

假如有 1001 個客戶端同時將請求發過來了,然后前 1000 個請求的執行時間都是 25ms,那么第 1001 個指令需要等待多久才能執行?25000ms,25秒,這個就是客戶端的卡頓時間,是由服務器不間斷的小卡頓積少成多導致的。

大量key集中過期導致卡頓如何解決?

方案一:在設置 key 的過期時間時,增加一個隨機時間

redis.expireat(key, expire_time + random(300))

這樣一來,Redis 在處理過期時,不會因為集中刪除過多的 key 導致壓力過大,從而避免阻塞主線程。

方案二:Redis 4.0 以上版本,開啟 lazy-free 機制

lazyfree-lazy-expire yes

另外,除了業務層面的優化和修改配置之外,你還可以通過運維手段及時發現這種情況。

運維層面,你需要把 Redis 的各項運行狀態數據監控起來,在 Redis 上執行 INFO 命令就可以拿到這個實例所有的運行狀態數據。

在這里我們需要重點關注 expired_keys 這一項,它代表整個實例到目前為止,累計刪除過期 key 的數量。

你需要把這個指標監控起來,當這個指標在很短時間內出現了突增,需要及時報警出來,然后與業務應用報慢的時間點進行對比分析,確認時間是否一致,如果一致,則可以確認確實是因為集中過期 key 導致的延遲變大。

從庫的過期策略: 從庫不會進行過期掃描,從庫對過期的處理是被動的。主庫在 key 到期時,會在 AOF 文件里增加一條 del 指令,同步到所有的從庫,從庫通過執行這條 del 指令來刪除過期的 key。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 在日常開發中,我們使用 Redis 存儲 key 時通常會設置一個過期時間,但是 Redis 是怎么刪除過期的 k...
    Java技術精選閱讀 209評論 0 0
  • Redis所有的數據結構都可以設置過期時間,時間一到就會自動刪除。思考:Redis是單線程的,刪除key的時間也會...
    seolinAziz閱讀 281評論 0 0
  • Redis過期策略 概述 Redis所有的數據結構都可以設置過期時間。Redis會將每個設置了過期時間的key放入...
    站得高看得遠閱讀 415評論 0 1
  • 1.前言 Redis的所有數據結構都是可以設置過期時間的,時間一到就可以自動刪除。那么,redis內部是如何知道哪...
    LZhan閱讀 454評論 0 0
  • 我是黑夜里大雨紛飛的人啊 1 “又到一年六月,有人笑有人哭,有人歡樂有人憂愁,有人驚喜有人失落,有的覺得收獲滿滿有...
    陌忘宇閱讀 8,592評論 28 53