關(guān)于 Redis 的過期策略與淘汰策略詳解
Redis作為一種高性能的鍵值存儲系統(tǒng),廣泛應(yīng)用于緩存、消息中間件等場景。在Redis中,數(shù)據(jù)的過期策略和淘汰策略對于內(nèi)存管理和系統(tǒng)性能至關(guān)重要。本文將詳細(xì)介紹Redis的過期策略和淘汰策略,并提供相應(yīng)的例子代碼。

一、Redis的過期策略
Redis支持對鍵值對設(shè)置過期時(shí)間,當(dāng)過期時(shí)間到達(dá)時(shí),Redis會自動(dòng)觸發(fā)過期鍵刪除策略,將過期的鍵值對從內(nèi)存中刪除以釋放內(nèi)存空間。Redis主要采用了以下幾種過期策略:
1. 定時(shí)刪除
定時(shí)刪除策略會為每個(gè)設(shè)置了過期時(shí)間的鍵創(chuàng)建一個(gè)定時(shí)器,當(dāng)過期時(shí)間到達(dá)時(shí),自動(dòng)刪除該鍵。這種策略可以確保鍵在過期時(shí)間到達(dá)時(shí)立即被刪除,但會占用大量的CPU資源,尤其是在存在大量設(shè)置了過期時(shí)間的鍵時(shí),CPU開銷會非常高。Redis并不推薦這種策略,因?yàn)樗鼤?yán)重影響Redis的性能。
2. 惰性刪除
惰性刪除策略不會主動(dòng)刪除過期的鍵,而是在每次訪問鍵時(shí),檢查該鍵是否過期,如果過期則刪除。這種策略對CPU友好,因?yàn)橹挥性趯?shí)際需要該鍵時(shí)才會進(jìn)行過期檢查。但是,它可能導(dǎo)致過期鍵在內(nèi)存中長時(shí)間占用空間,如果過期鍵長時(shí)間沒有被訪問,內(nèi)存將無法得到釋放。
3. 定期刪除
定期刪除策略是定時(shí)刪除和惰性刪除的一種折中方案。Redis會周期性地執(zhí)行過期鍵掃描操作,刪除其中的過期鍵。具體掃描的頻率和數(shù)量可以通過Redis的配置文件(redis.conf)中的hz參數(shù)來設(shè)置,默認(rèn)值為10,表示每秒鐘執(zhí)行10次掃描。在掃描過程中,Redis會隨機(jī)選擇一定數(shù)量的鍵進(jìn)行檢查,并刪除其中的過期鍵。這種策略既避免了惰性刪除可能導(dǎo)致的內(nèi)存占用問題,又減少了定時(shí)刪除對CPU資源的高消耗。
例子代碼
設(shè)置鍵的過期時(shí)間:
# Redis命令行設(shè)置過期時(shí)間
EXPIRE mykey 10 # 設(shè)置鍵mykey的過期時(shí)間為10秒4. 隨機(jī)刪除
隨機(jī)刪除策略并不是Redis的默認(rèn)策略,但在某些場景下可能會使用到。它將設(shè)置過期時(shí)間的鍵放在一個(gè)字典中,并設(shè)置一個(gè)虛擬時(shí)間,每次隨機(jī)刪除字典中的一部分過期鍵。這種策略可以避免在同一時(shí)間點(diǎn)刪除過多的鍵而導(dǎo)致Redis阻塞。
二、Redis的淘汰策略
當(dāng)Redis的內(nèi)存使用達(dá)到上限時(shí),需要按照某種策略淘汰部分?jǐn)?shù)據(jù)以釋放內(nèi)存。Redis提供了多種淘汰策略,可以在配置文件redis.conf中通過maxmemory-policy參數(shù)來設(shè)置。
1. noeviction
默認(rèn)策略,當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時(shí),新寫入操作會報(bào)錯(cuò),但刪除和讀請求可以繼續(xù)。這種策略可以確保Redis內(nèi)存不會被其他進(jìn)程搶占,但可能會導(dǎo)致Redis進(jìn)程被強(qiáng)制殺死,數(shù)據(jù)全部丟失,因此不建議在生產(chǎn)環(huán)境中使用。
2. allkeys-lru
從所有key中使用LRU(最近最少使用)算法進(jìn)行淘汰。LRU算法通過記錄每個(gè)key的最近訪問時(shí)間,淘汰最長時(shí)間未被訪問的key。適用于緩存場景,可以確保經(jīng)常被訪問的數(shù)據(jù)保留在內(nèi)存中,提高緩存命中率。
3. allkeys-random
從所有key中隨機(jī)淘汰數(shù)據(jù)。這種策略不考慮key的訪問頻率或過期時(shí)間,完全隨機(jī)選擇key進(jìn)行淘汰。在不確定哪些key是熱門數(shù)據(jù),或者對淘汰策略沒有特殊要求的情況下,可以使用這種簡單的隨機(jī)淘汰策略。
4. volatile-lru
從設(shè)置了過期時(shí)間的key中使用LRU算法進(jìn)行淘汰。這種策略只針對設(shè)置了過期時(shí)間的key進(jìn)行操作,優(yōu)先淘汰那些最近最少使用且已經(jīng)設(shè)置了過期時(shí)間的key。適用于需要設(shè)置過期時(shí)間,同時(shí)希望緩存盡可能保留熱門數(shù)據(jù)的場景。
5. volatile-random
從設(shè)置了過期時(shí)間的key中隨機(jī)淘汰。與allkeys-random類似,但這種策略只針對設(shè)置了過期時(shí)間的key進(jìn)行操作。在需要淘汰過期key,但又不希望完全依賴LRU算法的情況下,可以使用這種隨機(jī)淘汰策略。
6. volatile-ttl
在設(shè)置了過期時(shí)間的key中,淘汰過期時(shí)間剩余最短的。這種策略優(yōu)先淘汰那些即將過期的key,確保Redis存儲的數(shù)據(jù)盡可能新鮮。適用于需要快速淘汰即將過期數(shù)據(jù)的場景,比如緩存即將失效的會話信息等。
例子代碼:
設(shè)置Redis淘汰策略:
# Redis命令行設(shè)置淘汰策略
CONFIG SET maxmemory-policy volatile-lru或者在redis.conf配置文件中設(shè)置:
maxmemory-policy volatile-lru
maxmemory 100mb # 設(shè)置Redis最大內(nèi)存限制為100MB三、總結(jié)
Redis的過期策略和淘汰策略對于內(nèi)存管理和系統(tǒng)性能至關(guān)重要。通過合理配置這些策略,可以確保Redis在內(nèi)存使用達(dá)到上限時(shí),能夠按照預(yù)定的規(guī)則淘汰部分?jǐn)?shù)據(jù),以釋放內(nèi)存空間。同時(shí),通過合理的過期策略,可以確保過期的鍵值對能夠及時(shí)被刪除,避免內(nèi)存的浪費(fèi)。在實(shí)際應(yīng)用中,建議根據(jù)業(yè)務(wù)需求和數(shù)據(jù)特點(diǎn),選擇最合適的過期和淘汰策略。






























