Redis刪除過期key策略詳解
Redis中key的的過期時間
Redis 中可以為 key 設(shè)置過期時間,到期后 key 會自動被刪除,過期時間可以通過以下幾種方式設(shè)置:
在創(chuàng)建 key 時使用 EXPIRE 命令設(shè)置過期時間(秒級)
示例:
EXPIRE key1 30 # 30秒過期
使用 EXPIREAT 命令設(shè)置一個精確的過期時間(unix 時間戳)
示例:
EXPIREAT key2 1651811000 # 2022-05-06 14:30:00 過期
使用 PEXPIRE 命令設(shè)置過期時間(毫秒級)
示例:
PEXPIRE key3 6000 # 6秒過期
使用 PEXPIREAT 命令設(shè)置毫秒級精確過期時間
示例:
PEXPIREAT key4 1651811000000 # 2022-05-06 14:30:00.000過期
在 Redis 配置文件中設(shè)置所有 key 的默認(rèn)過期時間
通過 default-ttl 參數(shù)配置默認(rèn)過期時間
# redis.conf default-ttl 3600 # 默認(rèn)1小時過期
使用 PERSIST 命令可以移除一個 key 的過期時間設(shè)置
PERSIST key2 # 移除key2的過期時間
使用 TTL 命令可以查看一個 key 剩余的過期時間
TTL key3 # 查看key3的剩余過期時間
Redis 提供了靈活的 key 過期時間設(shè)置,可以按需為不同 key 設(shè)置過期時間。
Redis過期鍵刪除策略
Redis key過期的方式有三種:
- 被動刪除:當(dāng)讀/寫一個已經(jīng)過期的key時,會觸發(fā)惰性刪除策略,直接刪除掉這個過期key
- 主動刪除:由于惰性刪除策略無法保證冷數(shù)據(jù)被及時刪掉,所以Redis會定期主動淘汰一批已過期的key
- 當(dāng)前已用內(nèi)存超過maxmemory限定時,觸發(fā)主動清理策略
1、定時刪除
定時刪除是在設(shè)置key的過期時間的同時,會創(chuàng)建一個定時器(timer)。定時器在key的過期時間來臨時,立即執(zhí)行對key的刪除操作。
此種刪除策略可以保證過期key會盡可能快的被刪除,并釋放過期key所占用的內(nèi)存。
但是此種策略對CPU時間是最不友好的。在過期key比較多的情況下,刪除過期key這一行為可能會占用相當(dāng)一部分CPU時間,在內(nèi)存不緊張但是CPU時間非常緊張的情況下,將CPU時間用在刪除和當(dāng)前任務(wù)無關(guān)的過期key上,無疑會對服務(wù)器的響應(yīng)時間和吞吐量造成影響。
例如,正有大量的命令請求在等待服務(wù)器處理,并且服務(wù)器當(dāng)前不缺少內(nèi)存的情況下,服務(wù)器應(yīng)當(dāng)優(yōu)先將CPU時間用在處理客戶端的命令請求上面,而不是用在刪除過期key上面。
并且創(chuàng)建一個定時器(timer)需要用到Redis服務(wù)器中的時間事件,而當(dāng)前時間事件是用無序鏈表實現(xiàn)的,查找一個事件的時間復(fù)雜度為O(N),并不能高效地處理大量時間事件。要讓服務(wù)器創(chuàng)建大量的定時器,從而實現(xiàn)定時刪除,在現(xiàn)階段來說并不現(xiàn)實。
優(yōu)點:
1.可以自動清理不需要的緩存數(shù)據(jù),減少內(nèi)存占用。
2.可以定時刷新部分緩存,保證數(shù)據(jù)實時性。
3.可以根據(jù)業(yè)務(wù)需求自定義不同的數(shù)據(jù)緩存周期。
4.操作簡單,只需要設(shè)置過期時間,不需要手動刪除。
缺點:
1.需要額外的內(nèi)存來存儲 key 的過期時間。
2.過期刪除是被動操作,無法按需主動刪除。
3.過期時間的精度只到秒級,無法更細(xì)粒度控制。
4.如果過期 key 數(shù)量很多,過期刪除時還是有一定性能開銷。
5.只依賴過期時間可能導(dǎo)致一段時間內(nèi)緩存量激增,需配合其它方式控制。
示例:
// 設(shè)置10秒過期 jedis.setex("data", 10, "cache");
2、定期刪除
定期刪除是指Redis會每隔一段時間,對部分key進行檢查和刪除。具體來說,Redis會每隔一段時間隨機抽取一部分key,檢查其是否過期,如果過期則刪除。
優(yōu)點:
1.減少每次訪問的時間復(fù)雜度。
2.減少刪除操作對CPU時間的影響。
缺點:
可能會有一些過期key沒有被及時刪除。
通過定期刪除策略,可以有效地減少因為過期key而帶來的內(nèi)存浪費。
示例:
// 定期掃描刪除 public void delKeys(){ Set<String> keys = jedis.keys("cache:*"); jedis.del(keys.toArray(new String[0])); } // 調(diào)度執(zhí)行 scheduledExecutorService.scheduleAtFixedRate(this::delKeys, 0, 1, TimeUnit.HOURS);
3、惰性刪除
惰性刪除是指在訪問某個key時,Redis會先檢查該key是否過期,如果過期則立即刪除。這種策略的優(yōu)點是能夠及時釋放內(nèi)存空間,但缺點是會增加每次訪問的時間復(fù)雜度,因為需要進行過期檢查。
惰性刪除是定時刪除和定期刪除的折中處理方案。它放任key過期不管,但是每次獲取key時,都會檢查取得的key是否過期,如果過期,則刪除該key;若沒有過期,就返回該key的值。
優(yōu)點:
對CPU時間來說是最友好的,只在取出key時,才對key進行過期檢查,即只會在非做不可的情況下進行,并且刪除的目標(biāo)僅限于當(dāng)前處理的key,不會在刪除其他無關(guān)的過期key上花費任何CPU時間。
缺點:
對內(nèi)存是最不友好的。如果一個key已經(jīng)過期,而這個key又仍然保留在db中,那么只要這個過期key不被刪除,它所占用的內(nèi)存就不會釋放。例如,如果db中有非常多的過期key,而這些過期key又恰好沒有被訪問到的話,那它們也許永遠(yuǎn)也不會被刪除,除非用戶手動執(zhí)行flushdb命令清空,這樣會導(dǎo)致大量的無用的臟數(shù)據(jù)占用大量的內(nèi)存。
示例:
jedis.set("key", "value"); jedis.unlink("key"); // 惰性標(biāo)記刪除
總結(jié)
Redis的過期key刪除策略是惰性刪除、定期刪除和定時刪除的混合策略。惰性刪除能夠及時釋放內(nèi)存空間,但會增加每次訪問的時間復(fù)雜度;定期刪除能夠減少時間復(fù)雜度,但可能會有一些過期key沒有被及時刪除;定時刪除能夠精確控制過期時間,但需要額外的定時任務(wù)。通過這種混合策略,Redis能夠在保證內(nèi)存空間的同時,盡可能地減少對性能的影響。
以上就是Redis刪除過期key策略詳解的詳細(xì)內(nèi)容,更多關(guān)于Redis刪除過期key的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Redis數(shù)據(jù)庫的使用場景介紹(避免誤用Redis)
這篇文章主要介紹了Redis數(shù)據(jù)庫的使用場景介紹(避免誤用Redis),本文用簡要的語言總結(jié)了Redis數(shù)據(jù)庫的適應(yīng)場合,人而避免錯誤的使用它而產(chǎn)生昂貴的維護代價,需要的朋友可以參考下2015-03-03Redis五大基本數(shù)據(jù)類型及對應(yīng)使用場景總結(jié)
Redis有五種基本數(shù)據(jù)類型,分別是字符串(String)、哈希(Hash)、列表(List)、集合(Set)和有序集合(Sorted?Set),這些基本數(shù)據(jù)類型使得Redis具備了豐富的數(shù)據(jù)結(jié)構(gòu)和功能,適用于各種不同的應(yīng)用場景,本文就給大家詳細(xì)的介紹一下這五大類型2023-08-08redis哨兵模式分布式鎖實現(xiàn)與實踐方式(redisson)
這篇文章主要介紹了redis哨兵模式分布式鎖實現(xiàn)與實踐方式(redisson),具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-03-03