Redis過時策略

1、設置過時時間

expire key time(以秒爲單位) -- 這是最經常使用的方式redis

setex(String key, int seconds, String value) -- 字符串獨有的方式算法

注:除了字符串本身獨有設置過時時間的方法外,其餘數據類型都須要依靠expire方法來設置過時時間。若是設置了過時時間,以後又想讓緩存永不過時,使用persist key。沒有設置過時時間的狀況:Redis不管有沒有設置expire,其實都會遵循redis的配置好的刪除機制,在配置文件裏設置:數據庫

  • redis最大內存不足"時,數據清除策略,默認爲"volatile-lru"。
  • volatile-lru  -> 對"過時集合"中的數據採起LRU算法,若是對key使用"expire"指令指定了過時時間,那麼此key將會被添加到"過時集合"中。將已通過期/LRU的數據優先移除.若是"過時集合"中所有移除仍不能知足內存需求,將OOM。
  • allkeys-lru ->對全部的數據,採用LRU算法。
  • volatile-random ->對"過時集合"中的數據採起"隨即選取"算法,並移除選中的K-V,直到"內存足夠"爲止. 若是若是"過時集合"中所有移除所有移除仍不能知足,將OOM。
  • allkeys-random ->對全部的數據,採起"隨機選取"算法,並移除選中的K-V,直到"內存足夠"爲止。
  • volatile-ttl ->對"過時集合"中的數據採起TTL算法(最小存活時間),移除即將過時的數據。
  • noeviction ->不作任何干擾操做,直接返回OOM異常

若是數據的過時不會對"應用系統"帶來異常,且系統中write操做比較密集,建議採起"allkeys-lru"。對於沒有設置expire的數據,產生影響的是allkeys-lru機制,allkeys-random。因此redis沒有設置expire的數據是否會刪除,是由你本身選擇的刪除機制決定的。在Redis服務器佔用內存達到maxmemory最大的狀況下,當再想增長內存佔用時,會按maxmemory-policy刪除機制將老的數據刪除。volatile-lru機制,Redis會按LRU算法刪除設置了過時時間但尚未過時的key,而對於沒有設置過時時間的key,Redis是永遠保留的。固然,若是你不想刪除沒有過時的key,那可使用noeviction機制。緩存

 

 

 

2、3種過時策略

  a.定時刪除服務器

        含義:在設置key的過時時間的同時,爲該key建立一個定時器,讓定時器在key的過時時間來臨時,對key進行刪除併發

        優勢:保證內存被儘快釋放dom

        缺點:若過時key不少,刪除這些key會佔用不少的CPU時間,在CPU時間緊張的狀況下,CPU不能把全部的時間用來作要緊的事兒,還須要去花時間刪除這些key。而且定時器的建立耗時,若爲每個設置過時時間的key建立一個定時器(將會有大量的定時器產生),性能影響嚴重。memcached

    b.懶漢式刪除性能

        含義:key過時的時候不刪除,每次經過key獲取值的時候去檢查是否過時,若過時則刪除key返回null,若未過時直接執行響應操做。spa

        優勢:刪除操做只發生在經過key取值的時候發生,並且只刪除當前key,因此對CPU時間的佔用是比較少的,並且此時的刪除是已經到了非作不可的地步(若是此時還不刪除的話,咱們就會獲取到了已通過期的key了)

        缺點:若大量的key在超出超時時間後,好久一段時間內,都沒有被獲取過,那麼可能發生內存泄露(無用的垃圾佔用了大量的內存)

    c.按期刪除

        含義:每隔一段時間執行一次刪除過時key操做

        優勢:經過限制刪除操做的時長和頻率,來減小刪除操做對CPU時間的佔用--處理"定時刪除"的缺點。按期刪除過時key--處理"懶漢式刪除"的缺點

        缺點:在內存友好方面,不如"定時刪除"(會形成必定的內存佔用,可是沒有懶漢式那麼佔用內存)。 在CPU時間友好方面,不如"懶漢式刪除"(會按期的去進行比較和刪除操做,cpu方面不如懶漢式,可是比定時好)

 

 memcached只用了惰性刪除,而redis同時使用了惰性刪除與按期刪除

  懶漢式刪除:並非只有獲取key的時候纔會檢查key是否過時,在某些設置key的方法上也會檢查(eg.setnx key2 value2:該方法相似於memcached的add方法,若是設置的key2已經存在,那麼該方法返回false,什麼都不作;若是設置的key2不存在,那麼該方法設置緩存key2-value2。假設調用此方法的時候,發現redis中已經存在了key2,可是該key2已通過期了,若是此時不執行刪除操做的話,setnx方法將會直接返回false,也就是說此時並無從新設置key2-value2成功,因此對於必定要在setnx執行以前,對key2進行過時檢查)。

 

3、Redis採用的過時策略

    懶漢式刪除+按期刪除

        懶漢式刪除流程:

      在進行get或setnx等操做時,先檢查key是否過時;
       若過時,刪除key,而後執行相應操做;
        若沒過時,直接執行相應操做;
       

    按期刪除流程(簡單而言,對指定個數個庫的每個庫隨機刪除小於等於指定個數個過時key):

      遍歷每一個數據庫(就是redis.conf中配置的"database"數量,默認爲16)
       檢查當前庫中的指定個數個key(默認是每一個庫檢查20個key,注意至關於該循環執行20次,循環體是下邊的描述)
        若是當前庫中沒有一個key設置了過時時間,直接執行下一個庫的遍歷
        隨機獲取一個設置了過時時間的key,檢查該key是否過時,若是過時,刪除key
         判判定期刪除操做是否已經達到指定時長,若已經達到,直接退出按期刪除。


    對於按期刪除,在程序中有一個全局變量current_db來記錄下一個將要遍歷的庫,假設有16個庫,咱們這一次按期刪除遍歷了10個,那此時的current_db就是11,下一次按期刪除就從第11個庫開始遍歷,假設current_db等於15了,那麼以後遍歷就再從0號庫開始(此時current_db==0)。
    在實際中,若是咱們要本身設計過時策略,在使用懶漢式刪除+按期刪除時,控制時長和頻率這個尤其關鍵,須要結合服務器性能,已經併發量等狀況進行調整,以至最佳。

相關文章
相關標籤/搜索