摘要:的過期策略是什么樣的采用了定期刪除惰性刪除的過期策略。定期刪除原理定期刪除指的是默認(rèn)每隔就隨機(jī)抽取一些設(shè)置了過期時(shí)間的,檢測(cè)這些是否過期,如果過期了就將其刪掉。所有只會(huì)抽取一部分而不會(huì)全部檢查。
1.數(shù)據(jù)為什么會(huì)過期?首先,要明白redis是用來做數(shù)據(jù)緩存的,不是用來做數(shù)據(jù)存儲(chǔ)的(當(dāng)然也可以當(dāng)數(shù)據(jù)庫用),所以數(shù)據(jù)時(shí)候過期的,過期的數(shù)據(jù)就不見了,過期主要有兩種情況,
①在設(shè)置緩存數(shù)據(jù)時(shí)制定了過期時(shí)間,這樣到了過期時(shí)間數(shù)據(jù)就不見了。
②redis的數(shù)據(jù)是存放在內(nèi)存中的,而內(nèi)存是有限的,是不可能放過多數(shù)據(jù)的,比如只有10G的內(nèi)存,想要向里面放入20G的數(shù)據(jù),那么就注定會(huì)有10G的數(shù)據(jù)會(huì)丟失。
redis采用了 “定期刪除+惰性刪除” 的過期策略。
①定期刪除
原理:定期刪除指的是redis默認(rèn)每隔100ms就隨機(jī)抽取一些設(shè)置了過期時(shí)間的key,檢測(cè)這些key是否過期,如果過期了就將其刪掉。
為什么會(huì)選擇一部分,而不是全部:因?yàn)槿绻@是redis里面有大量的key都設(shè)置了過期時(shí)間,那么如果全部去檢測(cè)一遍,CPU負(fù)載就會(huì)很高,會(huì)浪費(fèi)大量的時(shí)間在檢測(cè)上面,甚至直接導(dǎo)致redis掛掉。所有只會(huì)抽取一部分而不會(huì)全部檢查。
出現(xiàn)問題:這樣的話就會(huì)出現(xiàn)大量的已經(jīng)過期的key并沒有被刪除,這就是 為什么有時(shí)候大量的key明明已經(jīng)過了失效時(shí)間,但是redis的內(nèi)存還是被大量占用的原因 ,為了解決這個(gè)問題,就需要 惰性刪除 這個(gè)策略了。
②惰性刪除
原理:惰性刪除不在是redis去主動(dòng)刪除,而是在你要獲取某個(gè)key 的時(shí)候,redis會(huì)先去檢測(cè)一下這個(gè)key是否已經(jīng)過期,如果沒有過期則返回給你,如果已經(jīng)過期了,那么redis會(huì)刪除這個(gè)key,不會(huì)返回給你。
這樣兩種策略就保證了 過期的key最終一定會(huì)被刪除掉 ,但是這只是保證了最終一定會(huì)被刪除,要是定時(shí)刪除漏掉了大量過期的key,而且我們也沒有及時(shí)的去訪問這些key,那么這些key不就不會(huì)被刪除了嗎?不就會(huì)一直占著我們的內(nèi)存嗎");
由于存在這樣的問題,所以redis引入了 內(nèi)存淘汰機(jī)制 來解決。
內(nèi)存淘汰機(jī)制就保證了在redis的內(nèi)存占用過多的時(shí)候,去進(jìn)行內(nèi)存淘汰,也就是刪除一部分key,保證redis的內(nèi)存占用率不會(huì)過高,那么它會(huì)刪除那些key呢?
redis提供了6中內(nèi)存淘汰策略,我們可以去進(jìn)行選擇,六中策略如下:
①noeviction:當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時(shí),新寫入操作會(huì)報(bào)錯(cuò),無法寫入新數(shù)據(jù),一般不采用。
②allkeys-lru:當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時(shí),在鍵空間中,移除最近最少使用的key,這個(gè)是最常用的。
③allkeys-random:當(dāng)內(nèi)存不足以容納新寫入的數(shù)據(jù)時(shí),在鍵空間中,隨機(jī)移除key,一般也不使用。
④volatile-lru:volatile-lru:當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時(shí),在設(shè)置了過期時(shí)間的鍵空間中,移除最近最少使用的key(這個(gè)一般不太合適) 。
⑤volatile-random:當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時(shí),在設(shè)置了過期時(shí)間的鍵空間中,隨機(jī)移除某個(gè)key 。
⑥volatile-ttl:當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時(shí),在設(shè)置了過期時(shí)間的鍵空間中,有更早過期時(shí)間的key優(yōu)先移除。
//基于JavaLinkedHashMap實(shí)現(xiàn)
public class LRUCache extends LinkedHashMap{
private final int CACHE_SIZE;
//保存?zhèn)鬟f進(jìn)來的最大數(shù)據(jù)量
public LRUCache(int cacheSize){
//設(shè)置hashmap的初始大小,同時(shí)最后一個(gè)true指的是讓linkedhashmap按照訪問順序來進(jìn)行排序,
//最近訪問的放在頭,最老訪問的放在尾
super((int)Math.ceil(cacheSize/0.75)+1,0.75f,true);
CACHE_SIZE = CacheSize;
}
@Override
protected boolean removeEldestEntry(Map.Entry eldest){
//當(dāng)map中的數(shù)據(jù)量大于指定的緩存?zhèn)€數(shù)的時(shí)候,就自動(dòng)刪除最老的數(shù)據(jù)。
return size() > CACHE_SIZE;
}
}
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/7197.html
摘要:事件分派器會(huì)根據(jù)每個(gè)當(dāng)前產(chǎn)生的事件,來選擇對(duì)應(yīng)的事件處理器來處理。核心是基于非阻塞的多路復(fù)用機(jī)制單線程避免了多線程上下文切換的開銷。 1.memcached和redis有什么區(qū)別? (1)Redis支持服務(wù)器端的數(shù)據(jù)操作 redis和memcached相比,redis擁有更多的 數(shù)據(jù)結(jié)構(gòu)并且支持更豐富的數(shù)據(jù)操作 ,通常在memcached里面,你需要將數(shù)據(jù)拿到客戶端來進(jìn)行類型的修改然后在se...
摘要:這個(gè)是類似的一種結(jié)構(gòu),這個(gè)一般就是可以將結(jié)構(gòu)化的數(shù)據(jù),比如一個(gè)對(duì)象前提是這個(gè)對(duì)象沒嵌套其他的對(duì)象給緩存在里,然后每次讀寫緩存的時(shí)候,可以就操作里的某個(gè)字段。 1.string 這是最基本的類型了,就是普通的set和get,做簡(jiǎn)單的kv緩存。 2.hash 這個(gè)是類似map的一種結(jié)構(gòu),這個(gè)一般就是可以將結(jié)構(gòu)化的數(shù)據(jù),比如一個(gè)對(duì)象(前提是這個(gè)對(duì)象沒嵌套其他的對(duì)象)給緩存在redis里,然后每次...
閱讀 2271·2021-10-09 09:41
閱讀 3426·2021-09-13 10:34
閱讀 1932·2019-08-30 12:59
閱讀 570·2019-08-29 17:27
閱讀 1070·2019-08-29 16:07
閱讀 2964·2019-08-29 13:15
閱讀 1316·2019-08-29 13:14
閱讀 1571·2019-08-26 12:18