一、前言
Redis在我們日常開發中是經常用到的,Redis也是功能非常強大,可以進行快取,還會有一些排行榜、點贊、訊息佇列、購物車等等;當然還有分布式鎖Redisson,我們使用肯定少不了集群!小編最近學習到一些記憶體如果滿了Redis是怎么操作呢?肯定像我們JVM一樣,有回識訓者淘汰的機制!今天小編和大家一起學習一下,小編也是看了陽哥的課,覺得講的很好,記錄一下,希望可以幫助到大家!!
二、自己配置Redis記憶體大小
redis安裝上,如果你不配置的話,默認就是按你的電腦記憶體的大小,
我們打開組態檔看一下哈!這里以6.0.6組態檔為例
打開redis.conf檔案:856行:
我們可以設定大小,我們可以看到是以位元組為單位的哈!
maxmemory <bytes>
我們可以使用命令查詢記憶體大小:
127.0.0.1:6379> config get maxmemory
1) "maxmemory"
2) "0"
不配置默認為0使用電腦最大記憶體,
當然也可以通過命令進行設定:
127.0.0.1:6379> config set maxmemory 2
OK
127.0.0.1:6379> config get maxmemory
1) "maxmemory"
2) "2"
127.0.0.1:6379> set k1 wang
(error) OOM command not allowed when used memory > 'maxmemory'.
根據測驗:我們發現redis也會像JVM一樣報OOM例外
心得: 我們一般不會調整Redis的記憶體大小,如果調也是一般像HashMap的加載因子一樣,也就是3/4即可
三、三大過期策略
三大過期策略:定時洗掉、惰性洗掉、定期洗掉
過期策略存在原因:
Redis不可能時時刻刻遍歷所有被設定了生存時間的key,來檢測資料是否已經到達過期時間,然后對它進行洗掉,
1. 定時洗掉
定時洗掉又名立即洗掉:能保證記憶體中資料的最大新鮮度,因為它保證過期鍵值會在過期后馬上被洗掉,其所占用的記憶體也會隨之釋放,但是立即洗掉對cpu是最不友好的,因為洗掉操作會占用cpu的時間,如果剛好碰上了cpu很忙的時候,比如正在做交集或排序等計算的時候,就會給cpu造成額外的壓力,讓CPU心累,時時需要洗掉,忙死,
這會產生大量的性能消耗,同時也會影響資料的讀取操作,
2. 惰性洗掉
資料到達過期時間,不做處理,等下次訪問該資料時,如果未過期,回傳資料;發現已過期,洗掉,回傳不存在,
惰性洗掉策略的缺點是,它對記憶體是很不友好的,
如果一個鍵已經過期,而這個鍵又仍然保留在資料庫中,那么只要這個過期鍵不被洗掉,它所占用的記憶體就不會釋放,
在使用惰性洗掉策略時,如果資料庫中有非常多的過期鍵,而這些過期鍵又恰好沒有被訪問到的話,那么它們也許永遠也不會被洗掉(除非用戶手動執行FLUSHDB),我們甚至可以將這種情況看作是一種記憶體泄漏 – 無用的垃圾資料占用了大量的記憶體,而服務器卻不會自己去釋放它們,這對于運行狀態非常依賴于記憶體的Redis服務器來說,肯定不是一個好訊息,
3. 定期洗掉
定期洗掉策略是前兩種策略的折中:
定期洗掉策略每隔一段時間執行一次洗掉過期鍵操作,并通過限制洗掉操作執行的時長和頻率來減少洗掉操作對CPU時間的影響,
周期性輪詢Redis庫中的時效性資料,來用隨機抽取的策略,利用過期資料占比的方式控制洗掉頻度
特點1:CPU性能占用設定有峰值,檢測頻度可自定義設定
特點2:記憶體壓力不是很大,長期占用記憶體的冷資料會被持續清理
4. 附例子:
redis默認每個100ms檢查,是否有過期的key,有過期key則洗掉,
注意:redis不是每隔100ms將所有的key檢查一次而是隨機抽取進行檢查(如果每隔100ms,全部key進行檢查,redis直接進去ICU),因此,如果只采用定期洗掉策略,會導致很多key到時間沒有洗掉,
定期洗掉策略的難點是確定洗掉操作執行的時長和頻率:如果洗掉操作執行得太頻繁,或者執行的時間太長,定期洗掉策略就會退化成定時洗掉策略,以至于將CPU時間過多地消耗在洗掉過期鍵上面,如果洗掉操作執行得太少,或者執行的時間太短,定期洗掉策略又會和惰性洗掉束略一樣,出現浪費記憶體的情況,因此,如果采用定期洗掉策略的話,服務器必須根據情況,合理地設定洗掉操作的執行時長和執行頻率,
5. 總結
定時洗掉 :對CPU不友好,用處理器性能換取存盤空間(拿時間換空間)
惰性洗掉:對memory不友好,用存盤空間換取處理器性能(拿空間換時間)
定期洗掉:周期性抽查存盤空間,隨機抽查,重點抽查(存在漏網之魚)
6.思考
我們會發現,三種情況都存在瑕疵,如果資料量大,一定會出現記憶體滿了,報OOM!所以我們下面引出八大淘汰策略!!
四、八大淘汰策略
我們還是打開redis.conf組態檔,找到861行:
# volatile-lru -> Evict using approximated LRU, only keys with an expire set.
# allkeys-lru -> Evict any key using approximated LRU.
# volatile-lfu -> Evict using approximated LFU, only keys with an expire set.
# allkeys-lfu -> Evict any key using approximated LFU.
# volatile-random -> Remove a random key having an expire set.
# allkeys-random -> Remove a random key, any key.
# volatile-ttl -> Remove the key with the nearest expire time (minor TTL)
# noeviction -> Don't evict anything, just return an error on write operations.
我們來翻譯一下哈:
volatile-lru:當記憶體放不下新添加的資料時,從設定了過期時間的key中使用LRU(最近最少使用)演算法進行洗掉key;
allkeys-lru:當記憶體放不下新添加的資料時,從所有key中使用LRU(最近最少使用)演算法進行洗掉key,
volatile-lfu:當記憶體放不下新添加的資料時,從設定了過期時間的key中,使用LFU(最近頻繁使用)演算法進行洗掉key,
allkeys-lfu:當記憶體放不下新添加的資料時,從所有key中使用LFU(最近頻繁使用)演算法進行洗掉key;
volatile-random:當記憶體放不下新添加的資料時,從設定了過期時間的key中,隨機洗掉key;,
allkeys-random:當記憶體放不下新添加的資料時,從所有key中隨機洗掉key,
volatile-ttl:當記憶體放不下新添加的資料時,在設定了過期時間的key中,根據過期時間進行淘汰,越早過期的優先被洗掉key;
noeviction:當記憶體放不下新添加的資料時,新寫入操作會報錯,默認策略
五、手動配置淘汰策略
打開redis.conf組態檔找到:887行,把注釋去掉,添加自己需要的淘汰策略
maxmemory-policy noeviction
當然我們也可以使用命令進行修改:
127.0.0.1:6379> config set maxmemory-policy allkeys-Lru
OK
127.0.0.1:6379> config get maxmemory-policy
1) "maxmemory-policy"
2) "allkeys-lru"
六、總結
這樣我們對Redis就有了進一步的了解,謝謝大家跟著小編一起走下來,看到這里還不動一下你的發財小手點個關注哈!!
有緣人才可以看得到的哦!!!
點擊訪問!小編自己的網站,里面也是有很多好的文章哦!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/507120.html
標籤:Java
