站長資訊網
        最全最豐富的資訊網站

        Redis的過期鍵刪除策略原理說明

        本篇文章給大家帶來了關于Redis的相關知識,主要介紹了Redis的過期鍵刪除策略原理說明,Redis服務器實際使用的是惰性刪除和定期刪除兩種策略:通過配合使用這兩種刪除策略,服務器可以很好地在合理使用CPU時間和避免浪費內存空間之間取得平衡,希望對大家有所幫助。

        Redis的過期鍵刪除策略原理說明

        推薦學習:Redis視頻教程

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

        惰性刪除

        惰性刪除策略對CPU時間來說是最友好的:程序只會在取出鍵時才對鍵進行過期檢查,這可以保證刪除過期鍵的操作只會在非做不可的情況下進行,并且刪除的目標僅限于當前處理的鍵,這個策略不會在刪除其他無關的過期鍵上花費任何CPU時間。

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

        在使用惰性刪除策略時,如果數據庫中有非常多的過期鍵,而這些過期鍵又恰好沒有被訪問到的話,那么它們也許永遠也不會被刪除(除非用戶手動執行FLUSHDB),我們甚至可以將這種情況看作是一種內存泄漏——無用的垃圾數據占用了大量的內存,而服務器卻不會自己去釋放它們,這對于運行狀態非常依賴于內存的Redis服務器來說,肯定不是一個好消息。

        舉個例子,對于一些和時間有關的數據,比如日志(log),在某個時間點之后,對它們的訪問就會大大減少,甚至不再訪問,如果這類過期數據大量地積壓在數據庫中,用戶以為服務器已經自動將它們刪除了,但實際上這些鍵仍然存在,而且鍵所占用的內存也沒有釋放,那么造成的后果肯定是非常嚴重的。

        定期刪除

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

        惰性刪除浪費太多內存,有內存泄漏的危險。定期刪除策略是前兩種策略的一種整合和折中:

        定期刪除策略每隔一段時間執行一次刪除過期鍵操作,并通過限制刪除操作執行的時長和頻率來減少刪除操作對CPU時間的影響。除此之外,通過定期刪除過期鍵,定期刪除策略有效地減少了因為過期鍵而帶來的內存浪費。定期刪除策略的難點是確定刪除操作執行的時長和頻率:

        如果刪除操作執行得太頻繁,或者執行的時間太長,定期刪除策略就會退化成定時刪除策略,以至于將CPU時間過多地消耗在刪除過期鍵上面。

        如果刪除操作執行得太少,或者執行的時間太短,定期刪除策略又會和惰性刪除策略一樣,出現浪費內存的情況。因此,如果采用定期刪除策略的話,服務器必須根據情況,合理地設置刪除操作的執行時長和執行頻率。

        惰性刪除策略

        過期鍵的惰性刪除策略由db.c/expireIfNeeded函數實現,所有讀寫數據庫的Redis命令在執行之前都會調用expireIfNeeded函數對輸入鍵進行檢查:

        如果輸入鍵已經過期,那么expireIfNeeded函數將輸入鍵從數據庫中刪除。

        如果輸入鍵未過期,那么expireIfNeeded函數不做動作。

        Redis的過期鍵刪除策略原理說明

        expireIfNeeded函數就像一個過濾器,它可以在命令真正執行之前,過濾掉過期的輸入鍵,從而避免命令接觸到過期鍵。

        另外,因為每個被訪問的鍵都可能因為過期而被expireIfNeeded函數刪除,所以每個命令的實現函數都必須能同時處理鍵存在以及鍵不存在這兩種情況:

        當鍵存在時,命令按照鍵存在的情況執行。

        當鍵不存在或者鍵因為過期而被expireIfNeeded函數刪除時,命令按照鍵不存在的情況執行。

        Redis的過期鍵刪除策略原理說明

        定期刪除策略的實現

        過期鍵的定期刪除策略由redis.c/activeExpireCycle函數實現,每當Redis的服務器周期性操作redis.c/serverCron函數執行時,activeExpireCycle函數就會被調用,它在規定的時間內,分多次遍歷服務器中的各個數據庫,從數據庫的expires字典中隨機檢查一部分鍵的過期時間,并刪除其中的過期鍵。

        整個過程可以用偽代碼描述如下

        Redis的過期鍵刪除策略原理說明

        activeExpireCycle函數的工作模式可以總結如下:

        函數每次運行時,都從一定數量的數據庫中取出一定數量的隨機鍵進行檢查,并刪除其中的過期鍵。

        全局變量current_db會記錄當前activeExpireCycle函數檢查的進度,并在下一次activeExpireCycle函數調用時,接著上一次的進度進行處理。比如說,如果當前activeExpireCycle函數在遍歷10號數據庫時返回了,那么下次activeExpireCycle函數執行時,將從11號數據庫開始查找并刪除過期鍵。

        隨著activeExpireCycle函數的不斷執行,服務器中的所有數據庫都會被檢查一遍,這時函數將current_db變量重置為0,然后再次開始新一輪的檢查工作。

        當服務器運行在復制模式下時,從服務器的過期鍵刪除動作由主服務器控制:

        主服務器在刪除一個過期鍵之后,會顯式地向所有從服務器發送一個DEL命令,告知從服務器刪除這個過期鍵。

        從服務器在執行客戶端發送的讀命令時,即使碰到過期鍵也不會將過期鍵刪除,而是繼續像處理未過期的鍵一樣來處理過期鍵

        從服務器只有在接到主服務器發來的DEL命令之后,才會刪除過期鍵。

        通過由主服務器來控制從服務器統一地刪除過期鍵,可以保證主從服務器數據的一致性,也正是因為這個原因,當一個過期鍵仍然存在于主服務器的數據庫時,這個過期鍵在從服務器里的復制品也會繼續存在。舉個例子,有一對主從服務器,它們的數據庫中都保存著同樣的三個鍵message、xxx和yyy,其中message為過期鍵,如圖所示。

        Redis的過期鍵刪除策略原理說明

        如果這時有客戶端向從服務器發送命令GET message,那么從服務器將發現message鍵已經過期,但從服務器并不會刪除message鍵,而是繼續將message鍵的值返回給客戶端,就好像message鍵并沒有過期一樣

        Redis的過期鍵刪除策略原理說明

        假設在此之后,有客戶端向主服務器發送命令GET message,那么主服務器將發現鍵message已經過期:主服務器會刪除message鍵,向客戶端返回空回復,并向從服務器發送DEL message命令

        Redis的過期鍵刪除策略原理說明

        從服務器在接收到主服務器發來的DEL message命令之后,也會從數據庫中刪除message鍵,在這之后,主從服務器都不再保存過期鍵message了

        Redis的過期鍵刪除策略原理說明

        推薦學習:Redis視頻教程

        贊(0)
        分享到: 更多 (0)
        網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
        主站蜘蛛池模板: 亚洲欧美日韩精品久久亚洲区| 宅男宅女精品国产AV天堂| 久久精品中文字幕一区| 2022免费国产精品福利在线| 亚洲人午夜射精精品日韩| 91热成人精品国产免费| 国产精品涩涩涩视频网站| 婷婷成人国产精品| 国产精品一区在线观看你懂的| 国产精品岛国久久久久| 久久亚洲美女精品国产精品| 欧美久久久久久午夜精品| 国产成人精品福利网站在线观看 | 亚洲欧美日韩国产成人精品影院| 99亚洲精品视频| 国产成人精品免费视| 久久精品一本到99热免费| 亚洲国产精品13p| 精品欧美一区二区三区久久久 | 精品一区二区三区免费观看| 色花堂国产精品第一页| 99久久久国产精品免费无卡顿| 久久九九精品99国产精品| 全球AV集中精品导航福利| 亚洲一区二区三区国产精品| 亚洲午夜精品第一区二区8050| 四虎成人精品| 思思久久99热免费精品6| 亚洲爆乳精品无码一区二区| 日韩视频中文字幕精品偷拍| 无码8090精品久久一区| 亚洲国产一成久久精品国产成人综合| 日韩精品免费一线在线观看| 婷婷成人国产精品| 中文精品99久久国产 | 91热成人精品国产免费| 1区1区3区4区产品芒果精品| 欧美高清在线精品一区| 亚洲精品理论电影在线观看| 91精品免费久久久久久久久| 99熟女精品视频一区二区三区|