Redis過期刪除是如何做的?

當一個鍵處於過期的狀態,其實在 Redis 中這個內存並不是實時就被從內存中進行摘除,而是 Redis 通過一定的機制去把一些處於過期鍵進行移除,進而達到內存的釋放,那麼當一個鍵處於過期,Redis 會在什麼時候去刪除?

幾時被刪除存在三種可能性,這三種可能性也代表了 Redis 的三種不同的刪除策略。

  • 定時刪除:在設置鍵過去的時間同時,創建一個定時器,讓定時器在鍵過期時間來臨,立即執行對鍵的刪除操作。
  • 惰性刪除:放任鍵過期不管,但是每次從鍵空間獲取鍵時,都會檢查該鍵是否過期,如果過期的話,就刪除該鍵。
  • 定期刪除:每隔一段時間,程序都要對數據庫進行一次檢查,刪除裏面的過期鍵,至於要刪除多少過期鍵,由算法而定。

1、定時刪除

設置鍵的過期時間,創建定時器,一旦過期時間來臨,就立即對鍵進行操作。

這種對內存是友好的,但是對 CPU 的時間是最不友好的,特別是在業務繁忙,過期鍵很多的時候,刪除過期鍵這個操作就會佔據很大一部分 CPU 的時間。

要知道 Redis 是單線程操作,在內存不緊張而 CPU 緊張的時候,將 CPU 的時間浪費在與業務無關的刪除過期鍵上面,會對 Redis 的服務器的響應時間和吞吐量造成影響。

另外,創建一個定時器需要用到 Redis 服務器中的時間事件,而當前時間事件的實現方式是無序鏈表,時間複雜度爲 O(n),讓服務器大量創建定時器去實現定時刪除策略,會產生較大的性能影響,所以,定時刪除並不是一種好的刪除策略。

2、惰性刪除

與定時刪除相反,惰性刪除策略對 CPU 來說是最友好的,程序只有在取出鍵的時候纔會進行檢查,是一種被動的過程。

與此同時,惰性刪除對內存來說又是最不友好的,一個鍵過期,只要不再被取出,這個過期鍵就不會被刪除,它佔用的內存也不會被釋放。

很明顯,惰性刪除也不是一個很好的策略,Redis 是非常依賴內存和較好內存的,如果一些長期鍵長期沒有被訪問,就會造成大量的內存垃圾,甚至會操成內存的泄漏。

在對執行數據寫入時,通過 expireIfNeeded 函數對寫入的 Key 進行過期判斷。

其中 expireIfNeeded 在內部做了三件事情,分別是:

  • 查看 Key 是否過期。
  • 向 Slave 節點傳播執行過去 Key 的動作。
  • 刪除過期 Key。

3、定期刪除

上面兩種刪除策略,無論是定時刪除和惰性刪除,這兩種刪除方式在單一的使用上都存在明顯的缺陷,要麼佔用太多 CPU 時間,要麼浪費太多內存。

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

  • 定期刪除策略每隔一段時間執行一次刪除過期鍵操作,並通過限制刪除操作執行的時間和頻率來減少刪除操作對 CPU 時間的影響。
  • 通過合理的刪除執行的時長和頻率,來達到合理的刪除過期鍵。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章