# 27 | 緩存被汙染了,該怎麼辦? ## 緩存汙染 有些數據被訪問的次數非常少,甚至只會被訪問一次。當這些數據服務完訪問請求後,如果還繼續留存在緩存中的話,就只會白白佔用緩存空間。這種情況,就是緩存汙染。 ## 如何解決緩存汙染問題? 分析前幾章提到的淘汰策略是否可以解決緩存污染 ### volatile-random 和 allkeys-random 效果非常有限  假設我們配置 Redis 緩存使用 allkeys-random 淘汰策略,當緩存寫滿時,allkeys-random 策略隨機選擇了數據 20 進行淘汰。不巧的是,數據 20 緊接著又被訪問了,此時,Redis 就會發生了緩存缺失,降低了應用的請求響應速度。 ### volatile-ttl 效果非常有限 複習:針對的是設置了過期時間的數據,把這些數據中剩餘存活時間最短的篩選出來並淘汰掉。 剩餘存活時間並不能直接反映數據再次訪問的情況。所以,按照 volatile-ttl 策略淘汰數據,和按隨機方式淘汰數據類似,也可能出現數據被淘汰後,被再次訪問導致的緩存缺失問題。 ### LRU 緩存策略 效果有限 複習:LRU 策略的核心思想:如果一個數據剛剛被訪問,那麼這個數據肯定是熱數據,還會被再次訪問。 在進行數據淘汰時,LRU 策略會在候選數據集中淘汰掉 lru 字段值最小的數據(也就是訪問時間最久的數據)。  ### LFU 緩存策略的優化 LFU 緩存策略是在 LRU 策略基礎上,為每個數據增加了一個計數器,來統計這個數據的訪問次數。 LFU 策略篩選淘汰數據時,首先會根據數據的訪問次數進行篩選,把訪問次數最低的數據淘汰出緩存。如果兩個數據的訪問次數相同,LFU 策略再比較這兩個數據的訪問時效性,把距離上一次訪問時間更久的數據淘汰出緩存。 Redis 在實現 LFU 策略的時候,只是把原來 24bit 大小的 lru 字段,又進一步拆分成了兩部分。 - ldt 值:lru 字段的前 16bit,表示數據的訪問時間戳; - counter 值:lru 字段的後 8bit,表示數據的訪問次數。Redis 只使用了 8bit 記錄數據的訪問次數,而 8bit 記錄的最大值是 255 並不是數據被訪問一次 counter 值就會 +1  一般可以將 lfu_log_factor 取值為 10 ### LFU 衰減機制 Redis 在實現 LFU 策略時,還設計了一個 counter 值的衰減機制。LFU 策略使用衰減因子配置項 lfu_decay_time 來控制訪問次數的衰減 舉個例子,假設 lfu_decay_time 取值為 1,如果數據在 N 分鐘內沒有被訪問,那麼它的訪問次數就要減 N。如果 lfu_decay_time 取值更大,那麼相應的衰減值會變小,衰減效果也會減弱。所以,如果業務應用中有短時高頻訪問的數據的話,建議把 lfu_decay_time 值設置為 1,這樣一來,LFU 策略在它們不再被訪問後,會較快地衰減它們的訪問次數,儘早把它們從緩存中淘汰出去,避免緩存汙染。
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up