天天看點

Redis緩存過期與記憶體淘汰Redis緩存過期與記憶體淘汰

Redis緩存過期與記憶體淘汰

  • Redis中有個設定時間過期的功能,即對存儲在redis 資料庫中的值可以設定一個過期時間,到了過期時間,key會被删除
  • 如果記憶體空間滿了,再往Redis裡面插入資料,就會觸發緩存淘汰機制

緩存過期政策

作為一個緩存資料庫,這是非常實用的。我們set key的時候,都可以給一個expire_time, 就是過期時間,通過過期時間我們可以指定這個key可以存活的時間。

那麼,到了過期時間後,這些key是怎麼被删除的呢?

  • 緩存過期是在 Key 超過 expire_time 後,從記憶體中删除,減少記憶體空間的占用
  • 不同政策的定義、優點和缺點都是不同的。Redis 的過期政策主要有三種實作方式:

定時删除:

對于每一個有過期時間的 Key,建立一個定時器,到過期時間後立即删除;

  • 優點:儲存記憶體可以盡快釋放,減少過期 Key 對記憶體空間的占用;
  • 缺點:占用大量的 CPU 資源去處理定時器,影響緩存的吞吐量,這和 Redis 設計追求性能的設定不符,是以一般不會采用這種政策。

惰性删除:

過期的 Key 不做處理,隻有當通路這個 Key 時才會判斷是否過期,過期則删除;

  • 優點:删除操作隻有在訪存的時候才可能執行,對 CPU 的占用做到了最小。
  • 缺點:如果記憶體中大量的 Key 均過期,且一段時間内沒有被通路,會占用大量記憶體。

定期删除:

每隔一段時間(預設100ms)全量掃描設定了過期時間的 Key,如果失效則從記憶體中删除,否則不做處理;

  • 優點:通過限制定時的頻率,來減少對 CPU 的占用和對記憶體的占用;
  • 缺點:作為一種折中的方案,在記憶體友好方面,不如定時删除政策;在 CPU 友好方面,不如惰性删除。使用時的表現非常依賴配置的定期頻率。

記憶體淘汰機制

但是僅僅通過設定過期時間還是有問題的。如果定期删除漏掉了很多過期key,然後你也

沒及時去查,也就沒走惰性删除,此時會有大量過期key堆積在記憶體裡,導緻redis記憶體耗

盡了

redis記憶體淘汰機制就橫空出世了,緩存過期政策和記憶體淘汰機制是非常容易混淆的兩個概念,兩者的目的是不同的。

  • 緩存過期政策:針對過期 Key ,從記憶體中移除的方式。
  • 記憶體淘汰機制:針對 Redis 記憶體不足時,業務還在繼續往 Redis 追加内容,如何處理已有的内容。

八種淘汰政策

  • volatile-lru:當記憶體不足以容納新寫入資料時,在設定了過期時間的鍵空間中,移除最近最少使用的 key;
  • allkeys-lru:當記憶體不足以容納新寫入資料時,在鍵空間中,移除最近最少使用的 key;
  • volatile-lfu:當記憶體不足以容納新寫入資料時,在過期密集的鍵中,使用 LFU 算法進行删除 key;
  • allkeys-lfu:當記憶體不足以容納新寫入資料時,對所有的 key 執行 LFU 算法篩選過期;
  • volatile-random:當記憶體不足以容納新寫入資料時,在設定了過期的鍵中,随機删除一個 key;
  • allkeys-random:當記憶體不足以容納新寫入資料時,随機删除一個或者多個 key;
  • volatile-ttl:當記憶體不足以容納新寫入資料時,在設定了過期時間的鍵空間中,有更早過期時間的 key 優先移除;
  • noeviction:當記憶體不足以容納新寫入資料時,新寫入操作直接報錯,無法寫入。

上述算法按照特性可以分為幾類:LRU/LFU 算法、随機删除算法、優先淘汰曆史資料算法、報錯處理算法。目前主流是使用 LRU 算法

  • Redis 用作持久化資料庫,不配置緩存過期時間,采用 allkeys-lru ;
  • Redis 作為緩存資料庫,配置了 Key 過期時間,采用 volatile-lru 算法。

LRU算法

LRU(Least Recently Used,最近最少使用算法)是最常見的緩存淘汰算法,核心思想是 “如果資料最近被通路過,那麼将來被通路的可能性也更高”。

算法思想

  • 新資料直接插入到連結清單頭部;
  • 每當緩存命中(即緩存資料被通路),則将被命中的資料移到連結清單頭部;
  • 當連結清單滿的時候,将連結清單尾部的資料丢棄。
    Redis緩存過期與記憶體淘汰Redis緩存過期與記憶體淘汰

總結,越靠近連結清單頭部的資料越是不容易被淘汰,越靠近連結清單尾部的資料越是容易淘汰。

繼續閱讀