14.5 緩存數據的刪除和替換
14.5.1 過期數據
可以使用ttl查看key的狀態。已過期的數據,redis并未馬上刪除。優先去執行讀寫數據操作,刪除操作延后執行。
14.5.2 刪除策略
redis中每一個value對應一個內存地址,在expires,一個內存地址,對應一個時間截,如果達到指定時間,就完成刪除處理
三種刪除策略
-
定時刪除:創建一個定時器,當key設置過期時間已到達,刪除key,同時expires中也刪除
- 優點:節約內存
- 缺點:對于cpu實時處理壓力影響,對redis執行的效率有影響
-
惰性刪除:數據到達過期時間,先不做刪除,直到下次訪問該數據時,再做刪除(以空間換時間)
- 執行流程:在get數據時,先執行redis中一個內部函數 expireIfNeeded(),如果沒有過期,就返回,如果已過期,就刪除,返回-2
- 優點:節約CPU資源
- 缺點:內存占用過大。
-
定期刪除
- redis啟動服務時,讀取server.hz的值,默認為10,可以通過info server指令查看
- 每秒鐘執行server.hz次定時輪詢,調用serverCron()函數,函數中又執行databasesCron(),對16數據庫進行輪詢,執行了activeExpireCycle(),檢測其中元素的過期情況。每次輪詢都執行250ms/server.hz時長。隨機從對應的庫中抽取20個(默認)key進行檢測
- 如果key已過期,則刪除key
- 如果一輪中刪除的key數量>w*25%,則再次循環剛才的過程
- 如果一輪中刪除的key數量<=w*25%,則開始檢查下一個庫
redis中使用惰性刪除和定期刪除
14.5.3 逐出算法
通過 配置文件 maxmemory < bytes>來設置最大緩存容量。一般情況,建議設置為總數據的15%到30%,在實際生產環境下,可以設置50%。如果不設置,默認全部使用
redis緩存淘汰策略
在redis默認情況下,不進行數據淘汰noevction,一旦緩存被寫滿了,再有寫請求,redis直接返回錯誤。
過期數據淘汰策略,先限定了,數據都是在過期范圍。
- valotile-ttl:在進行篩選時,根據過期時間先后順序進行一個刪除,越早過期的越先被刪除
- valotile-random:在設置了過期時間的鍵值對中,進行隨機刪除
- valotile-lru:會使用LRU算法篩選設置了過期的鍵值對
- valotile-lfu:會使用LFU算法篩選設置了過期的鍵值對
所有數據淘汰策略:
- allkeys-random:從所有鍵值對中隨機篩選并刪除
- allkeys-lru:從所有鍵值對中采用LRU算法進行篩選刪除
- allkeys-lfu:從所有鍵值對中采用LFU算法進行篩選刪除
LRU算法
算法Least Recently Used,最近最少使用原則,最近不用的數據會被篩選出來,最近頻繁使用的數據會保留
lru算法,需要使用鏈表來管理所有緩存數據,帶來內存開銷。有數據被訪問時,需要執行鏈表數據的移動,會降低redis性能。
記錄數據最后一次訪問的時間截,第一次會隨機選出N個數據,作為一個候選集合,作一個排序,再把lru最小的數據進行淘汰
上面提到的N的配置:maxmemory-samples 5
LFU算法
算法Least Frequently Used,最不常用原則。根據歷史訪問頻率來淘汰數據。
每個數據塊都有一個引用計數,按引用計數來排序。如果引用計數相同,按照時間排序
- 新加入的數據放在隊尾,引用計為1
- 當數據被訪問,引用計數增加,隊列重排
- 當需要淘汰數據時,將隊列尾部的數據塊刪除
逐出算法選擇:maxmemory-policy noeviction
- 優先使用allkeys-lru策略。
- 如果業務數據訪問頻率差別不大,可以建議使用allkeys-random。
- 首推的新聞、置頂視頻,不設置過期時間,可以建議使得volatile-lru。