8.Redis內存淘汰策略

內存淘汰機制

當 Redis 內存超出物理內存限制時,內存的數據會開始和磁盤產生頻繁的交換 (swap)。 交換會讓 Redis 的性能急劇下降,對于訪問量比較頻繁的 Redis 來說,這樣低速的存取效率基本上等于不可用。

在生產環境中我們是不允許 Redis 出現交換行為的,為了限制最大使用內存,Redis 提供了配置參數 maxmemory 來限制內存超出期望大小。

1.淘汰策略

當實際內存超出 maxmemory 時,Redis 提供了6種可選策略 (maxmemory-policy) 來讓用戶自己決定該如何騰出新的空間以繼續提供讀寫服務。

  • noeviction:不會繼續服務寫請求 (DEL 請求可以繼續服務),讀請求可以繼續進行。這樣可以保證不會丟失數據,但是會讓線上的業務不能持續進行。這是默認的淘汰策略。
  • volatile-lru:嘗試淘汰設置了過期時間的 key,通過LRU算法驅逐最近最少使用的key。沒有設置過期時間的 key 不會被淘汰,這樣可以保證需要持久化的數據不會突然丟失。
  • volatile-random:嘗試淘汰設置了過期時間的 key,在設置了過期時間的key集合中隨機選擇數據淘汰。
  • volatile-ttl:嘗試淘汰設置了過期時間的 key,在設置了過期時間的key集合中優先淘汰ttl小的。
  • allkeys-lru:和volatile-lru的區別在于要淘汰的key對象是全體key集合而不只是設置了過期時間的key,其他都一樣。
  • allkeys-random:和volatile-random的區別在于要淘汰的key對象是全體key集合而不只是設置了過期時間的key,其他都一樣。

Redis4.0后新增了兩個策略:

volatile-lfu:嘗試淘汰設置了過期時間的 key,通過LFU算法驅逐使用頻率最少的key。沒有設置過期時間的 key 不會被淘汰。

allkeys-lfu:和volatile-lfu的區別在于要淘汰的key對象是全體key集合而不只是設置了過期時間的key,其他都一樣。

2.LRU算法

Redis LRU使用的是近似LRU算法,它跟 LRU 算法還不太一樣。之所以不使用 LRU 算法,是因為需要消耗大量的額外的內存,需要對現有的數據結構進行較大的改造。近似 LRU 算法則很簡單,在現有數據結構的基礎上使用隨機采樣法來淘汰元素,能達到和 LRU 算法非常近似的效果。

Redis 為實現近似 LRU 算法,它給每個 key 增加了一個額外的小字段,這個字段長度24位,存的是最后一次被訪問的時間戳,當Redis執行寫操作時,發現內存超出我們配置的{maxmemory},就會執行一次LRU淘汰算法,隨機采樣出{maxmemory_samples}個樣本,默認值為5,然后淘汰掉最舊的key,如果淘汰后內存還超出{maxmemory},那就繼續隨機采樣淘汰,直到內存低于{maxmemory}為止。

采樣數越大,近似LRU算法的效果越接近嚴格LRU算法,通過樣本數量調整算法的精度

淘汰池是一個數組,它的大小是${maxmemory_samples},在每次淘汰循環中,新隨機出的key列表會淘汰池中的key列表進行融合,淘汰掉最舊的一個key之后,保留剩余較舊的key列表放入淘汰池等待下一個循環。

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

推薦閱讀更多精彩內容