1. 程式人生 > >資料快取策略 快取淘汰算法系列

資料快取策略 快取淘汰算法系列

一、前言

  快取演算法歷史已經很久了,但在樓主查詢相關資料時,發現知識零碎,且原理介紹的很不詳細,遂有了總結常用快取演算法文章的想法,以供廣大朋友們查閱。本文是快取系列的第一篇,知識側重於初略的介紹,並未深入。

二、NRU(Not recently used)

  1、演算法思想

    NRU演算法的思想是保留最近使用過的物件。

  2、工作原理

    快取維護兩個標記位,初始值為0。一個標記位R標識物件是否被使用過,另一個M用來標識物件是否被修改過。當一個物件在快取中找到時,R置為1(referenced);當一個物件被修改時,M置為1(modified)。一個物件擁有的標記位有4種狀態:

    3. referenced, modified

    2. referenced, not modified

    1. not referenced, modified

    0. not referenced, not modified

    當快取已滿,但新的物件需要加入快取時,從等級(上面狀態最左邊的數字代表等級)最低的物件中隨機淘汰一個。

    同時,快取還有一個週期性的時鐘,它在每個時間間隔會把所有物件的R標記為清零(這樣就知道該物件最近,也就是一個時間間隔,是否被使用),但M不會清零。所以上面not referenced, modified狀態看似不可能,但在經歷過一個時間間隔,R位被清零時將有可能發生。

    注意,該演算法認為,最近被使用過的物件,比最近被修改過的物件更重要。

 三、FIFO(First-in, first-out)

   1、演算法思想

    該演算法是最簡單的快取淘汰演算法,其原理正如它名字一樣,最近使用過的物件放到快取佇列的末尾,佇列頭部儲存的是最早使用的物件。

四、Second-chance

  1、演算法思想

    這是FIFO演算法的改進版,相對於FIFO演算法立刻淘汰物件,該演算法會檢查待淘汰物件的引用標誌位。如果物件被引用過,該物件引用位清零,重新插入佇列尾部,像新的物件一樣;如果該物件未被引用過,則將被淘汰。

  2、工作原理

    在FIFO演算法的基礎上,

    *為快取中的所有物件增加一個“引用標誌位”

    *每次物件被使用時,設定標誌位為1

    *新物件加入快取時,設定其標誌位為0

    *在淘汰物件時,檢視它的標誌位。如果為0,則淘汰該物件;如果為1,則設定其標誌位為0,重新加入佇列末尾。         

五、LRU(Least recently Used)

  1、演算法思想

  LRU演算法的核心思想是基於“如果資料最近被訪問過,它在未來也極有可能訪問過”。因此如果資料的變化趨勢符合這個思想,效果會比較好。

  2、工作原理

    (1)資料結構:連結串列,用於儲存需要快取的資料;HashMap,用來讀取快取中的資料,保證時間複雜讀為O(1)

    (2)實現:

    當資料讀取時,有兩種情況:

   a、資料在快取中,則把該資料從新移到連結串列頭部

   b、資料不在快取中,則把資料插入到連結串列中。

    如何插入:

   a、如果連結串列不滿,則把資料插入連結串列頭部

   b、如果連結串列滿了,則把尾部的資料刪除,同時把其插入連結串列頭部

六、Clock

  1、演算法思想

    儘管上文介紹的Second-chance演算法是一個合理的演算法,但是它並不是很高效,因為它頻繁需要把物件插入到佇列尾部,要知道位移也是很耗時的。而更高效的演算法Clock,採用的是一個迴圈連結串列,有一個指標指向最早的物件,且每個快取中的物件都維護一個標記位。

  2、工作原理

  * 當待快取物件在快取中時,無論該物件標記位為0還是1,都設定為1(被使用)。同時,指標指向該物件的下一個物件。

  *若不在快取中時,檢查指標指向物件的標記位。如果是0,則用待快取物件替換該物件;如果是1,則置為0,指標指向下一個物件。如此直到淘汰一個物件為止。

七、Gclock(Generalized clock page replacement algorithm)

  1、演算法思想

    該演算法是Clock的變種。相對於Clock標誌位採用的是二進位制0和1表示,Gclock的標誌位採用的是一個整數,意味著理論上可以一直增加到無窮大。

  2、工作原理

  * 當待快取物件在快取中時,把其標記位的值加1。同時,指標指向該物件的下一個物件。

  *若不在快取中時,檢查指標指向物件的標記位。如果是0,則用待快取物件替換該物件;否則,把標記位的值減1,指標指向下一個物件。如此直到淘汰一個物件為止。由於標記位的值允許大於1,所以指標可能迴圈多遍才淘汰一個物件。

 八、WSclock(Working set clock page replacement algorithm)

  1、演算法思想

    該演算法同樣是clock的變種,可能是實際運用最廣泛的演算法。它採用clock的原理,是ws演算法(不懂的朋友可以閱讀ws演算法)的增強版。演算法資料結構為迴圈連結串列,每個快取物件儲存了"最近使用的時間"rt和"是否引用"的R標誌位,使用一個週期計時器t。age表示為當前時間和rt的差值

  2、工作原理

  *當待快取物件存在快取中時,更新rt為當前時間。同時,指標指向該物件的下一個物件。

  *若不存在於快取中時,如果快取沒滿,則更新指標指向位置的rt為當前時間,R為1。同時,指標指向下一個物件。如果滿了,則需要淘汰一個物件。檢查指標指向的物件,

  (1)R為1,說明物件在working set中,則重置R為0,指標指向下一個物件。

  (2)R為0。如果age大於t,說明物件不在working set中,則替換該物件,並置R為1,rt為當前時間。如果age不大於t,則繼續尋找淘汰物件。如果回到指標開始的位置,還未尋找到淘汰物件,則淘汰遇到的第一個R為0的物件。

九、LRU-K演算法

  1、演算法思想

  LRU-K中的K代表最近使用的次數,因此LRU可以認為是LRU-1。LRU-K的主要目的是為了解決LRU演算法“快取汙染”的問題,其核心思想是將“最近使用過1次”的判斷標準擴充套件為“最近使用過K次”。

  2、工作原理

  相比LRU,LRU-K需要多維護一個佇列,用於記錄所有快取資料被訪問的歷史。只有當資料的訪問次數達到K次的時候,才將資料放入快取。當需要淘汰資料時,LRU-K會淘汰第K次訪問時間距當前時間最大的資料。詳細實現如下

   

  (1). 資料第一次被訪問,加入到訪問歷史列表;

  (2). 如果資料在訪問歷史列表裡後沒有達到K次訪問,則按照一定規則(FIFO,LRU)淘汰;

  (3). 當訪問歷史佇列中的資料訪問次數達到K次後,將資料索引從歷史佇列刪除,將資料移到快取佇列中,並快取此資料,快取佇列重新按照時間排序;

  (4). 快取資料佇列中被再次訪問後,重新排序;

  (5). 需要淘汰資料時,淘汰快取佇列中排在末尾的資料,即:淘汰“倒數第K次訪問離現在最久”的資料。

  LRU-K具有LRU的優點,同時能夠避免LRU的缺點,實際應用中LRU-2是綜合各種因素後最優的選擇,LRU-3或者更大的K值命中率會高,但適應性差,需要大量的資料訪問才能將歷史訪問記錄清除掉。

十、Two queues(2Q)

  1、演算法思想

  該演算法類似於LRU-2,不同點在於2Q將LRU-2演算法中的訪問歷史佇列(注意這不是快取資料的)改為一個FIFO快取佇列,即:2Q演算法有兩個快取佇列,一個是FIFO佇列,一個是LRU佇列。

  2、工作原理

  當資料第一次訪問時,2Q演算法將資料快取在FIFO佇列裡面,當資料第二次被訪問時,則將資料從FIFO佇列移到LRU佇列裡面,兩個佇列各自按照自己的方法淘汰資料。詳細實現如下:

   

  (1). 新訪問的資料插入到FIFO佇列;

  (2). 如果資料在FIFO佇列中一直沒有被再次訪問,則最終按照FIFO規則淘汰;

  (3). 如果資料在FIFO佇列中被再次訪問,則將資料移到LRU佇列頭部;

  (4). 如果資料在LRU佇列再次被訪問,則將資料移到LRU佇列頭部;

  (5). LRU佇列淘汰末尾的資料。