Redis的數(shù)據(jù)庫(kù)結(jié)構(gòu),結(jié)構(gòu)為
typedef struct redisDb {
dict *dict; /* The keyspace for this DB */
dict *expires; /* Timeout of keys with a timeout set */
dict *blocking_keys; /* Keys with clients waiting for data (BLPOP) */
dict *ready_keys; /* Blocked keys that received a PUSH */
dict *watched_keys; /* WATCHED keys for MULTI/EXEC CAS */
struct evictionPoolEntry *eviction_pool; /* Eviction pool of keys */
int id; /* Database ID */
long long avg_ttl; /* Average TTL, just for stats */
} redisDb;
Redis是一個(gè)KV類(lèi)型的數(shù)據(jù)庫(kù)油昂,比較重要的屬性為(dict,expires)
-
dict:保存了數(shù)據(jù)庫(kù)里面所有的鍵值對(duì)
他是key都是字符串類(lèi)型倾贰,值的話是對(duì)應(yīng)的對(duì)象(字符串冕碟,列表,hash匆浙,set安寺,zset)
-
expires:保存了所有key值的到期時(shí)間,定期刪除也是基于這張表做的
Redis過(guò)期鍵刪除策略(惰性刪除首尼、定期刪除挑庶、主動(dòng)清除)
-
惰性刪除
在獲取(寫(xiě)操作之前也會(huì)先讀取一下)這個(gè)key的時(shí)候判斷鍵是否過(guò)期言秸,如果過(guò)期的話就進(jìn)行刪除,并且返回空
-
定期刪除
它在規(guī)定的時(shí)間內(nèi)挠羔,分多次遍歷服務(wù)器中的各個(gè)數(shù)據(jù)庫(kù)井仰,從數(shù)據(jù)庫(kù)的expires 字典中隨機(jī)檢查一部分鍵的過(guò)期時(shí)間,并刪除其中的過(guò)期鍵破加。
-
主動(dòng)清理(當(dāng)前已用內(nèi)存超過(guò)maxmemory限定時(shí),觸發(fā)主動(dòng)清理策略)
在介紹刪除策略之前先了解一下刪除算法雹嗦,LRU跟LFU
- LRU(Least Recently Used范舀,最久未使用的)以最近一次訪問(wèn)時(shí)間作為參考,淘汰很久沒(méi)被訪問(wèn)過(guò)的數(shù)據(jù)了罪,
- LFU(Least Frequently Used锭环,最不頻繁使用的)以訪問(wèn)次數(shù)作為參考,淘汰最近一段時(shí)間被訪問(wèn)次數(shù)最少的數(shù)據(jù)
主動(dòng)刪除策略泊藕,主要有3個(gè)維度(a:對(duì)key有設(shè)置過(guò)期時(shí)間的 b:所有key辅辩,c:不處理)
(a) 針對(duì)設(shè)置了過(guò)期時(shí)間的key做處理:
- volatile-ttl(time-to-live):在篩選時(shí),會(huì)針對(duì)設(shè)置了過(guò)期時(shí)間的鍵值對(duì)娃圆,根據(jù)過(guò)期時(shí)間的先后進(jìn)行刪除玫锋,越早過(guò)期的越先被刪除。
- volatile-random:就像它的名稱(chēng)一樣讼呢,在設(shè)置了過(guò)期時(shí)間的鍵值對(duì)中撩鹿,進(jìn)行隨機(jī)刪除。
- volatile-lru:會(huì)使用 LRU 算法篩選設(shè)置了過(guò)期時(shí)間的鍵值對(duì)刪除悦屏。
- volatile-lfu:會(huì)使用 LFU 算法篩選設(shè)置了過(guò)期時(shí)間的鍵值對(duì)刪除节沦。
(b) 針對(duì)所有的key做處理:
- allkeys-random:從所有鍵值對(duì)中隨機(jī)選擇并刪除數(shù)據(jù)。
- allkeys-lru:使用 LRU 算法在所有數(shù)據(jù)中進(jìn)行篩選刪除础爬。
- allkeys-lfu:使用 LFU 算法在所有數(shù)據(jù)中進(jìn)行篩選刪除甫贯。
(c) 不處理:
- noeviction:不會(huì)剔除任何數(shù)據(jù),拒絕所有寫(xiě)入操作并返回客戶端錯(cuò)誤信息"(error)
主動(dòng)刪除策略配置建議
當(dāng)存在熱點(diǎn)數(shù)據(jù)時(shí)看蚜,LRU的效率很好叫搁,但偶發(fā)性的、周期性的批量操作會(huì)導(dǎo)致LRU命中率急劇下
降失乾,緩存污染情況比較嚴(yán)重常熙。這時(shí)使用LFU可能更好點(diǎn)。
根據(jù)自身業(yè)務(wù)類(lèi)型碱茁,配置好maxmemory-policy(默認(rèn)是noeviction)裸卫,推薦使用volatile-lru。如
果不設(shè)置最大內(nèi)存纽竣,當(dāng) Redis 內(nèi)存超出物理內(nèi)存限制時(shí)墓贿,內(nèi)存的數(shù)據(jù)會(huì)開(kāi)始和磁盤(pán)產(chǎn)生頻繁的交
換 (swap)茧泪,會(huì)讓 Redis 的性能急劇下降。
當(dāng)Redis運(yùn)行在主從模式時(shí)聋袋,只有主結(jié)點(diǎn)才會(huì)執(zhí)行過(guò)期刪除策略队伟,然后把刪除操作”del key”同
步到從結(jié)點(diǎn)刪除數(shù)據(jù)。