本地緩存實現 需要考慮幾個方面
- 2020 年 2 月 18 日
- 筆記
1、存儲集合的選擇
實現本地緩存,存儲容器肯定是 key/value 形式的數據結構,在 Java 中,也就是我們常用的 Map 集合。Map 中有 HashMap、Hashtable、ConcurrentHashMap 幾種供我們選擇,如果不考慮高並發情況下數據安全問題,我們可以選擇HashMap,如果考慮高並發情況下數據安全問題,我們可以選擇 Hashtable、ConcurrentHashMap 中的一種集合,但是我們優先選擇 ConcurrentHashMap,因為 ConcurrentHashMap 的性能比 Hashtable 要好。
2、過期緩存處理
因為緩存直接存儲在內存中,如果我們不處理過期緩存,內存將被大量無效緩存佔用,這不是我們想要的,所以我們需要清理這些失效的緩存。過期緩存處理可以參考 Redis 的策略來實現,Redis 採用的是定期刪除 + 懶惰淘汰策略。
定期刪除策略
定期刪除策略是每隔一段時間檢測已過期的緩存,並且降之刪除。這個策略的優點是能夠確保過期的緩存都會被刪除。同時也存在着缺點,過期的緩存不一定能夠及時的被刪除,這跟我們設置的定時頻率有關係,另一個缺點是如果緩存數據較多時,每次檢測也會給 cup 帶來不小的壓力。
懶惰淘汰策略
懶惰淘汰策略是在使用緩存時,先判斷緩存是否過期,如果過期將它刪除,並且返回空。這個策略的優點是只有在查找的時候,才判斷是否過期,對 CUP 影響較。同時這種策略有致命的缺點,當存入了大量的緩存,這些緩存都沒有被使用並且已過期,都將成為無效緩存,這些無效的緩存將佔用你大量的內存空間,最後導致服務器內存溢出。
可以參考Redis:兩種並用 ,懶惰淘汰 和定時 隨機20個檢查,失效率超過多少繼續檢查,但如果到了時間也會停止
3、緩存淘汰策略
緩存淘汰跟過期緩存處理要區別開來,緩存淘汰是指當我們的緩存個數達到我們指定的緩存個數時,畢竟我們的內存不是無限的。如果我們需要繼續添加緩存的話,我們就需要在現有的緩存中根據某種策略淘汰一些緩存,給新添加的緩存騰出位置,下面一起來認識幾種常用的緩存淘汰策略。
先進先出策略
最先進入緩存的數據在緩存空間不夠的情況下會被優先被清除掉,以騰出新的空間接受新的數據。該策略主要比較緩存元素的創建時間。在一些對數據實效性要求比較高的場景下,可考慮選擇該類策略,優先保障最新數據可用。
最少使用策略
無論是否過期,根據元素的被使用次數判斷,清除使用次數較少的元素釋放空間。該策略主要比較元素的hitCount(命中次數),在保證高頻數據有效性場景下,可選擇這類策略。
最近最少使用策略
無論是否過期,根據元素最後一次被使用的時間戳,清除最遠使用時間戳的元素釋放空間。該策略主要比較緩存最近一次被get使用時間。在熱點數據場景下較適用,優先保證熱點數據的有效性。
兩種辦法:一借用LinkedHashMap,每次操作都會排序 ,二每個緩存對象攜帶最近使用時間,淘汰時需要遍歷整個表