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