Redis過期數(shù)據(jù)是否會被立馬刪除
引言
當 key 達到過期時間,Redis 就會馬上刪除么?
先說結論:并不會立馬刪除。
Redis 有兩種刪除過期數(shù)據(jù)的策略:
- 定期選取部分數(shù)據(jù)刪除;
- 惰性刪除;
該命令在 Redis 2.4 版本,過期時間并不是很精確,它可能在零到一秒之間。
從 Redis 2.6 開始,過期錯誤為 0 到 1 毫秒。
EXPIRE key seconds [ NX | XX | GT | LT]
指令可以將指定的 key 設置過期時間,如果沒有設置過期時間, key 將一直存在,除非我們明確將其刪除,比如執(zhí)行 DEL
指令。
所謂”狡兔死,走狗烹“,沒用了就干掉,跟 35 歲就“畢業(yè)”是一個道理。
好慌……
從 Redis 版本 7.0.0 開始:EXPIRE
添加了選項:NX
、XX
和GT
、LT
選項。
- NX:當 key 沒有過期時才設置過期時間;
- XX:只有 key 已過期的時候才設置過期時間;
- GT:僅當新的到期時間大于當前到期時間時才設置過期時間;
- LT:僅在新到期時間小于當前到期時間才設置到過期時間。
過期與持久化
?主從或者集群架構中,兩臺機器的時鐘嚴重不同步,會有什么問題么?
key 過期信息是用 Unix 絕對時間戳表示的。
為了讓過期操作正常運行,機器之間的時間必須保證穩(wěn)定同步,否則就會出現(xiàn)過期時間不準的情況。
比如兩臺時鐘嚴重不同步的機器發(fā)生 RDB 傳輸, slave 的時間設置為未來的 2000 秒,假如在 master 的一個 key 設置 1000 秒存活,當 Slave 加載 RDB 的時候 key 就會認為該 key 過期(因為 slave 機器時間設置為未來的 2000 s),并不會等待 1000 s 才過期。
機器時鐘不同步導致過期混亂
惰性刪除
惰性刪除很簡單,就是當有客戶端的請求查詢該 key
的時候,檢查下 key
是否過期,如果過期,則刪除該 key
。
比如當 Redis 收到客戶端的GET movie:小澤#瑪……利亞.rmvb
請求,就會先檢查 key = movie:小澤#瑪……利亞.rmvb
是否已經(jīng)過期,如果過期那就刪除。
刪除過期數(shù)據(jù)的主動權交給了每次訪問請求。
該實現(xiàn)通過 expireIfNeeded
函數(shù)實現(xiàn),源碼路徑:src/db.c
。
int?expireIfNeeded(redisDb?*db,?robj?*key,?int?force_delete_expired)?{ ???//?key?沒有過期,return?0 ????if?(!keyIsExpired(db,key))?return?0; ????if?(server.masterhost?!=?NULL)?{ ????????if?(server.current_client?==?server.master)?return?0; ????????if?(!force_delete_expired)?return?1; ????} ????if?(checkClientPauseTimeoutAndReturnIfPaused())?return?1; ????/*?Delete?the?key?*/ ????deleteExpiredKeyAndPropagate(db,key); ????return?1; }
定期刪除
僅僅靠客戶端訪問來判斷 key 是否過期才執(zhí)行刪除肯定不夠,因為有的 key 過期了,但未來再也沒人訪問,這些數(shù)據(jù)要怎么刪除呢?
不能讓這些數(shù)據(jù)「占著茅坑不拉屎」。
所謂定期刪除,也就是 Redis 默認每 1 秒運行 10 次(每 100 ms 執(zhí)行一次),每次隨機抽取一些設置了過期時間的 key,檢查是否過期,如果發(fā)現(xiàn)過期了就直接刪除。
注意:并不是一次運行就檢查所有的庫,所有的鍵,而是隨機檢查一定數(shù)量的鍵。
具體步驟如下:
定時刪除
- 從所有設置了過期時間的 key 集合中隨機選擇 20 個 key;
- 刪除「步驟 1」發(fā)現(xiàn)的所有過期 key 數(shù)據(jù);
- 「步驟 2 」結束,過期的 key 超過 25%,則繼續(xù)執(zhí)行「步驟 1」。
刪除的源碼 expire.c 的 activeExpireCycle 函數(shù)實現(xiàn)。
這也就意味著在任何時候,過期 key 的最大數(shù)量等于每秒最大寫入操作量除以 4。
?為啥不檢查所有設置過期時間的 key?
你想呀,假設 Redis 里存放了 100 w 個 key,都設置了過期時間,每隔 100 毫秒就檢查 100 w 個 key,CPU 全浪費在檢查過期 key 上了,Redis 也就廢了。
注意了:不管是定時刪除,還是惰性刪除。當數(shù)據(jù)刪除后,master
會生成刪除的指令記錄到 AOF
和 slave
節(jié)點。
碼哥,如果過期的數(shù)據(jù)太多,定時刪除無法刪除完全(每次刪除完過期的 key 還是超過 25%),同時這些 key 也再也不會被客戶端請求,也就是無法走惰性刪除,會怎樣?
會不會導致 Redis 內(nèi)存耗盡,怎么破?
這個問題問得好,答案是走內(nèi)存淘汰機制。
以上就是Redis過期數(shù)據(jù)是否會被立馬刪除的詳細內(nèi)容,更多關于Redis過期數(shù)據(jù)的資料請關注腳本之家其它相關文章!
相關文章
基于 Redis 的 JWT令牌失效處理方案(實現(xiàn)步驟)
當用戶登錄狀態(tài)到登出狀態(tài)時,對應的JWT的令牌需要設置為失效狀態(tài),這時可以使用基于Redis 的黑名單方案來實現(xiàn)JWT令牌失效,本文給大家分享基于 Redis 的 JWT令牌失效處理方案,感興趣的朋友一起看看吧2024-03-03