Redis學習筆記—Redis的緩存過期和淘汰政策
1.性能簡介
- Redis性能高:
- 官方資料
- 讀:110000次/s
- 寫:81000次/s
- 長期使用,key會不斷增加,Redis作為緩存使用,實體記憶體也會滿
- 記憶體與硬碟交換(swap) 虛拟記憶體 ,頻繁IO 性能急劇下降
2.maxmemory:作為redis最大實體記憶體
-
不設定的場景,作為DB使用
- Redis的key是固定的,不會增加
- Redis作為DB使用,保證資料的完整性,不能淘汰 , 可以做叢集,橫向擴充
- 緩存淘汰政策:禁止驅逐 (預設)
-
設定的場景
- Redis是作為緩存使用,不斷增加Key
- maxmemory : 預設為0 不限制
-
:達到實體記憶體後性能急劇下架,甚至崩潰,這是為什麼?問題
:記憶體與硬碟交換(swap) 虛拟記憶體 ,頻繁IO 性能急劇下降答
-
設定多少?
- 與業務有關
- 1個Redis執行個體,保證系統運作 1 G ,剩下的就都可以設定Redis,實體記憶體的3/4
- slaver : 留出一定的記憶體
- 在redis.conf 設定屬性
,如果數字後面沒有機關一律按照B結尾maxmemory 1024mb
-
: 獲得maxmemory數 `CONFIG GET maxmemory指令
- 設定maxmemory後,當趨近maxmemory時,通過緩存淘汰政策,從記憶體中删除對象
- 不設定maxmemory 無最大記憶體限制 maxmemory-policy noeviction (禁止驅逐) 不淘汰
- 設定maxmemory,在配置檔案中maxmemory-policy(淘汰政策) 要配置
3. expire資料結構
- 在
中可以使用Redis
指令設定一個鍵的存活時間expire
,過了這段時間,該鍵就會自動被删除。(ttl: time to live)
4.expire原理
- 上面的代碼是Redis 中關于資料庫的結構體定義,這個結構體定義中除了 id 以外都是指向字典的指針,其中我們隻看 dict 和 expires。
- dict 用來維護一個 Redis 資料庫中包含的所有 Key-Value 鍵值對,expires則用于維護一個 Redis 資料庫中設定了失效時間的鍵(即key與失效時間的映射)。
- 當我們使用 expire指令設定一個key的失效時間時,Redis 首先到 dict 這個字典表中查找要設定的key是否存在,如果存在就将這個key和失效時間添加到 expires 這個字典表。
- 當我們使用 setex指令向系統插入資料時,Redis 首先将 Key 和 Value 添加到 dict 這個字典表中,然後将 Key 和失效時間添加到 expires 這個字典表中。
- 簡單地總結來說就是,設定了失效時間的key和具體的失效時間全部都維護在 expires 這個字典表中。
5.删除政策
- Redis的資料删除有定時删除、惰性删除和主動删除三種方式。
- Redis目前采用惰性删除+主動删除的方式。
- 定時删除
- 在設定鍵的過期時間的同時,建立一個定時器,讓定時器在鍵的過期時間來臨時,立即執行對鍵的删除操作。
- 需要建立定時器,而且消耗CPU,一般不推薦使用。
- 惰性删除
- 在key被通路時如果發現它已經失效,那麼就删除它。
- 調用expireIfNeeded函數,該函數的意義是:讀取資料之前先檢查一下它有沒有失效,如果失效了就删除它。
- 主動删除
- 在redis.conf檔案中可以配置主動删除政策,預設是no-enviction(不删除)
- 在redis.conf檔案中可以配置
maxmemory-policy allkeys-lru
6.LRU簡介
- LRU (Least recently used) 最近最少使用,算法根據資料的曆史通路記錄來進行淘汰資料,其核心思想是“如果資料最近被通路過,那麼将來被通路的幾率也更高”。
- 最常見的實作是使用一個連結清單儲存緩存資料,詳細算法實作如下:
- 新資料插入到連結清單頭部;
- 每當緩存命中(即緩存資料被通路),則将資料移到連結清單頭部;
- 當連結清單滿的時候,将連結清單尾部的資料丢棄。
- 在Java中可以使用LinkHashMap(哈希連結清單)去實作LRU
- 讓我們以使用者資訊的需求為例,來示範一下LRU算法的基本思路:
- 假設我們使用哈希連結清單來緩存使用者資訊,目前緩存了4個使用者,這4個使用者是按照時間順序依次從連結清單右端插入的。
7.LRU資料淘汰機制
- 在伺服器配置中儲存了 lru 計數器 server.lrulock,會定時(redis 定時程式 serverCorn())更新,server.lrulock 的值是根據 server.unixtime 計算出來的。
- 另外,從redisObject 中可以發現,每一個 redis 對象都會設定相應的 lru。可以想象的是,每一次通路資料的時候,會更新 redisObject.lru。
- LRU 資料淘汰機制是這樣的:在資料集中随機挑選幾個鍵值對,取出其中 lru 最大的鍵值對淘汰。
- 不可能周遊key 用
越大 說明 通路間隔時間越長目前時間-最近通路
8. 緩存淘汰政策的選擇
-
: 不删除政策, 達到最大記憶體限制時, 如果需要更多記憶體, 直接傳回錯誤資訊。 大多數寫指令都會導緻占用更多的記憶體(有極少數會例外, 如 DEL )。noeviction
-
: 所有key通用; 優先删除最近最少使用(less recently used ,LRU) 的 key,在不确定時一般采用政策。 冷熱資料交換allkeys-lru
-
: 隻限于設定了 expire 的部分; 優先删除最近最少使用(less recently used ,LRU) 的 key,比allkeys-lru性能差,存過期時間volatile-lru
-
: 希望請求符合平均分布(每個元素以相同的機率被通路)allkeys-random
-
: 隻限于設定了 expire 的部分; 随機删除一部分 key。volatile-random
-
:自己控制,隻限于設定了 expire 的部分; 優先删除剩餘時間(time to live,TTL) 短的key,緩存穿透volatile-ttl