Redis的過時策略及內存淘汰機制

關注公衆號:xy的技術圈算法

Redis的用途很是普遍。做爲一個高性能的內存數據庫,它常常被用於緩存的業務場景。數據庫

所謂緩存,即在第一次獲取到數據的時候,把它暫存在內存中。這樣下次須要這個數據的時候,就直接從內存中取,不用再去查詢數據庫或調用遠程接口,這樣能夠極大地提升應用程序的性能。緩存

若是緩存中的數據永久存在,那佔用的內存就會變得愈來愈大。而內存是有限的,因此緩存系統須要在須要的時候刪除一些沒必要要的緩存數據以節約內存空間。bash

Redis提供了兩種機制配合來達到上述目的:過時策略內存淘汰機制dom

過時策略

使用過Redis的同窗應該知道,咱們在設置一個key以後,能夠指定這個key的過時時間。那麼這個key到了過時時間就會當即被刪除嗎?Redis是如何刪除這些過時key的呢?性能

經常使用命令

先說結論:Redis是使用按期刪除+惰性刪除二者配合的過時策略。網站

按期刪除spa

按期刪除指的是Redis默認每隔100ms就隨機抽取一些設置了過時時間的key,檢測這些key是否過時,若是過時了就將其刪掉。操作系統

由於key太多,若是全盤掃描全部的key會很是耗性能,因此是隨機抽取一些key來刪除。這樣就有可能刪除不完,須要惰性刪除配合。code

惰性刪除

惰性刪除再也不是Redis去主動刪除,而是在客戶端要獲取某個key的時候,Redis會先去檢測一下這個key是否已通過期,若是沒有過時則返回給客戶端,若是已通過期了,那麼Redis會刪除這個key,不會返回給客戶端。

因此惰性刪除能夠解決一些過時了,但沒被按期刪除隨機抽取到的key。但有些過時的key既沒有被隨機抽取,也沒有被客戶端訪問,就會一直保留在數據庫,佔用內存,長期下去可能會致使內存耗盡。因此Redis提供了內存淘汰機制來解決這個問題。

爲何不使用定時刪除?所謂定時刪除,指的是用一個定時器來負責監視key,當這個key過時就自動刪除,雖然內存及時釋放,可是十分消耗CPU資源,所以通常不推薦採用這一策略。

內存淘汰機制

Redis在使用內存達到某個閾值(經過maxmemory配置)的時候,就會觸發內存淘汰機制,選取一些key來刪除。內存淘汰有許多策略,下面分別介紹這幾種不一樣的策略。

# maxmemory <bytes> 配置內存閾值
# maxmemory-policy noeviction 
複製代碼
  • noeviction:當內存不足以容納新寫入數據時,新寫入操做會報錯。默認策略
  • allkeys-lru:當內存不足以容納新寫入數據時,在鍵空間中,移除最近最少使用的key。
  • allkeys-random:當內存不足以容納新寫入數據時,在鍵空間中,隨機移除某個key。
  • volatile-lru:當內存不足以容納新寫入數據時,在設置了過時時間的鍵空間中,移除最近最少使用的key。
  • volatile-random:當內存不足以容納新寫入數據時,在設置了過時時間的鍵空間中,隨機移除某個key。
  • volatile-ttl:當內存不足以容納新寫入數據時,在設置了過時時間的鍵空間中,有更早過時時間的key優先移除。

如何選取合適的策略?比較推薦的是兩種lru策略。根據本身的業務需求。若是你使用Redis只是做爲緩存,不做爲DB持久化,那推薦選擇allkeys-lru;若是你使用Redis同時用於緩存和數據持久化,那推薦選擇volatile-lru。

LRU是Least Recently Used的縮寫,即最近最少使用。LRU源於操做系統的一種頁面置換算法,選擇最近最久未使用的頁面予以淘汰。在Redis裏,就是選擇最近最久未使用的key進行刪除。

持久化如何處理過時?

前面的文章裏面介紹了Redis的兩種持久化策略:RDB和AOF。在持久化和數據恢復階段,對過時key也有一些特殊的處理。

RDB

從內存數據庫持久化數據到RDB文件:持久化key以前,會檢查是否過時,過時的key不進入RDB文件 從RDB文件恢復數據到內存數據庫:數據載入數據庫以前,會對key先進行過時檢查,若是過時,不導入數據庫(主庫狀況)。

AOF

從內存數據庫持久化數據到AOF文件:當key過時後,尚未被刪除,此時進行執行持久化操做(該key是不會進入aof文件的,由於沒有發生修改命令) 當key過時後,在發生刪除操做時,程序會向aof文件追加一條del命令(在未來的以aof文件恢復數據的時候該過時的鍵就會被刪掉) AOF重寫:重寫時,會先判斷key是否過時,已過時的key不會重寫到aof文件

認真寫文章,用心作分享。

我的網站:yasinshaw.com

公衆號:xy的技術圈

相關文章
相關標籤/搜索