您好,登錄后才能下訂單哦!
這篇“Redis的過期策略和內存淘汰策略怎么用”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“Redis的過期策略和內存淘汰策略怎么用”文章吧。
expire key seconds 時間復雜度:O(1)
設置key
的過期時間。超時后,將會自動刪除該key
。在Redis的術語中一個key
的相關超時是volatile的。
超時后只有對key
執行DEL、SET、GETSET時才會清除。 這意味著,從概念上講所有改變key
而不用新值替換的所有操作都將保持超時不變。 例如,使用 INCR
遞增key的值,執行 LPUSH
將新值推到 list 中或用 HSET
改變hash的field
,這些操作都使超時保持不變。
使用 PERSIST
命令可以清除超時,使其變成一個永久key
若 key
被 RENAME
命令修改,相關的超時時間會轉移到新key
若 key
被 RENAME
命令修改,比如原來就存在 Key_A
,然后調用 RENAME Key_B Key_A
命令,這時不管原來 Key_A
是永久的還是設為超時的,都會由Key_B
的有效期狀態覆蓋
注意,使用非正超時調用 EXPIRE/PEXPIRE 或具有過去時間的 EXPIREAT/PEXPIREAT 將導致key被刪除而不是過期(因此,發出的key事件將是 del,而不是過期)。
對已經有過期時間的key
執行EXPIRE
操作,將會更新它的過期時間。有很多應用有這種業務場景,例如記錄會話的session。
在 Redis 版本之前 2.1.3 中,使用更改其值的命令更改具有過期集的密鑰具有完全刪除key的效果。由于現在修復的復制層中存在限制,因此需要此語義。
EXPIRE 將返回 0,并且不會更改具有超時集的鍵的超時。
1
如果成功設置過期時間。
0
如果key
不存在或者不能設置過期時間。
假設有一 Web 服務,對用戶最近訪問的最新 N 頁感興趣,這樣每個相鄰頁面視圖在上一個頁面之后不超過 60 秒。從概念上講,可以將這組頁面視圖視為用戶的導航會話,該會話可能包含有關ta當前正在尋找的產品的有趣信息,以便你可以推薦相關產品。
可使用以下策略輕松在 Redis 中對此模式建模:每次用戶執行頁面視圖時,您都會調用以下命令:
MULTI RPUSH pagewviews.user:<userid> http://..... EXPIRE pagewviews.user:<userid> 60 EXEC
如果用戶空閑超過 60 秒,則將刪除該key,并且僅記錄差異小于 60 秒的后續頁面視圖。 此模式很容易修改,使用 INCR 而不是使用 RPUSH 的列表。
通常,創建 Redis 鍵時沒有關聯的存活時間。key將永存,除非用戶以顯式方式(例如 DEL 命令)將其刪除。 EXPIRE 族的命令能夠將過期項與給定key關聯,但代價是該key使用的額外內存。當key具有過期集時,Redis 將確保在經過指定時間時刪除該key。 可使用 EXPIRE 和 PERSIST 命令(或其他嚴格命令)更新或完全刪除生存的關鍵時間。
在 Redis 2.4 中,過期可能不準確,并且可能介于 0 到 1 秒之間。 由于 Redis 2.6,過期誤差從 0 到 1 毫秒。
過期信息的鍵存儲為絕對 Unix 時間戳(Redis 版本 2.6 或更高版本為毫秒)。這意味著即使 Redis 實例不處于活動狀態,時間也在流動。 要使過期工作良好,必須穩定計算機時間。若將 RDB 文件從兩臺計算機上移動,其時鐘中具有大 desync,則可能會發生有趣的事情(如加載時加載到過期的所有key)。 即使運行時的實例,也始終會檢查計算機時鐘,例如,如果將一個key設置為 1000 秒,然后在將來設置計算機時間 2000 秒,則該key將立即過期,而不是持續 1000 秒。
鍵的過期方式有兩種:被動方式 - 惰性刪除,主動方式 - 定期刪除。
當客戶端嘗試訪問key時,key會被動過期,即Redis會檢查該key是否設置了過期時間,如果過期了就會刪除,也不會返回任何東西。 注意并非是key到期了就會被自動刪除,而是當查詢該key時,Redis再很懶惰地檢查是否刪除。這和 spring 的延遲初始化有著異曲同工之妙。
當然,這是不夠的,因為有過期的key,永遠不會再訪問。無論如何,這些key都應過期,因此請定期 Redis 在具有過期集的key之間隨機測試幾個key。已過期的所有key將從key空間中刪除。
具體來說,如下 Redis 每秒 10 次:
測試 20 個帶有過期的隨機鍵
刪除找到的所有已過期key
如果超過 25% 的key已過期,從步驟 1 重新開始
這是一個微不足道的概率算法,基本上假設我們的樣本代表整個key空間,繼續過期,直到可能過期的key百分比低于 25%。 這意味著在任何給定時刻,使用內存的已過期的最大鍵量等于最大寫入操作量/秒除以 4。
為了在不犧牲一致性的情況下獲得正確行為,當key過期時,DEL 操作將同時在 AOF 文件中合成并獲取所有附加的從節點。這樣,過期的這個處理過程集中到主節點中,還沒有一致性錯誤的可能性。
但是,雖然連接到主節點的從節點不會獨立過期key(但會等待來自master的 DEL),但它們仍將使用數據集中現有過期的完整狀態,因此,當選擇slave作為master時,它將能夠獨立過期key,完全充當master。
可是,很多過期key,你沒及時去查,定期刪除也漏掉了,大量過期key堆積內存,Redis內存殆耗盡!
因此還需有內存淘汰機制!
不會繼續服務寫請求 (DEL 請求可以繼續服務),讀請求可以繼續進行。這樣 可以保證不會丟失數據,但是會讓線上的業務不能持續進行。
config.c
createEnumConfig("maxmemory-policy", NULL, MODIFIABLE_CONFIG, maxmemory_policy_enum, server.maxmemory_policy, MAXMEMORY_NO_EVICTION, NULL, NULL),
當內存不足以容納新寫入數據時,在鍵空間中,隨機移除某key。憑啥隨機呢,至少也是把最近最少使用的key刪除。
當內存不足以容納新寫入數據時,在鍵空間中,移除最近最少使用的key,沒有設置過期時間的 key 也會被淘汰。
LRU的關鍵是看頁面最后一次被使用到發生調度的時間長短,而LFU關鍵是看一定時間段內頁面被使用的頻率。
嘗試淘汰設置了過期時間的 key,最少使用的 key 優先被淘汰。 沒有設置過期時間的 key 不會被淘汰,這樣可以保證需要持久化的數據不會突然丟失。 區別于 allkey-lru,這個策略要淘汰只是過期的 key 集合。
淘汰的 key 是過期 key 集合中隨機的 key。
淘汰的策略不是 LRU,而是 key 的剩余壽命 ttl 的值,ttl 越小越優先被淘汰。
volatile-xxx 策略只會針對帶過期時間的 key 進行淘汰,allkeys-xxx 策略會對所有的 key 進行淘汰。
如果你只是拿 Redis 做緩存,那應該使用 allkeys-xxx,客戶端寫緩存時不必攜帶過期時間。
如果你還想同時使用 Redis 的持久化功能,那就使用 volatile-xxx 策略,這樣可以保留沒有設置過期時間的 key,它們是永久的 key 不會被 LRU 算法淘汰。
確實有時會問這個,因為有些候選人如果確實過五關斬六將,前面的問題都答的很好,那么其實讓他寫一下LRU算法,可以考察一下編碼功底
你可以現場手寫最原始的LRU算法,那個代碼量太大了,不太現實
public class LRUCache<K, V> extends LinkedHashMap<K, V> { private final int CACHE_SIZE; // 這里就是傳遞進來最多能緩存多少數據 public LRUCache(int cacheSize) { // true指linkedhashmap將元素按訪問順序排序 super((int) Math.ceil(cacheSize / 0.75) + 1, 0.75f, true); CACHE_SIZE = cacheSize; } @Override protected boolean removeEldestEntry(Map.Entry eldest) { // 當KV數據量大于指定緩存個數時,就自動刪除最老數據 return size() > CACHE_SIZE; } }
以上就是關于“Redis的過期策略和內存淘汰策略怎么用”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。