簡單總結哈,LRU+雙向鏈表實現緩存, 和Redis的

 1. Least Recently Used   

最近最少使用淘汰機制, 訪問一個key在map中,也就是 在內存中, 就將此頁放到建表頭部, , 不在內存中, (假如規定鏈表只能有三個節點, 當訪問第四個時, 如果值不在內存中, 那就釋放鏈表最尾部的節點, 然後將此值包裝成節點, 放入頭部)  就先去磁盤取.    

2. 爲什麼不使用雙向鏈表   

使用雙向鏈表, 每個節點會增加兩個指針的空間消耗

3. redis不使用鏈表, 那用什麼結構或者屬性實現LRU淘汰策略

redis採用設置  全局 server-lruclock   時鐘,  每個節點有一個  lru時間戳    屬性, 類似於兩個時間戳

1. 訪問節點時候會將server-lruclock 複製給lru , 避免系統調用, 造成上下文切換

2. 而 全局的server-lruclock跟根據全局變量server.hz來調用系統操作實現更新

4. redis採用的一些內存策略

1. 定期刪除+惰性刪除

定期刪除 , 每隔一定時間, 根據maxmemory_samples設置的個數,  選取這麼多節點進行檢查過期,  一次性檢查全部, 會造成卡頓

惰性刪除, 你訪問一個key, 會看看過期沒, 過期了就刪除

4.1 那內存還是會滿怎麼辦, 那就出現淘汰策略

Redis系統提供五種淘汰策略,即參數maxmemory_policy有五種取值:

noeviction: 如果緩存數據超過了maxmemory限定值,並且客戶端正在執行的命令會導致內存分配,則向客戶端返回錯誤響應.

allkeys-lru: 所有的緩存數據(包括沒有超時屬性的和具有超時屬性的)都參與LRU算法淘汰.

volatile-lru: 只有超時屬性的緩存數據才參與LRU算法淘汰.

allkeys-random: 所有的緩存數據(包括沒有超時屬性的和具有超時屬性的)都參與淘汰, 但是採用隨機淘汰,而不是用LRU算法進行淘汰.

volatile-random: 只有超時屬性的緩存數據才參與淘汰,但是採用隨機淘汰,而不是用LRU算法進行淘汰.

volatile-ttl: 只有超時屬性的緩存數據才參與淘汰. 根據緩存數據的超時TTL進行淘汰,而不是用LRU算法進行淘汰.

4.2 怎樣實現LRU呢

根據3中描述的結構屬性,  全局屬性和節點私有兩個屬性差值越大說明, 最近最少訪問, 然後淘汰

如果淘汰策略是allkeys-random或者volatile-random,則從相應數據庫中隨機選擇一個key進行淘汰.

如果淘汰策略是allkeys-lru或者volatile-lru, 則根據配置的採樣值maxmemory_samples,隨機從數據庫中選擇maxmemory_samples個key, 淘汰其中熱度最低的key對應的緩存數據.

如果淘汰策略是volatile-ttl,則根據配置的採樣值maxmemory_samples,隨機從數據庫中選擇maxmemory_samples個key,淘汰其中最先要超時的key對應的緩存數據.

所以採樣參數maxmemory_samples配置的數值越大, 就越能精確的查找到待淘汰的緩存數據,但是也消耗更多的CPU計算,執行效率降
 

引用大佬~ https://blog.csdn.net/azurelaker/article/details/85045245

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章