Redis過時鍵刪除策略

三種刪除策略:算法

  1. 定時刪除:在設置鍵的過時時間的同時,建立一個定時器(timer),讓定時器在鍵的過時時間來臨時,當即執行對鍵的刪除操做。數據庫

  2. 惰性刪除:聽任鍵過時無論,可是每次從鍵空間中獲取鍵時,都檢查取得的鍵是否過時,若是過時的話,就刪除該鍵;若是沒有過時,就返回該鍵。服務器

  3. 按期刪除:每隔一段時間,程序就對數據庫進行一次檢查,刪除裏面的過時鍵。至於要刪除多少過時鍵,以及要檢查多少個數據庫,則由算法決定。spa

在這三種策略中,第一種和第三種爲主動刪除策略,而第二種則爲被動刪除策略。日誌

  定時刪除策略是對內存最友好的:經過使用定時器,定時刪除策略能夠保證過時鍵會盡量快地被刪除,並釋放過時鍵所佔用的內存。另外一方面,定時刪除策略的缺點是,它對CPU時間是最不友好的:在過時鍵比較多的狀況下,刪除過時鍵這一行爲可能會佔用至關一部分CPU時間,在內存不緊張可是CPU時間很是緊張的狀況下,將CPU時間用在刪除和當前任務無關的過時鍵上,無疑會對服務器的響應時間和吞吐量形成影響。orm

  例如,若是正有大量的命令請求在等待服務器處理,而且服務器當前不缺乏內存,那麼服務器應該優先將CPU時間用在處理客戶端的命令請求上面,而不是用在刪除過時鍵上面。事件

  除此以外,建立一個定時器須要用到Redis服務器中的時間事件,而當前時間事件的實現方式--無序鏈表,查找一個事件的時間複雜度爲O(N) ---- 並不能高效地處理大量時間事件。內存

  所以,要讓服務器建立大量的定時器,從而實現定時刪除策略,在現階段來講並不現實。ci


  惰性刪除策略對CPU時間來講是最友好的:程序只會在取出鍵時纔對鍵進行過時檢查,這能夠保證刪除過時鍵的操做只會在非作不可的狀況下進行,而且刪除的目標僅限於當前處理的鍵,這個策略不會在刪除其餘無關的過時鍵上花費任何CPU時間。it

  惰性刪除策略的缺點是,它對內存是最不友好的:若是一個鍵已通過期,而這個鍵又仍然保留在數據庫中,那麼只要這個過時鍵不被刪除,它所佔的內存就不會釋放。

  在使用惰性刪除策略時,若是數據庫中有很是多的過時鍵,而這些過時鍵又剛好沒有被訪問到的話,那麼它們也許永遠也不會被刪除(除非用戶手動執行FLUSHDB),咱們甚至能夠將這種狀況看做是一種內存泄露----無用的垃圾數據佔用了大量的內存,而服務器卻不會本身去釋放它們,這對於運行狀態很是依賴於內存的Redis服務器來講,確定不是一個好消息。

  舉個例子,對於一些和時間有關的數據,好比日誌(log),在某個時間以後,對它們的訪問就會大大減小,甚至再也不訪問,若是這類過時數據大量地積壓在數據庫中,用戶覺得服務器已經自動將它們刪除了,但實際上這些鍵仍然存在,並且鍵所佔用的內存也沒有釋放,那麼形成的後果確定是很是嚴重的。


  從上面對定時刪除和惰性刪除的討論來看,這兩種刪除方式在單一使用都有明顯的缺陷:

    1. 定時刪除佔用太多CPU時間,影響服務器的響應時間和吞吐量;

    2. 惰性刪除浪費太多內存,有內存泄露的危險。

  按期刪除策略是前兩種策略的一種整合和折中:

    1. 按期刪除策略每隔一段時間執行一次刪除過時鍵操做,並經過限制刪除操做執行的時長和頻率來減小刪除操做對CPU時間的影響;

    2. 除此以外,經過按期刪除過時鍵,按期刪除策略有效地減小了由於過時鍵而帶來的內存浪費。

  按期刪除策略的難點是肯定刪除操做執行的時長和頻率:

    1. 若是刪除操做執行的太頻繁,或者執行的時間太長,按期刪除策略就會退化成定時刪除策略,以致於將CPU時間過多地消耗在刪除過時鍵上面。

    2. 若是刪除操做執行得太少,或者執行的時間過短,按期刪除策略又會和惰性刪除策略同樣,出現浪費內存的狀況。

  所以,若是採用按期刪除策略的話,服務器必須根據狀況,合理地設置刪除操做的執行時長和執行頻率。

  Redis服務器實際使用的是惰性刪除和按期刪除兩種策略:經過配合使用這兩種刪除策略,服務器能夠很好地在合理使用CPU時間和避免浪費內存空間之間取得平衡。

相關文章
相關標籤/搜索