這篇文章主要介紹redis中過期鍵刪除策略和數(shù)據(jù)逐出策略的示例分析,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!
創(chuàng)新互聯(lián)建站是一家集網(wǎng)站建設(shè),會(huì)澤企業(yè)網(wǎng)站建設(shè),會(huì)澤品牌網(wǎng)站建設(shè),網(wǎng)站定制,會(huì)澤網(wǎng)站建設(shè)報(bào)價(jià),網(wǎng)絡(luò)營銷,網(wǎng)絡(luò)優(yōu)化,會(huì)澤網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強(qiáng)企業(yè)競(jìng)爭(zhēng)力。可充分滿足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時(shí)我們時(shí)刻保持專業(yè)、時(shí)尚、前沿,時(shí)刻以成就客戶成長(zhǎng)自我,堅(jiān)持不斷學(xué)習(xí)、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實(shí)用型網(wǎng)站。
Redis作為一個(gè)高性能的內(nèi)存NoSql數(shù)據(jù)庫,其容量受到最大內(nèi)存限制的限制。
在實(shí)際生產(chǎn)環(huán)境中使用Redis時(shí),偶然會(huì)覺得Redis的內(nèi)存占用要比自己預(yù)想的大。事實(shí)上,Redis占用的內(nèi)存除了保存鍵值對(duì)所需的開銷外,還有一些運(yùn)行時(shí)產(chǎn)生的額外內(nèi)存,包括:
過期Key所占空間
漸進(jìn)式Rehash導(dǎo)致未及時(shí)刪除的空間
Redis管理數(shù)據(jù),包括底層數(shù)據(jù)結(jié)構(gòu)開銷,客戶端信息,讀寫緩沖區(qū)等
主從復(fù)制,bgsave時(shí)的額外開銷
Redis的漸進(jìn)式Rehash,在筆者介紹Concurrenthashmap擴(kuò)容的時(shí)候,做了簡(jiǎn)單的介紹,點(diǎn)擊查看
Redis的主從復(fù)制,則在筆者的另一篇博客里做了詳細(xì)的介紹,點(diǎn)擊查看
所以本文將主要圍繞過期Key的回收問題進(jìn)行講解。
如果Redis的一個(gè)鍵是過期的,那它到了過期時(shí)間之后并不是馬上就從內(nèi)存中被刪除,而是采用了三種不同的刪除策略:
立即刪除
惰性刪除
定時(shí)刪除
其中第二種為被動(dòng)刪除,第一種和第三種為主動(dòng)刪除,而且第一種實(shí)時(shí)性更高。
立即刪除是指,在設(shè)置鍵的過期時(shí)間時(shí),創(chuàng)建一個(gè)回調(diào)事件,當(dāng)過期時(shí)間達(dá)到時(shí),由時(shí)間處理器自動(dòng)執(zhí)行鍵的刪除操作。
立即刪除能保證內(nèi)存中數(shù)據(jù)的最大新鮮度,因?yàn)樗WC過期鍵值會(huì)在過期后馬上被刪除,其所占用的內(nèi)存也會(huì)隨之釋放。但是立即刪除對(duì)cpu是最不友好的。因?yàn)閯h除操作會(huì)占用cpu的時(shí)間,如果剛好碰上了cpu正在做排序等計(jì)算的時(shí)候,就會(huì)給cpu造成額外的壓力。
而且目前redis事件處理器對(duì)時(shí)間事件的處理方式--無序鏈表,查找一個(gè)key的時(shí)間復(fù)雜度為O(n),所以并不適合用來處理大量的時(shí)間事件。
惰性刪除是指,某個(gè)鍵值過期后,此鍵值不會(huì)馬上被刪除,而是等到下次被使用的時(shí)候,才會(huì)被檢查到過期,此時(shí)才能得到刪除。所以惰性刪除的缺點(diǎn)很明顯:浪費(fèi)內(nèi)存。
舉個(gè)例子,對(duì)于一些按時(shí)間點(diǎn)來更新的數(shù)據(jù),比如log日志,過期后在很長(zhǎng)的一段時(shí)間內(nèi)可能都得不到訪問,這樣在這段時(shí)間內(nèi)就要浪費(fèi)這么多內(nèi)存來存log。
從上面分析來看,立即刪除會(huì)短時(shí)間內(nèi)占用大量cpu,惰性刪除會(huì)在一段時(shí)間內(nèi)浪費(fèi)內(nèi)存,所以定時(shí)刪除是一個(gè)折中的辦法。
定時(shí)刪除是指:每隔一段時(shí)間執(zhí)行一次刪除操作,并通過限制刪除操作執(zhí)行的時(shí)長(zhǎng)和頻率,來減少刪除操作對(duì)cpu的影響。另一方面定時(shí)刪除也有效的減少了因惰性刪除帶來的內(nèi)存浪費(fèi)。
Redis過期Key清理的機(jī)制對(duì)清理的頻率和最大時(shí)間都有限制,在盡量不影響正常服務(wù)的情況下,進(jìn)行過期Key的清理,以達(dá)到長(zhǎng)時(shí)間服務(wù)的性能最優(yōu)。
Redis會(huì)周期性的隨機(jī)測(cè)試一批設(shè)置了過期時(shí)間的key并進(jìn)行處理。測(cè)試到的已過期的key將被刪除。具體的算法如下:
Redis配置項(xiàng)hz定義了serverCron任務(wù)的執(zhí)行周期,默認(rèn)為10,即CPU空閑時(shí)每秒執(zhí)行10次;
每次過期key清理的時(shí)間不超過CPU時(shí)間的25%,即若hz=1,則一次清理時(shí)間最大為250ms,若hz=10,則一次清理時(shí)間最大為25ms;
清理時(shí)依次遍歷所有的db;
從db中隨機(jī)取20個(gè)key,判斷是否過期,若過期,則逐出;
若有5個(gè)以上key過期,則重復(fù)步驟4,否則遍歷下一個(gè)db;
在清理過程中,若達(dá)到了25%CPU時(shí)間,退出清理過程;
這是一個(gè)基于概率的簡(jiǎn)單算法,基本的假設(shè)是抽出的樣本能夠代表整個(gè)key空間,redis持續(xù)清理過期的數(shù)據(jù)直至將要過期的key的百分比降到了25%以下。
由于算法采用的隨機(jī)取key判斷是否過期的方式,故幾乎不可能清理完所有的過期Key。
調(diào)高h(yuǎn)z參數(shù)可以提升清理的頻率,過期key可以更及時(shí)的被刪除,但hz太高會(huì)增加CPU時(shí)間的消耗。
在redis中,允許用戶設(shè)置最大使用內(nèi)存大小maxmemory(需要配合maxmemory-policy使用),設(shè)置為0表示不限制(默認(rèn)配置)。 生產(chǎn)環(huán)境中需要設(shè)置此值,最好不超過內(nèi)存60%-70%。 當(dāng)redis內(nèi)存數(shù)據(jù)集快到達(dá)maxmemory時(shí),redis會(huì)實(shí)行數(shù)據(jù)淘汰策略。
Redis提供6種數(shù)據(jù)淘汰策略。在逐出算法中,根據(jù)用戶設(shè)置的逐出策略,選出待逐出的key,直到當(dāng)前內(nèi)存小于最大內(nèi)存值為止。
可選逐出策略如下:
volatile-lru:從已設(shè)置過期時(shí)間的數(shù)據(jù)集中挑選最近最少使用的數(shù)據(jù)淘汰
volatile-ttl:從已設(shè)置過期時(shí)間的數(shù)據(jù)集中挑選將要過期的數(shù)據(jù)淘汰
volatile-random:從已設(shè)置過期時(shí)間的數(shù)據(jù)集中任意選擇數(shù)據(jù) 淘汰
allkeys-lru:從數(shù)據(jù)集中挑選最近最少使用的數(shù)據(jù)淘汰
allkeys-random:從數(shù)據(jù)集中任意選擇數(shù)據(jù)淘汰
no-enviction(驅(qū)逐):禁止驅(qū)逐數(shù)據(jù)
在redis2.8中默認(rèn)策略是volatile-lru
在redis3.2和redis4.0中默認(rèn)策略是no-eviction
如果使用no-eviction時(shí),當(dāng)內(nèi)存不足,Redis會(huì)返回OOM的錯(cuò)誤信息
(error) OOM command not allowed when used memory > 'maxmemory'.
當(dāng)cache中沒有符合清除條件的key時(shí),回收策略 volatile-lru, volatile-random 和volatile-ttl 將會(huì)和策略 noeviction 一樣直接返回錯(cuò)誤。
選擇正確的回收策略是很重要的,取決于你的應(yīng)用程序的訪問模式。使用INFO命令輸出來監(jiān)控緩存命中和錯(cuò)過的次數(shù),以調(diào)優(yōu)Redis的配置。
通用規(guī)則如下:
如果期望用戶請(qǐng)求呈現(xiàn)冪律分布(power-law distribution),也就是,期望一部分子集元素被訪問得遠(yuǎn)比其他元素多時(shí),可以使用allkeys-lru策略。
如果期望是循環(huán)周期的訪問,所有的鍵被連續(xù)掃描,或者期望請(qǐng)求符合平均分布(每個(gè)元素以相同的概率被訪問),可以使用allkeys-random策略。
如果期望是讓redis使用緩存對(duì)象設(shè)置的TTL值,確定哪些對(duì)象應(yīng)該是較好的清除候選項(xiàng),可以使用volatile-ttl策略。
以上是“Redis中過期鍵刪除策略和數(shù)據(jù)逐出策略的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對(duì)大家有幫助,更多相關(guān)知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!