文章首發於公衆號:蘑菇睡不着,歡迎來看看
Redis 中都是鍵值對的存儲形式,鍵都是字符串類型的,而值有不少種類型,如 string、list、hash、set、sorted set等類型。當設置鍵值對時咱們還應該爲其設置過時時間,經過 expire 以及 pexpire 命令;還能夠經過 setnx 命令設置。那麼,當設置過時時間以後,究竟是怎麼將過時的鍵值對刪除的那?想知道答案的話,咱們就一塊兒看看 Redis 的過時鍵刪除策略。
在說刪除策略以前有個點帶你們先了解下,那就是若是肯定一個鍵是否過時,這裏我總結了下: redis
1) 檢查這個鍵是否在過時字典中,若是存在,那麼取出這個鍵的過時時間。(過時字典存儲的是每一個鍵的過時時間,字典中 key 是 鍵, value 是 long 類型的過時時間)
2) 拿到過時時間以後,和當前 UNIX 時間戳比較,若是大於,則鍵過時。數據庫
以上就是判斷一個鍵是否過時的方法。接下來講說當鍵過時了怎麼去刪除。 服務器
目前來講有三種刪除策略:函數
下面來詳細介紹每一種刪除策略。學習
定時刪除策略
優勢是:對內存友好。由於經過定時器,當一個鍵到達過時時間時就會立馬被刪除,直接就釋放了內存。
缺點是:對 CPU 不友好。由於若是過時鍵比較多,那麼刪除這些過時鍵會佔用至關一部分CPU時間,若是CPU時間很是緊張的話,還將CPU時間用在刪除和當前任務無關的過時鍵上,會對服務器的響應時間以及吞吐量形成影響。
所以,經過 定時刪除 策略來時間過時鍵的刪除不太現實。ip
惰性刪除策略優勢:對 CPU 時間友好。程序只會在取出鍵時纔會判斷是否刪除,而且只做用到當前鍵上,其餘過時鍵不會花費 CPU 時間去處理。
惰性刪除策略缺點:對內存不友好。由於只有鍵被使用時纔會去檢查是否刪除,若是有大量的鍵一直不被使用,那麼這些鍵就算過時了也不會被刪除,會一直佔用着內存。這種能夠理解爲是一種內存泄漏——大量無用的數據一直佔用着內存,而且不會被刪除。內存
相比較定時刪除對CPU的不友好,惰性刪除的對內存不友好。按期刪除採用了一種折中的方式:字符串
但刪除的時長和頻率比較難定義,由於:同步
所以。若是採用按期刪除策略的話須要經過具體的業務場景來定義時長和頻率。string
經過這兩種方式能夠很好的利用CPU時間以及避免內存浪費的狀況。接下來說講惰性刪除以及按期刪除的實現。
惰性刪除策略由 expireIfNeeded 函數實現,全部讀寫數據庫的 Redis 命令在執行以前都會調用 exipreIfNeeded 函數對輸入鍵進行檢查。
按期刪除策略由 activeExpireCucle 函數實現,被調用時,它在規定的時間內,分屢次遍歷服務器中的各個數據庫,從數據庫的 expires 字典中隨機檢查一部分鍵的過時時間,並刪除其中的過時鍵。
在執行 SAVE 命令或 BGSAVE 命令建立一個新的 RDB 文件時,程序會對數據庫中的鍵進行檢查,已過時的鍵不會被保存到新的 RDB 文件中。
如:redis中包含 r一、r二、r3 三個鍵,而且 r1 已通過期,那麼程序只會講 r2 和 r3 保存到 RDB 文件中。
所以,過時鍵不會對新的 RDB 文件形成影響。
在啓動 redis 服務器時,若是服務器開啓了 RDB 功能,那麼服務器將對 RDB 文件進行載入;
當服務器開啓 AOF 的運行模式時,若是某個鍵過時了,但沒有被惰性或按期刪除,那麼 AOF 不會理會。若是被惰性或按期刪除了, AOF 會在文件末尾追加一條 DEL 命令,來顯示地記錄該鍵已被刪除。
當 AOF 重寫時,過時的鍵不會被載入到 redis 數據庫中。
當服務器在 複製 模式下時,從服務器的過時鍵刪除動做都是由主服務器來進行的。
Redis 的過時鍵刪除策略是 惰性刪除 + 按期刪除,這也既能夠合理的控制 CPU 使用 還能夠 減小內存的浪費。
關於更多 Java 知識以及刷題分享,能夠來公衆號 蘑菇睡不着 看看,你們一塊兒學習。
你越主動就會越主動,咱們下期見~