超出物理內存後的Redis應對策略

當Redis內存超出物理內存限制時,內存的數據會開始和磁盤產生頻繁的交換。交換會讓Redis的性能急劇下降,對於訪問量比較頻繁的Redis來說等於不可用。

爲了限制最大使用內存,Redis提供了配置參數maxmemory來限制內存超出期望大小。當實際內存超出maxmemory時,Redis 提供了幾種可選策略來讓用戶自己決定該如何騰出新的空間以繼續提供讀寫服務:

1.noeviction不會繼續服務寫請求 (DEL請求可以繼續服務),讀請求可以繼續進行。這樣可以保證不會丟失數據,但是會讓線上的業務不能持續進行。這是默認的淘汰策略。

2.volatile-lru 嘗試淘汰設置了過期時間的key,最少使用的 key優先被淘汰。沒有設置過期時間的key不會被淘汰,這樣可以保證需要持久化的數據不會突然丟失。

3.volatile-ttl 跟上面一樣,除了淘汰的策略是key的剩餘壽命ttl的值,ttl越小越優先被淘汰。

4.volatile-random跟上面一樣,不過淘汰的key是過期key集合中隨機的key。

5.allkeys-lru區別於volatile-lru是要淘汰的key對象是全體的key集合,而不只是過期的key集合。這意味着沒有設置過期時間的key也會被淘汰。

6.allkeys-random跟上面一樣,不過淘汰的策略是隨機的key。

總之,volatile-xxx策略只會針對帶過期時間的key進行淘汰,allkeys-xxx策略會對所有的key進行淘汰。

Redis是怎麼設計這個策略的呢?

答:Redis給每個key增加了一個額外的小字段,這個字段的長度是24個 bit,也就是最後一次被訪問的時間戳。

Redis採取了近似於LRU算法,採用懶惰處理方式,當發現內存超出maxmemory,就會執行一次LRU淘汰算法。就是隨機採樣出5(可以配置)個key,然後淘汰掉最舊的key,如果淘汰後內存還是超出maxmemory,那就繼續隨機採樣淘汰,直到內存低於maxmemory爲止。

如何採樣就是看 maxmemory-policy 的配置,如果是allkeys就是從所有的key字典中隨機,如果是volatile就從帶過期時間的 key 字典中隨機。每次採樣多少個key看的是 maxmemory_samples的配置,默認爲5。

同時 Redis3.0在算法中增加了淘汰池,進一步提升了近似 LRU 算法的效果。淘汰池是一個數組,它的大小是maxmemory_samples,在每一次淘汰循環中,新隨機出來的key列表會和淘汰池中的key 列表進行融合,淘汰掉最舊的一個key之後,保留剩餘較舊的key列表放入淘汰池中留待下一個循環。

發佈了167 篇原創文章 · 獲贊 10 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章