一、redis緩存數(shù)據(jù),內(nèi)存占滿,怎么解決
(1)默認(rèn)情況下,redis在使用的內(nèi)存空間超過maxmemory值時(shí),并不會(huì)淘汰數(shù)據(jù),也就是設(shè)置的noeviction策略。對應(yīng)到redis緩存,也就是值,一旦緩存被寫滿了,再有寫請求到來時(shí),redis不會(huì)提供服務(wù),而是直接返回錯(cuò)誤。(因此不推薦使用)
(2)對于 volatile-random、volatile-ttl、volatile-lru 和 volatile-lfu這四種淘汰策略,它們篩選的候選數(shù)據(jù)范圍,被限制在已經(jīng)設(shè)置了過期時(shí)間的鍵值對上。也正是因?yàn)槿绱耍词咕彺鏇]有寫滿,這些數(shù)據(jù)如果過期了,也會(huì)被刪除。
volatile-ttl 在篩選時(shí),會(huì)針對設(shè)置了過期時(shí)間的鍵值對,根據(jù)過期時(shí)間的先后進(jìn)行刪除,越早過期的越先被刪除。volatile-random 就像它的名稱一樣,在設(shè)置了過期時(shí)間的鍵值對中,進(jìn)行隨機(jī)刪除。volatile-lru 會(huì)使用 LRU 算法篩選設(shè)置了過期時(shí)間的鍵值對。volatile-lfu 會(huì)使用 LFU 算法選擇設(shè)置了過期時(shí)間的鍵值對。(LFU算法會(huì)在LRU算法的基礎(chǔ)上,同時(shí)考慮數(shù)據(jù)的訪問時(shí)效性和數(shù)據(jù)的訪問次數(shù))(3)對于allkeys-lru、allkeys-random、allkeys-lfu這三種淘汰策略的備選淘汰數(shù)據(jù)范圍,擴(kuò)大到了所有鍵值對,無論這些鍵值對是否設(shè)置了過期時(shí)間。
allkeys-random 策略,從所有鍵值對中隨機(jī)選擇并刪除數(shù)據(jù);allkeys-lru 策略,使用 LRU 算法在所有數(shù)據(jù)中進(jìn)行篩選。allkeys-lfu 策略,使用 LFU 算法在所有數(shù)據(jù)中進(jìn)行篩選也就是說,如果一個(gè)鍵值對被刪除策略選中了,即使它的過期時(shí)間還沒到,也需要被刪除。當(dāng)然,如果它的過期時(shí)間到了但未被策略選中,同樣也會(huì)被刪除。
怎么使用呢?
優(yōu)先使用allkeys-lru策略。這樣,可以充分利用LRU算法的優(yōu)勢,把最近最常訪問的數(shù)據(jù)留在緩存中,提升應(yīng)用的訪問性能。如果你的業(yè)務(wù)數(shù)據(jù)中有明顯的冷熱數(shù)據(jù)的區(qū)分,建議使用allkeys-lru策略如果業(yè)務(wù)應(yīng)用中的數(shù)據(jù)訪問頻率不大,沒有明顯的冷熱數(shù)據(jù)區(qū)分,建議使用allkeys-random策略,隨機(jī)淘汰數(shù)據(jù)即可如果業(yè)務(wù)有置頂?shù)男枨?,比如置頂新聞、置頂視頻,那么,可以使用 volatile-lru策略,同時(shí)不給這些置頂數(shù)據(jù)設(shè)置過期時(shí)間。這樣一來,這些需要置頂?shù)臄?shù)據(jù)一直不會(huì)被刪除,而其他數(shù)據(jù)會(huì)在過期時(shí)根據(jù) LRU 規(guī)則進(jìn)行篩選。LRU算法
LRU 算法的全稱是 Least Recently Used,從名字上就可以看出,這是按照最近最少使用的原則來篩選數(shù)據(jù),最不常用的數(shù)據(jù)會(huì)被篩選出來,而最近頻繁使用的數(shù)據(jù)會(huì)留在緩存中。
那具體是怎么篩選的呢? LRU會(huì)把所有的數(shù)據(jù)組織成一個(gè)鏈表,鏈表的頭和尾分別表示MRU端和LRU段,分別代表最近最常使用的數(shù)據(jù)和最近最不常用的數(shù)據(jù)。
我們現(xiàn)在有數(shù)據(jù) 6、3、9、20、5。如果數(shù)據(jù) 20 和 3 被先后訪問,它們都會(huì)從現(xiàn)有的鏈表位置移到 MRU 端,而鏈表中在它們之前的數(shù)據(jù)則相應(yīng)地往后移一位。因?yàn)?,LRU 算法選擇刪除數(shù)據(jù)時(shí),都是從 LRU 端開始,所以把剛剛被訪問的數(shù)據(jù)移到 MRU 端,就可以讓它們盡可能地留在緩存中。如果有一個(gè)新數(shù)據(jù) 15 要被寫入緩存,但此時(shí)已經(jīng)沒有緩存空間了,也就是鏈表沒有空余位置了,那么,LRU 算法做兩件事:數(shù)據(jù) 15 是剛被訪問的,所以它會(huì)被放到 MRU 端;算法把 LRU 端的數(shù)據(jù) 5 從緩存中刪除,相應(yīng)的鏈表中就沒有數(shù)據(jù) 5 的記錄了。其實(shí),LRU 算法背后的想法非常樸素:它認(rèn)為剛剛被訪問的數(shù)據(jù),肯定還會(huì)被再次訪問,所以就把它放在 MRU 端;長久不訪問的數(shù)據(jù),肯定就不會(huì)再被訪問了,所以就讓它逐漸后移到 LRU 端,在緩存滿時(shí),就優(yōu)先刪除它。
不過,LRU算法在實(shí)際實(shí)現(xiàn)時(shí),需要用鏈表管理所有的緩存數(shù)據(jù),這會(huì)帶來額外的空間開銷。而且,當(dāng)有數(shù)據(jù)被訪問時(shí),需要在鏈表上把該數(shù)據(jù)移動(dòng)到MRU端,如果有大量數(shù)據(jù)被訪問,就會(huì)帶來很多鏈表移動(dòng)操作,會(huì)很耗時(shí),進(jìn)而降低redis緩存性能。
所以,在redis中,LRU算法被做了簡化,以減輕淘汰數(shù)據(jù)對緩存性能的影響。
延伸閱讀:
二、實(shí)例(instance)是什么
一組Oracle 后臺(tái)進(jìn)程/線程以及一個(gè)共享內(nèi)存區(qū),這些內(nèi)存由同一個(gè)計(jì)算機(jī)上運(yùn)行的線程/進(jìn)程所共享。這里可以維護(hù)易失的、非持久性內(nèi)容(有些可以刷新輸出到磁盤)。就算沒有磁盤存儲(chǔ),數(shù)據(jù)庫實(shí)例也能存在。也許實(shí)例不能算是世界上最有用的事物,不過你完全可以把它想成是最有用的事物,這有助于對實(shí)例和數(shù)據(jù)庫劃清界線。