了解LRU緩存的實現方法,這就夠了

2020-12-03 沙茶敏碎碎念

在之前的文章,我們介紹過常用緩存淘汰算法(文末有連結)。常見的緩存淘汰算法有先進先出淘汰算法(FIFO),最近最少使用淘汰算法(LSU),最近最久未使用算法(LRU),MRU(最近最常使用算法)。今天我們來討論其中的一種,也是最常用的LRU算法,看看它是如何實現的。

我們使用例子是谷歌開源的kv存儲LevelDB的經典LRUCache實現。LRUCache一般採用雙鏈進行實現,第一個是一個開散列,第二個是雙向鍊表,我們先簡單介紹下這兩個數據結構。首先是開散列。

開散列(Open Hashing),如果你是個Java開發,那對此肯定不陌生,也就是HashMap。我們先算出一個Key的Hash值,然後在存到對應的列裡面。如果同一個開散列有兩個key的Hash值一樣,我們稱之為衝突。怎麼解決衝突呢?一般我們使用鍊表解決,相同hash值的key在同一列。這裡,我們不難想到一個經典的java面試題,為什麼java的類的hash函數要設計成儘可能不同的類返回不同的值。如果元素的個數大於散列的列數,我們對散列進行擴大一杯,重新哈希,我們稱之為Rehash。好了,這裡我們不難想到另外一個經典的面試題目,為什麼Java開發中,如果已知key的數量,要在在聲明HashMap的時候就把大小傳進去,相信聰明的你現在已經有了答案。

第二個數據結構是雙向鍊表,在我們還在學習數據結構的年代,我們學習了鍊表,雙向鍊表只是鍊表的一個進化版,擁有兩個指針,一個指向前一個節點,一個指向後一個節點。這種數據結果有什麼特點呢?就是在刪除的P的時候,我們只要把P的前置結點的後置結點置為P的後置結點,把P的後置結點置的前置結點置為P的前置結點,就能夠把一個元素刪除。

兩種數據結構的複雜度如下:

雙向列表,查詢比較慢,但是插入很快,而且非常 容易維護先後使用順序。開散列,查詢很快,插入很快,但是很難維護先後順序,需要給每個元素加上時間戳再去遍歷。我們發現當兩種數據結構巧妙結合起來,用雙向鍊表維護最近未使用,用開散列來查詢,並且在開散列的值上面記錄元素在雙向鍊表中的位置,就能能夠大大的降低複雜度。

每次插入的流程如下:

1.當我們插入一個元素的時候,我們首先去開散列中找到這個元素

2.如果這個元素已經存在,則開散列中的值找到元素所在的雙向鍊表的位置,把它提到最新使用。

3.如果這個元素不存在,那麼開散列中插入這個元素,並且判斷是否要重新擴展。雙向鍊表中插入這個元素,並且判斷是否要淘汰掉最舊元素,如果要,那麼同時在開散列中刪除該元素。

好了,今天的內容我們就講到這裡,如果覺得我講的還不錯,歡迎關注我。

相關焦點

  • 怎麼實現的延時隊列?以及訂閱模式、LRU
    所以這次準備繼續總結,因為第一個問題,Redis的批量操作,是我在面試過程中被真實問到的,當時沒答上來,也是因為確實沒了解過Redis的批量操作。當時的問題,我還記得比較清晰:Redis執行批量操作的功能是什麼?使用場景就是搞促銷活動時,會做預緩存,會往緩存裡放大批數據,如果直接放的話那麼會很慢,怎麼能提高效率呢?
  • 如何使用鍊表實現 LRU 算法
    什麼是 LRU 算法LRU 是一種緩存淘汰策略。計算機的緩存容量有限,如果緩存滿了就要刪除一些內容,給新的內容騰位置。但是要刪除哪些內容呢?我們肯定希望刪掉那些沒有用的緩存,而把有用的數據繼續留在緩存中,方便之後繼續使用。
  • 手機中的緩存是什麼意思?
    緩存是為了提升硬體數據讀取性能而產生的一種技術,當設備需要讀取數據的時候,通常會先查看緩存區域是否存在,若存在則直接調用,若不存在則從內存中進行查找。從某種意義上來說,緩存區域越大,意味著您硬體設備的執行效率也就越高。並不僅僅是存儲設備會建立緩存機制,就連處理器也是如此,我們挑選桌面級處理器的時候,一級、二級緩存的容量也是比較重要的參數。
  • 這些方法,能夠讓你的Python程序快如閃電
    使用內置的數據類型這一點非常明顯。內置的數據類型非常快,尤其相比於樹或鍊表等自定義類型而言。這主要是因為內置數據類型使用 C 語言實現,使用 Python 實現的代碼在運行速度上和它們沒法比。使用 lru_cache 實現緩存/記憶我在之前的博客中介紹過這一技巧,但我認為它值得用一個簡單例子再次進行說明:importfunctoolsimporttime#cachingupto12differentresults@functools.lru_cache(maxsize=12)defslow_func(x):time.sleep(2)#Simulatelongcomputationreturnxslow_func
  • 如何在uni-app項目中使用數據緩存方法
    那麼,數據緩存有哪些方法呢?如何設置緩存、獲取緩存、刪除緩存和清空緩存?點擊設置緩存按鈕,查看控制臺列印結果5、使用相同方法,添加一個獲取緩存按鈕、先點擊獲取緩存按鈕,然後點擊刪除緩存,查看控制臺列印結果,接著再次點擊獲取緩存按鈕先點擊獲取緩存按鈕,然後點擊刪除緩存
  • 地鐵五分鐘理解LRU算法
    lru算法演示1、最開始時,內存空間是空的,因此依次進入A、B、C是沒有問題的。2、當加入D時,就出現了問題,內存空間不夠了,因此根據LRU算法,內存空間中A待的時間最為久遠,選擇A,將其淘汰。
  • 湖南EPE珍珠棉緩存維護原材料
    湖南EPE珍珠棉緩存維護原材料按材料分:EPE(ExpandablePolyethylene),是聚氨酯發泡高壓聚乙烯,有些人稱作聚氨酯發泡棉,別稱珍珠棉。由高壓聚乙烯聚氨酯發泡而成,生產加工非常容易、重量較輕、吸水能力低、防水性優良、抗性佳、緩存性出,別名伊比龍,是是非非化學交聯網膜囊構造,是以密度低高壓聚乙烯(LDPE)為關鍵原材料擠壓成型轉化成的高泡沫塑料高壓聚乙烯產品。
  • 戴爾RAID控制器引入CacheCade緩存技術
    LSI CacheCade技術能將經常訪問的「熱點」數據緩存在固態驅動器(SSD)中,從而大幅提升採用硬碟驅動器的系統存儲的I/O性能。採用Dell PERC H700和H800的系統通過配置 CacheCade技術可實現性能的顯著提升,同時不會損失現有的驅動器存儲空間,而且只需對SSD技術稍加投資即可。
  • 面試不再怕,程式設計師大佬教你20行Python代碼,搞懂LRU算法
    LRU算法在後端工程師面試中,是一個比較常出現的題目,這篇文章帶大家一起,理解LRU算法,並最終用Python輕鬆實現一個基於LRU算法的緩存。緩存是什麼先看一張圖,當我們訪問網頁,瀏覽器會給伺服器發請求,伺服器會經過一系列的運算,把頁面返回給瀏覽器。
  • 用這二招清除Windows10中的緩存,飛速提升電腦運行速度
    通常,這種類型的內存存儲稱為「內存緩存」。但是,在某些情況下,緩存可能會被阻塞並填滿所有系統內存。如果系統的內存較少(少於8GB),尤其如此。在這些情況下,系統將顯示「內存不足」的警告,性能會降低並且應用程式將無法正常運行。在最壞的情況下,系統可能因數據丟失而崩潰。
  • 雲計算核心技術Docker教程:docker構建緩存介紹
    在檢查每條指令時,Docker 會在其緩存中查找可重用的現有鏡像,而不是創建新的(重複的)鏡像。如果根本不想使用緩存,則可以使用命令--no-cache=true 上的選項docker build。但是,如果您確實讓Docker使 用其緩存,那麼了解何時可以找到匹配的鏡像,這一點很重要。Docker遵循的基本規則概述如下:1.從已在緩存中的父鏡像開始,將下一條指令與從該基本鏡像派生的所有子鏡像進行比較,以查看是否其中一個是使用完全相同的指令構建的。如果不是,則高速緩存無效。2.在大多數情況下,只需將中的指令Dockerfile與子鏡像之一進行比較就足夠了。
  • gtoken v1.1.0 發布,gf 的 token 插件,加入 Redis 緩存支持
    gtoken此版本主要加入了緩存redis支持,便於項目集群部署介紹基於gf框架的token插件,通過服務端驗證方式實現token認證; 支持單機gcache和集群gredis
  • 256MB緩存才夠用 士必得固態硬碟測評
    固態硬碟誕生之初開始,外置緩存晶片就成為了高端固態硬碟的標配。這是因為緩存晶片能夠協助主控進行更加快捷穩定的讀寫傳輸,協調和簡化主控晶片和快閃記憶體顆粒的工作交互。可以說緩存的存在讓固態硬碟的性能更加強悍,使用壽命也更加長久。
  • epe緩存泡綿原材料主要用途
    epe緩存泡綿原材料主要用途epe珍珠棉廣泛運用於汽車座墊、靠枕、電子電氣、儀表設備、電腦上、音箱、器材、標準機箱、五金照明燈飾、藝術品、夾層玻璃、瓷器、家用電器、家具家具、酒水及環氧樹脂等易破禮物包裝、五金製品、小玩具、瓜果蔬菜的內包裝、生活用品等不同產品的包裝,及其快遞公司包裝。添加彩防靜電劑和無滷阻燃劑後,更顯其的特性。