Redis
的文章,我以前寫過一篇關於Redis的緩存的三大問題,累計閱讀也快800了,對於還只有3k左右的粉絲量,可以達到這個閱讀量,已是比較難了。web
這說明那篇文章寫的還過得去,收到不少人的閱讀確定,感興趣的看一下[]。面試
三大緩存問題只是Redis的其中的一小部分的知識點,想要深刻學習Redis還要學習比較多的知識點。redis
那麼今天就帶來了一個面試常問的一個問題:假如你的Redis內存滿了怎麼辦? 長期的把Redis做爲緩存使用,總有一天會存滿的時候對吧。算法
這個面試題不慌呀,在Redis中有配置參數maxmemory
能夠設置Redis內存的大小。緩存
在Redis的配置文件redis.conf
文件中,配置maxmemory
的大小參數以下所示: 實際生產中確定不是
100mb
的大小哈,不要給誤導了,這裏我只是讓你們認識這個參數,通常小的公司都是設置爲3G
左右的大小。dom
除了在配置文件中配置生效外,還能夠經過命令行參數的形式,進行配置,具體的配置命令行以下所示:編輯器
//獲取maxmemory配置參數的大小
127.0.0.1:6379> config get maxmemory
//設置maxmemory參數爲100mb
127.0.0.1:6379> config set maxmemory 100mb
複製代碼
假若實際的存儲中超出了Redis的配置參數的大小時,Redis中有淘汰策略,把須要淘汰的key給淘汰掉,整理出乾淨的一塊內存給新的key值使用。學習
接下來咱們就詳細的聊一聊Redis中的淘汰策略,而且深刻的理解每一個淘汰策略的原理和應用的場景。優化
Redis提供了6種的淘汰策略,其中默認的是noeviction
,這6中淘汰策略以下:url
noeviction
(
默認策略):如果內存的大小達到閥值的時候,全部申請內存的指令都會報錯。
allkeys-lru
:全部key都是使用
LRU算法進行淘汰。
volatile-lru
:全部
設置了過時時間的key使用LRU算法進行淘汰。
allkeys-random
:全部的key使用
隨機淘汰的方式進行淘汰。
volatile-random
:全部
設置了過時時間的key使用隨機淘汰的方式進行淘汰。
volatile-ttl
:全部設置了過時時間的key
根據過時時間進行淘汰,越早過時就越快被淘汰。
假如在Redis中的數據有一部分是熱點數據,而剩下的數據是冷門數據,或者咱們不太清楚咱們應用的緩存訪問分佈情況,這時可使用allkeys-lru
。
假如全部的數據訪問的頻率大概同樣,就可使用allkeys-random
的淘汰策略。
假如要配置具體的淘汰策略,能夠在redis.conf
配置文件中配置,具體配置以下所示: 這隻須要把註釋給打開就能夠,而且配置指定的策略方式,另外一種的配置方式就是命令的方式進行配置,具體的執行命令以下所示:
// 獲取maxmemory-policy配置
127.0.0.1:6379> config get maxmemory-policy
// 設置maxmemory-policy配置爲allkeys-lru
127.0.0.1:6379> config set maxmemory-policy allkeys-lru
複製代碼
在介紹6種的淘汰策略方式的時候,說到了LRU算法,那麼什麼是LRU算法呢?
LRU(Least Recently Used)
即表示最近最少使用,也就是在最近的時間內最少被訪問的key,算法根據數據的歷史訪問記錄來進行淘汰數據。
它的核心的思想就是:假如一個key值在最近不多被使用到,那麼在未來也不多會被訪問。
實際上Redis實現的LRU並非真正的LRU算法,也就是名義上咱們使用LRU算法淘汰鍵,可是實際上被淘汰的鍵並不必定是真正的最久沒用的。
Redis使用的是近似的LRU算法,經過隨機採集法淘汰key,每次都會隨機選出5個key,而後淘汰裏面最近最少使用的key。
這裏的5個key只是默認的個數,具體的個數也能夠在配置文件中進行配置,在配置文件中的配置以下圖所示: 當近似LRU算法取值越大的時候就會越接近真實的LRU算法,能夠這樣理解,由於取值越大那麼獲取的數據就越全,淘汰中的數據的就越接近最近最少使用的數據。
那麼爲了實現根據時間實現LRU算法,Redis必須爲每一個key中額外的增長一個內存空間用於存儲每一個key的時間,大小是3字節。
在Redis 3.0中對近似的LRU算法作了一些優化,Redis中會維護大小是16
的一個候選池的內存。
當第一次隨機選取的採樣數據,數據都會被放進候選池中,而且候選池中的數據會根據時間進行排序。
當第二次之後選取的數據,只有小於候選池內的最小時間的纔會被放進候選池中。
當某一時刻候選池的數據滿了,那麼時間最大的key就會被擠出候選池。當執行淘汰時,直接從候選池中選取最近訪問時間最小的key進行淘汰。
這樣作的目的就是選取出最近似符合最近最少被訪問的key值,可以正確的淘汰key值,由於隨機選取的樣本中的最小時間可能不是真正意義上的最小時間。
可是LRU算法有一個弊端:就是假如一個key值在之前都沒有被訪問到,然而最近一次被訪問到了,那麼就會認爲它是熱點數據,不會被淘汰。
然而有些數據之前常常被訪問到,只是最近的時間內沒有被訪問到,這樣就致使這些數據極可能被淘汰掉,這樣一來就會出現誤判而淘汰熱點數據。
因而在Redis 4.0的時候除了LRU算法,新加了一種LFU算法,那麼什麼是LFU算法算法呢?
LFU(Least Frequently Used)
即表示最近頻繁被使用,也就是最近的時間段內,頻繁被訪問的key,它以最近的時間段的被訪問次數的頻率做爲一種判斷標準。
它的核心思想就是:根據key最近被訪問的頻率進行淘汰,比較少被訪問的key優先淘汰,反之則優先保留。
LFU算法反映了一個key的熱度狀況,不會由於LRU算法的偶爾一次被訪問被認爲是熱點數據。
在LFU算法中支持volatile-lfu
策略和allkeys-lfu
策略。
以上介紹了Redis的6種淘汰策略,這6種淘汰策略旨在告訴咱們怎麼作,可是何時作?這個還沒說,下面咱們就來詳細的瞭解Redis何時執行淘汰策略。
在Redis種有三種刪除的操做此策略,分別是:
定時刪除對於內存來講是友好的,定時清理出乾淨的空間,可是對於cpu來講並非友好的,程序須要維護一個定時器,這就會佔用cpu資源。
惰性的刪除對於cpu來講是友好的,cpu不須要維護其它額外的操做,可是對於內存來講是不友好的,由於要是有些key一直沒有被訪問到,就會一直佔用着內存。
按期刪除是上面兩種方案的折中方案**,每隔一段時間刪除過時的key,也就是根據具體的業務,合理的取一個時間按期的刪除key**。
經過最合理控制刪除的時間間隔來刪除key,減少對cpu的資源的佔用消耗,使刪除操做合理化。
在Redis中持久化的方式有兩種RDB
和AOF
,具體這兩種詳細的持久化介紹,能夠參考這一篇文章[]。
在RDB中是以快照的形式獲取內存中某一時間點的數據副本,在建立RDB文件的時候能夠經過save
和bgsave
命令執行建立RDB文件。
這兩個命令都不會把過時的key保存到RDB文件中,這樣也能達到刪除過時key的效果。
當在啓動Redis載入RDB文件的時候,Master
不會把過時的key載入,而Slave
會把過時的key載入。
在AOF模式下,Redis提供了Rewite的優化措施,執行的命令分別是REWRITEAOF
和BGREWRITEAOF
,這兩個命令都不會把過時的key寫入到AOF文件中,也能刪除過時key。