Redis緩存淘汰策略

常用緩存策略

常用的緩存淘汰策略有以下

  • 先進先出算法(FIFO)
  • Least Frequently Used(LFU)
    淘汰一定時期內被訪問次數最少的頁面,以次數作爲參考
  • Least Recently Used(LRU)
    淘汰最長時間未被使用的頁面,以時間作爲參考

這些算法在不同層次的緩存上執行時擁有不同的效率和代價,需根據具體場合選擇最合適的一種。

FIFO

FIFO(First in First out),先進先出。在FIFO Cache設計中,核心原則就是:如果一個數據最先進入緩存中,則應該最早淘汰掉。

1、利用一個雙向鏈表保存數據,
2、當來了新的數據之後便添加到鏈表末尾,
3、如果Cache存滿數據,則把鏈表頭部數據刪除,
4、然後把新的數據添加到鏈表末尾。
5、在訪問數據的時候,如果在Cache中存在該數據的話,則返回對應的value值;
6、否則返回-1。如果想提高訪問效率,可以利用hashmap來保存每個key在鏈表中對應的位置。

LFU

 

 

1、新加入數據插入到隊列尾部(因爲引用計數爲1);
2、 隊列中的數據被訪問後,引用計數增加,隊列重新排序;
3、當需要淘汰數據時,將已經排序的列表最後的數據塊刪除。

LRU

 

 

1、新數據插入到鏈表頭部;
2、每當緩存命中(即緩存數據被訪問),則將數據移到鏈表頭部;
3、當鏈表滿的時候,將鏈表尾部的數據丟棄。

Two queues(2Q)

2Q算法有兩個緩存隊列,一個是FIFO隊列,一個是LRU隊列。當數據第一次訪問時,2Q算法將數據緩存在FIFO隊列裏面,當數據第二次被訪問時,則將數據從FIFO隊列移到LRU隊列裏面,兩個隊列各自按照自己的方法淘汰數據。詳細實現如下:

 

 

  1. 新訪問的數據插入到FIFO隊列;
  2. 如果數據在FIFO隊列中一直沒有被再次訪問,則最終按照FIFO規則淘汰;
  3. 如果數據在FIFO隊列中被再次訪問,則將數據移到LRU隊列頭部;
  4. 如果數據在LRU隊列再次被訪問,則將數據移到LRU隊列頭部;
  5. LRU隊列淘汰末尾的數據。

這種情況適用與以下場景
當存在熱點數據時,LRU的效率很好,但偶發性的、週期性的批量操作會導致LRU命中率急劇下降,緩存污染情況比較嚴重。

週期性的批量操作,會立即淘汰LRU隊列中的大量數據,導致緩存命中率大幅度下降。而APP常規操作中,有大量偶發批量操作,比如:進入頁面後立即返回,就是很典型的一種。

所以LRU算法並不是一個非常好的選擇。

轉自:https://www.cnblogs.com/zhangfengshi/p/11466263.html