redis過時策略和內存淘汰機制

常見的刪除策略

1.定時刪除:在設置鍵的過時時間的同時,建立一個timer,讓定時器在鍵的過時時間到達時,當即執行對鍵的刪除操做。(主動刪除)數據庫

對內存友好,可是對cpu時間不友好,有較多過時鍵的而狀況下,刪除過時鍵會佔用至關一部分cpu時間。dom

2.惰性刪除:聽任過時鍵無論,可是每次從鍵空間中獲取鍵時,都檢查取到的鍵是否過去,若是過時就刪除,若是沒過時就返回該鍵。(被動刪除)code

對cpu時間友好,程序只會在取出鍵的時候纔會對鍵進行過時檢查,這不會在刪除其餘無關過時鍵上花費任何cpu時間,可是若是一個鍵已通過期,而這個鍵又保留在數據庫中,那麼只要這個過時鍵不被刪除,他所佔用的內存就不會釋放,對內存不友好。server

3.按期刪除:每隔一段時間就對數據庫進行一次檢查,刪除裏面的過時鍵。(主動刪除)對象

採用對內存和cpu時間折中的方法,每一個一段時間執行一次刪除過時鍵操做,並經過限制操做執行的時長和頻率來減小對cpu時間的影響。難點在於,選擇一個好的策略來設置刪除操做的時長和執行頻率。內存

redis使用的過時策略:按期刪除+惰性刪除

按期刪除

redis 會將每一個設置了過時時間的 key 放入到一個獨立的字典中,之後會按期遍歷這個字典來刪除到期的 key。it

Redis 默認會每秒進行十次過時掃描(100ms一次),過時掃描不會遍歷過時字典中全部的 key,而是採用了一種簡單的貪心策略。io

  • 從過時字典中隨機 20 個 key;
  • 刪除這 20 個 key 中已通過期的 key;
  • 若是過時的 key 比率超過 1/4,那就重複步驟 1;

redis默認是每隔 100ms就隨機抽取一些設置了過時時間的key,檢查其是否過時,若是過時就刪除。注意這裏是隨機抽取的。爲何要隨機呢?你想想假如 redis 存了幾十萬個 key ,每隔100ms就遍歷全部的設置過時時間的 key 的話,就會給 CPU 帶來很大的負載!class

惰性刪除

所謂惰性策略就是在客戶端訪問這個key的時候,redis對key的過時時間進行檢查,若是過時了就當即刪除,不會給你返回任何東西。

按期刪除可能會致使不少過時key到了時間並無被刪除掉。因此就有了惰性刪除。假如你的過時 key,靠按期刪除沒有被刪除掉,還停留在內存裏,除非你的系統去查一下那個 key,纔會被redis給刪除掉。這就是所謂的惰性刪除,即當你主動去查過時的key時,若是發現key過時了,就當即進行刪除,不返回任何東西.

按期刪除是集中處理,惰性刪除是零散處理。

爲何要採用按期刪除+惰性刪除2種策略呢?

若是過時就刪除。假設redis裏放了10萬個key,都設置了過時時間,你每隔幾百毫秒,就檢查10萬個key,那redis基本上就死了,cpu負載會很高的,消耗在你的檢查過時key上了.

可是問題是,按期刪除可能會致使不少過時key到了時間並無被刪除掉,那咋整呢?因此就是惰性刪除了。這就是說,在你獲取某個key的時候,redis會檢查一下 ,這個key若是設置了過時時間那麼是否過時了?若是過時了此時就會刪除,不會給你返回任何東西。

並非key到時間就被刪除掉,而是你查詢這個key的時候,redis再懶惰的檢查一下

經過上述兩種手段結合起來,保證過時的key必定會被幹掉。

因此說用了上述2種策略後,下面這種現象就不難解釋了:數據明明都過時了,可是還佔有着內存

redis內存淘汰機制

可是僅僅經過設置過時時間仍是有問題的。咱們想一下:若是按期刪除漏掉了不少過時 key,而後你也沒及時去查,也就沒走惰性刪除,此時會怎麼樣?若是大量過時key堆積在內存裏,致使redis內存快耗盡了。redis是如何解決這個問題呢? 使用redis 內存淘汰機制

這個問題可能有小夥伴們遇到過,放到Redis中的數據怎麼沒了?

由於Redis將數據放到內存中,內存是有限的,好比redis就只能用10個G,你要是往裏面寫了20個G的數據,會咋辦?固然會幹掉10個G的數據,而後就保留10個G的數據了。那幹掉哪些數據?保留哪些數據?固然是幹掉不經常使用的數據,保留經常使用的數據了

redis 提供 6種數據淘汰策略:

  • no-eviction:不會繼續服務寫請求(DEL請求能夠繼續服務),讀請求能夠繼續進行。這樣能夠保證不會丟失數據,可是會讓線上的業務不能持續進行。這是默認的淘汰策略。
  • volatile-lru:嘗試淘汰設置了過時時間的 key,最少使用的 key 優先被淘汰。沒有設置過時時間的key不會被淘汰,這樣能夠保證須要持久化的數據不會忽然丟失。(這個是使用最多的)
  • volatile-ttl:跟上面同樣,除了淘汰的策略不是 LRU,而是 key 的剩餘壽命 ttl 的值,ttl 越小越優先被淘汰,即淘汰將要過時的數據.
  • volatile-random:從已設置過時時間的數據集(server.db[i].expires)中隨機選擇數據淘汰
  • allkeys-lru:區別於 volatile-lru,這個策略要淘汰的 key 對象是全體的 key 集合,而不僅是過時的 key 集合。這意味着沒有設置過時時間的 key 也會被淘汰。
  • allkeys-random:從全體的key集合(server.db[i].dict)中任意選擇數據淘汰
配置方式:
maxmemory-policy volatile-lru   #默認是noeviction,即不進行數據淘汰
相關文章
相關標籤/搜索