天天看點

【75期】面試官:說說Redis的過期鍵删除政策吧!(高頻)

【75期】面試官:說說Redis的過期鍵删除政策吧!(高頻)

程式員的成長之路

網際網路/程式員/技術/資料共享 

閱讀本文大概需要 5 分鐘。

劃重點:Redis的過期鍵删除政策也是面試中經常會被問的,我最近面試,被問到了好幾次。

對于Redis伺服器來說,記憶體資源非常寶貴,如果一些過期鍵一直不被删除,就會造成資源浪費,是以我們需要考慮一個問題:如果一個鍵過期了,它什麼時候會被删除呢?

1. 常見的删除政策

常見的删除政策有以下3種:

  • 定時删除

在設定鍵的過期時間的同時,建立一個定時器,讓定時器在鍵的過期時間來臨時,立即執行對鍵的删除操作。

  • 惰性删除

放任過期鍵不管,每次從鍵空間中擷取鍵時,檢查該鍵是否過期,如果過期,就删除該鍵,如果沒有過期,就傳回該鍵。

  • 定期删除

每隔一段時間,程式對資料庫進行一次檢查,删除裡面的過期鍵,至于要删除哪些資料庫的哪些過期鍵,則由算法決定。

其中定時删除和定期删除為主動删除政策,惰性删除為被動删除政策。

接下來我們一一講解。

1.1 定時删除政策

定時删除政策通過使用定時器,定時删除政策可以保證過期鍵盡可能快地被删除,并釋放過期鍵占用的記憶體。

是以,定時删除政策的優缺點如下所示:

  • 優點:對記憶體非常友好
  • 缺點:對CPU時間非常不友好

舉個例子,如果有大量的指令請求等待伺服器處理,并且伺服器目前不缺少記憶體,如果伺服器将大量的CPU時間用來删除過期鍵,那麼伺服器的響應時間和吞吐量就會受到影響。

也就是說,如果伺服器建立大量的定時器,伺服器處理指令請求的性能就會降低,是以Redis目前并沒有使用定時删除政策。

1.2 惰性删除政策

惰性删除政策隻會在擷取鍵時才對鍵進行過期檢查,不會在删除其它無關的過期鍵花費過多的CPU時間。

是以,惰性删除政策的優缺點如下所示:

  • 優點:對CPU時間非常友好
  • 缺點:對記憶體非常不友好

舉個例子,如果資料庫有很多的過期鍵,而這些過期鍵又恰好一直沒有被通路到,那這些過期鍵就會一直占用着寶貴的記憶體資源,造成資源浪費。

1.3 定期删除政策

定期删除政策是定時删除政策和惰性删除政策的一種整合折中方案。

定期删除政策每隔一段時間執行一次删除過期鍵操作,并通過限制删除操作執行的時長和頻率來減少删除操作對CPU時間的影響,同時,通過定期删除過期鍵,也有效地減少了因為過期鍵而帶來的記憶體浪費。

2. Redis使用的過期鍵删除政策

Redis伺服器使用的是惰性删除政策和定期删除政策。

2.1 惰性删除政策的實作

過期鍵的惰性删除政策由expireIfNeeded函數實作,所有讀寫資料庫的Redis指令在執行之前都會調用expireIfNeeded函數對輸入鍵進行檢查:

  • 如果輸入鍵已經過期,那麼将輸入鍵從資料庫中删除
  • 如果輸入鍵未過期,那麼不做任何處理

以上描述可以使用如下流程圖表示:

【75期】面試官:說說Redis的過期鍵删除政策吧!(高頻)

2.2 定期删除政策的實作

過期鍵的定期删除政策由activeExpireCycle函數實作,每當Redis伺服器的周期性操作serverCron函數執行時,activeExpireCycle函數就會被調用,它在規定的時間内,分多次周遊伺服器中的各個資料庫,從資料庫的expires字典中随機檢查一部分鍵的過期時間,并删除其中的過期鍵。

activeExpireCycle函數的大體流程為:

函數每次運作時,都從一定數量的資料庫中随機取出一定數量的鍵進行檢查,并删除其中的過期鍵,比如先從0号資料庫開始檢查,下次函數運作時,可能就是從1号資料庫開始檢查,直到15号資料庫檢查完畢,又重新從0号資料庫開始檢查,這樣可以保證每個資料庫都被檢查到。

劃重點:

關于定期删除的大體流程,最近面試時有被問道,我就是按上述描述回答的。

可能有的面試官還會問,每次随機删除哪些key呢?可以提下LRU算法(Least Recently Used 最近最少使用),一般不會再細問,不過有興趣的同學可以深入研究下。更多面試題,歡迎關注公衆号 Java面試題精選

3. RDB對過期鍵的處理

3.1 生成RDB檔案

在執行SAVE指令或者BGSAVE指令建立一個新的RDB檔案時,程式會對資料庫中的鍵進行檢查,已過期的鍵不會被儲存到新建立的RDB檔案中。

舉個例子,如果資料庫中包含3個鍵k1、k2、k3,并且k2已經過期,那麼建立新的RDB檔案時,程式隻會将k1和k3儲存到RDB檔案中,k2則會被忽略。

3.2 載入RDB檔案

在啟動Redis伺服器時,如果伺服器隻開啟了RDB持久化,那麼伺服器将會載入RDB檔案:

  • 如果伺服器以主伺服器模式運作,在載入RDB檔案時,程式會對檔案中儲存的鍵進行檢查,未過期的鍵會被載入到資料庫中,過期鍵會被忽略。
  • 如果伺服器以從伺服器模式運作,在載入RDB檔案時,檔案中儲存的所有鍵,不論是否過期,都會被載入到資料庫中。

因為主從伺服器在進行資料同步(完整重同步)的時候,從伺服器的資料庫會被清空,是以一般情況下,過期鍵對載入RDB檔案的從伺服器不會造成影響。更多面試題,歡迎關注公衆号 Java面試題精選

4. AOF對過期鍵的處理

4.1 AOF檔案寫入

如果資料庫中的某個鍵已經過期,并且伺服器開啟了AOF持久化功能,當過期鍵被惰性删除或者定期删除後,程式會向AOF檔案追加一條DEL指令,顯式記錄該鍵已被删除。

舉個例子,如果用戶端執行指令GET message通路已經過期的message鍵,那麼伺服器将執行以下3個動作:

  • 從資料庫中删除message鍵
  • 追加一條DEL message指令到AOF檔案

    -向執行GET message指令的用戶端傳回空回複

4.2 AOF檔案重寫

在執行AOF檔案重寫時,程式會對資料庫中的鍵進行檢查,已過期的鍵不會被儲存到重寫後的AOF檔案中。

5. 複制功能對過期鍵的處理

在主從複制模式下,從伺服器的過期鍵删除動作由主伺服器控制:

  • 主伺服器在删除一個過期鍵後,會顯式地向所有從伺服器發送一個DEL指令,告知從伺服器删除這個過期鍵。
  • 從伺服器在執行用戶端發送的讀指令時,即使發現該鍵已過期也不會删除該鍵,照常傳回該鍵的值。
  • 從伺服器隻有接收到主伺服器發送的DEL指令後,才會删除過期鍵。

繼續閱讀