您好,登錄后才能下訂單哦!
這篇文章主要介紹Redis中過期鍵刪除策略和數據逐出策略的示例分析,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!
Redis作為一個高性能的內存NoSQL數據庫,其容量受到最大內存限制的限制。
在實際生產環境中使用Redis時,偶然會覺得Redis的內存占用要比自己預想的大。事實上,Redis占用的內存除了保存鍵值對所需的開銷外,還有一些運行時產生的額外內存,包括:
過期Key所占空間
漸進式Rehash導致未及時刪除的空間
Redis管理數據,包括底層數據結構開銷,客戶端信息,讀寫緩沖區等
主從復制,bgsave時的額外開銷
Redis的漸進式Rehash,在筆者介紹Concurrenthashmap擴容的時候,做了簡單的介紹,點擊查看
Redis的主從復制,則在筆者的另一篇博客里做了詳細的介紹,點擊查看
所以本文將主要圍繞過期Key的回收問題進行講解。
如果Redis的一個鍵是過期的,那它到了過期時間之后并不是馬上就從內存中被刪除,而是采用了三種不同的刪除策略:
立即刪除
惰性刪除
定時刪除
其中第二種為被動刪除,第一種和第三種為主動刪除,而且第一種實時性更高。
立即刪除是指,在設置鍵的過期時間時,創建一個回調事件,當過期時間達到時,由時間處理器自動執行鍵的刪除操作。
立即刪除能保證內存中數據的最大新鮮度,因為它保證過期鍵值會在過期后馬上被刪除,其所占用的內存也會隨之釋放。但是立即刪除對cpu是最不友好的。因為刪除操作會占用cpu的時間,如果剛好碰上了cpu正在做排序等計算的時候,就會給cpu造成額外的壓力。
而且目前redis事件處理器對時間事件的處理方式--無序鏈表,查找一個key的時間復雜度為O(n),所以并不適合用來處理大量的時間事件。
惰性刪除是指,某個鍵值過期后,此鍵值不會馬上被刪除,而是等到下次被使用的時候,才會被檢查到過期,此時才能得到刪除。所以惰性刪除的缺點很明顯:浪費內存。
舉個例子,對于一些按時間點來更新的數據,比如log日志,過期后在很長的一段時間內可能都得不到訪問,這樣在這段時間內就要浪費這么多內存來存log。
從上面分析來看,立即刪除會短時間內占用大量cpu,惰性刪除會在一段時間內浪費內存,所以定時刪除是一個折中的辦法。
定時刪除是指:每隔一段時間執行一次刪除操作,并通過限制刪除操作執行的時長和頻率,來減少刪除操作對cpu的影響。另一方面定時刪除也有效的減少了因惰性刪除帶來的內存浪費。
Redis過期Key清理的機制對清理的頻率和最大時間都有限制,在盡量不影響正常服務的情況下,進行過期Key的清理,以達到長時間服務的性能最優。
Redis會周期性的隨機測試一批設置了過期時間的key并進行處理。測試到的已過期的key將被刪除。具體的算法如下:
Redis配置項hz定義了serverCron任務的執行周期,默認為10,即CPU空閑時每秒執行10次;
每次過期key清理的時間不超過CPU時間的25%,即若hz=1,則一次清理時間最大為250ms,若hz=10,則一次清理時間最大為25ms;
清理時依次遍歷所有的db;
從db中隨機取20個key,判斷是否過期,若過期,則逐出;
若有5個以上key過期,則重復步驟4,否則遍歷下一個db;
在清理過程中,若達到了25%CPU時間,退出清理過程;
這是一個基于概率的簡單算法,基本的假設是抽出的樣本能夠代表整個key空間,redis持續清理過期的數據直至將要過期的key的百分比降到了25%以下。
由于算法采用的隨機取key判斷是否過期的方式,故幾乎不可能清理完所有的過期Key。
調高hz參數可以提升清理的頻率,過期key可以更及時的被刪除,但hz太高會增加CPU時間的消耗。
在redis中,允許用戶設置最大使用內存大小maxmemory(需要配合maxmemory-policy使用),設置為0表示不限制(默認配置)。 生產環境中需要設置此值,最好不超過內存60%-70%。 當redis內存數據集快到達maxmemory時,redis會實行數據淘汰策略。
Redis提供6種數據淘汰策略。在逐出算法中,根據用戶設置的逐出策略,選出待逐出的key,直到當前內存小于最大內存值為止。
可選逐出策略如下:
volatile-lru:從已設置過期時間的數據集中挑選最近最少使用的數據淘汰
volatile-ttl:從已設置過期時間的數據集中挑選將要過期的數據淘汰
volatile-random:從已設置過期時間的數據集中任意選擇數據 淘汰
allkeys-lru:從數據集中挑選最近最少使用的數據淘汰
allkeys-random:從數據集中任意選擇數據淘汰
no-enviction(驅逐):禁止驅逐數據
在redis2.8中默認策略是volatile-lru
在redis3.2和redis4.0中默認策略是no-eviction
如果使用no-eviction時,當內存不足,Redis會返回OOM的錯誤信息
(error) OOM command not allowed when used memory > 'maxmemory'.
當cache中沒有符合清除條件的key時,回收策略 volatile-lru, volatile-random 和volatile-ttl 將會和策略 noeviction 一樣直接返回錯誤。
選擇正確的回收策略是很重要的,取決于你的應用程序的訪問模式。使用INFO命令輸出來監控緩存命中和錯過的次數,以調優Redis的配置。
通用規則如下:
如果期望用戶請求呈現冪律分布(power-law distribution),也就是,期望一部分子集元素被訪問得遠比其他元素多時,可以使用allkeys-lru策略。
如果期望是循環周期的訪問,所有的鍵被連續掃描,或者期望請求符合平均分布(每個元素以相同的概率被訪問),可以使用allkeys-random策略。
如果期望是讓redis使用緩存對象設置的TTL值,確定哪些對象應該是較好的清除候選項,可以使用volatile-ttl策略。
以上是“Redis中過期鍵刪除策略和數據逐出策略的示例分析”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。