場景:
如果你不斷的寫入數據,當數據寫入的量超過了redis能承受的范圍之后,該怎么辦?
redis是會在數據達到一定程度之后,超過了一個最大的限度之后,就會將數據進行一定的清理,從內存中清理掉一些數據,只有清理掉一些數據之后,才能將新的數據寫入內存中
1、LRU算法概述
redis默認情況下就是使用LRU策略的,因為內存是有限的,但是如果你不斷地往redis里面寫入數據,那肯定是沒法存放下所有的數據在內存的
所以redis默認情況下,當內存中寫入的數據很滿之后,就會使用LRU算法清理掉部分內存中的數據,騰出一些空間來,然后讓新的數據寫入redis緩存中
LRU:Least Recently Used,最近最少使用算法
將最近一段時間內,最少使用的一些數據,給干掉。比如說有一個key,在最近1個小時內,只被訪問了一次; 還有一個key在最近1個小時內,被訪問了1萬次
這個時候比如你要將部分數據給清理掉,你會選擇清理哪些數據啊?肯定是那個在最近小時內被訪問了1萬次的數據
2、緩存清理設置
maxmemory,設置redis用來存放數據的最大的內存大小,一旦超出這個內存大小之后,就會立即使用LRU算法清理掉部分數據
如果用LRU,那么就是將最近最少使用的數據從緩存中清除出去
對於64 bit的機器,如果maxmemory設置為0,那么就默認不限制內存的使用,直到耗盡機器中所有的內存為止; 但是對於32 bit的機器,有一個隱式的閑置就是3GB
maxmemory-policy,可以設置內存達到最大閑置后,采取什么策略來處理
(1)noeviction: 如果內存使用達到了maxmemory,client還要繼續寫入數據,那么就直接報錯給客戶端
(2)allkeys-lru: 就是我們常說的LRU算法,移除掉最近最少使用的那些keys對應的數據
(3)volatile-lru: 也是采取LRU算法,但是僅僅針對那些設置了指定存活時間(TTL)的key才會清理掉
(4)allkeys-random: 隨機選擇一些key來刪除掉
(5)volatile-random: 隨機選擇一些設置了TTL的key來刪除掉
(6)volatile-ttl: 移除掉部分keys,選擇那些TTL時間比較短的keys
allkeys-lru是redis緩存清理最常用的算法
3、緩存清理的流程
(1)客戶端執行數據寫入操作
(2)redis server接收到寫入操作之后,檢查maxmemory的限制,如果超過了限制,那么就根據對應的policy清理掉部分數據
(3)寫入操作完成執行
4、redis的LRU近似算法
(1)redis采取的是LRU近似算法,也就是對keys進行采樣,然后在采樣結果中進行數據清理
(2)redis 3.0開始,在LRU近似算法中引入了pool機制,表現可以跟真正的LRU算法相當,但是還是有所差距的,不過這樣可以減少內存的消耗
(3)redis LRU算法,是采樣之后再做LRU清理的,跟真正的、傳統、全量的LRU算法是不太一樣的
(4)maxmemory-samples,比如5,可以設置采樣的大小,如果設置為10,那么效果會更好,不過也會耗費更多的CPU資源