Redis 过期键删除策略、内存淘汰机制
文章目錄
- 過期鍵刪除策略
- 定時刪除
- 惰性刪除
- 定期刪除
- Redis的選擇
- 內(nèi)存淘汰機制
redis中緩存的數(shù)據(jù)是有過期時間的,當緩存數(shù)據(jù)失效時,redis會刪除過期數(shù)據(jù)以節(jié)省內(nèi)存,那redis是怎樣怎樣的策略來刪除過期數(shù)據(jù)的呢?
過期鍵刪除策略
過期刪除策略通常有以下三種
- 定時刪除:在為鍵設置過期時間的同時創(chuàng)建一個定時器,當過期時間到來時就會觸發(fā)定時器中的處理函數(shù),立即執(zhí)行過期鍵的刪除操作
- 定期刪除:每隔一段時間就對數(shù)據(jù)庫進行一次檢查,刪除其中的過期鍵。檢查的數(shù)據(jù)庫數(shù)量及刪除的過期鍵數(shù)量由算法決定
- 惰性刪除:不會主動去刪除過期鍵。每次獲取鍵時都會判斷獲取的鍵是否過期,如果過期則刪除,沒過期則返回
其中前兩種為主動刪除策略,最后一種為被動刪除策略。下面就來談談這三種策略的優(yōu)缺點以及Redis中究竟使用的哪一種
定時刪除
定時刪除策略對于內(nèi)存來說十分友好,通過定時器能夠保證過期鍵能夠在第一時間被刪除,而不會一直占用內(nèi)存。
但是同樣的,它對CPU時間非常不友好。在過期鍵比較多的時候,維護大量的定時器會給CPU帶來巨大的壓力,即使過期鍵少的時候,它也會將寶貴的CPU時間用在維護定時器,以及刪除和當前任務無關的過期鍵上,對服務器的響應時間與吞吐量造成了一定的影響。
惰性刪除
從開始的描述可以看出,惰性刪除對于CPU時間來說是最為友好的,因為我們只會在取出鍵的時候才會對其進行刪除操作,這也就保證了我們不會在執(zhí)行其他任務的時候又背地里去刪除無關的過期鍵,合理的利用了CPU時間。
但是!!!也正是因為這個原因,使得它對內(nèi)存極度不友好。如果一個鍵已經(jīng)過期,而只要我們不去獲取這個鍵,就不會觸發(fā)過期檢查,那也就意味著他會一直占用這一塊內(nèi)存而不釋放。
這意味著什么呢?如果我們有非常多的過期鍵,而這些過期鍵又恰好因為版本迭代、項目組交替,在后續(xù)版本中并沒有對其進行訪問,那么它可能永遠也不會被刪除。我們可以將這種情況當成內(nèi)存泄漏中的一種,對于Redis這種內(nèi)存數(shù)據(jù)庫來說,這種情況造成的后果十分嚴重
定期刪除
定期刪除策略其實是上述兩種策略的折中選擇。
定期刪除策略相對于定時刪除策略來說,由于其每隔一段時間才進行一次刪除操作,通過限制了刪除操作的時常和頻率,大大減少了刪除操作對CPU時間的影響。
相比于惰性刪除,并且由于定期刪除過期鍵,有效地減少了過期鍵帶來的空間浪費。即兼顧了CPU,又避免了內(nèi)存浪費,是兩者的折中選擇。
但是上述這些優(yōu)點的前提,就是我們必須要確定一個合理的刪除操作的時長和頻率。
- 如果刪除操作過于頻繁,則又退化成了定時刪除策略,浪費了大量的CPU時間
- 如果刪除操作執(zhí)行過少,則又會像惰性刪除一樣,出現(xiàn)大量的內(nèi)存浪費問題。
Redis的選擇
下面給出三種的效率對比
CPU:惰性刪除 > 定期刪除 > 定時刪除
內(nèi)存利用率:定時刪除 > 定期刪除 > 惰性刪除
- 定時刪除占用太多CPU時間,影響服務器的吞吐量和性能,但是很好的避免了內(nèi)存浪費
- 惰性刪除浪費太多內(nèi)存,有內(nèi)存泄漏的風險,但是卻保證了CPU的效率
- 定期刪除屬于前兩種的折中,既保證了CPU時間的合理利用,又避免了內(nèi)存的浪費
為了能夠在合理利用CPU時間與避免浪費內(nèi)存空間之間取得平衡,Redis同時使用了惰性刪除和定期刪除。
這樣的搭配雖然保證了Redis強大的吞吐量以及響應速度,但是卻存在因為沒有定時刪除機制,所以存在著內(nèi)存浪費問題。
由于Redis中通常存儲的數(shù)據(jù)量十分龐大,這就導致了定期刪除每次只能抽取其中的一部分進行刪除,倘若有一部分過期鍵一直沒有被抽取到,并且我們也一直沒有訪問它來觸發(fā)惰性刪除,這個過期鍵就會一直存在內(nèi)存中,如果不進行處理,就可能導致內(nèi)存耗盡。
為了解決這個問題,Redis又引入了內(nèi)存淘汰機制
內(nèi)存淘汰機制
當Redis的內(nèi)存占用過高時,如果內(nèi)存不足以容納新寫入的數(shù)據(jù),就會通過某種機制來刪除一部分鍵,來減少當前占用的內(nèi)存,這就是內(nèi)存淘汰機制。
當前Redis提供了8種內(nèi)存淘汰策略,除卻之前的6種,還有兩種Redis4.0后新增的LFU模式:volatile-lfu以及allkeys-lfu
| volatile-lru | 在已設置過期時間的key中,挑選最近最少使用的key淘汰 |
| volatile-lfu | 在已設置過期時間的key中,挑選最不經(jīng)常使用的key淘汰 |
| volatile-ttl | 在已設置過期時間的key中,挑選將要過期的key淘汰 |
| volatile-random | 在已設置過期時間的key中,隨機挑選key淘汰 |
| allkeys-lru | 在所有key中,挑選最近最少使用的key淘汰 |
| allkeys-lfu | 在所有key中, 挑選最不經(jīng)常使用的key淘汰 |
| allkeys-random | 在所有key中,隨機挑選key淘汰 |
| no-eviction | 當內(nèi)存不足以寫入新數(shù)據(jù)時,寫入操作會報錯,并且不會淘汰數(shù)據(jù)(不常用) |
乍一看策略很多很難記,其實總共就是四種不同的淘汰策略,以及兩種key的選擇范圍
選擇范圍
- allkeys:淘汰的范圍為所有的key
- volatile:淘汰的范圍為已設置過期時間的key
淘汰策略
- LRU:Least recently used,即淘汰最近最少使用的key
- LFU:Least Frequently Used,即淘汰最不經(jīng)常使用的key
- TTL:Time To Live,即淘汰生命時間最短,即將要過期的key
- Random:隨機淘汰
其中LRU和LFU較為常用,如果有想了解其算法原理的,可以看看我的往期博客
高級數(shù)據(jù)結(jié)構(gòu)與算法 | LRU緩存機制(Least Recently Used)
高級數(shù)據(jù)結(jié)構(gòu)與算法 | LFU緩存機制(Least Frequently Used)
總結(jié)
以上是生活随笔為你收集整理的Redis 过期键删除策略、内存淘汰机制的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Redis 特殊数据类型 :Geospa
- 下一篇: 高级数据结构与算法 | LFU缓存机制(