LRU算法的實現,簡單粗暴的Redis與中規中矩的Memcached

b36g 9年前發布 | 37K 次閱讀 LRU NoSQL數據庫

原文  http://calvin1978.blogcn.com/articles/lru.html

Redis

今天看 Redis3.0的發行通告 里說,LRU算法大幅提升了,就翻開源碼來八卦一下,結果哭笑不得,這所謂"近似LRU"算法,實在太簡單,太粗暴,太偷懶,太Redis了。

Github的Redis項目 里搜索lru,代碼在redis.c的freeMemoryIfNeeded()函數里,如果內存超出了maxmemory的設置,就會用此方法釋放出足夠的內存來存放新增記錄。

先看 2.6版的代碼 : 竟然就是隨機找三條記錄出來,比較哪條空閑時間最長就刪哪條,然后再隨機三條出來,一直刪到內存足夠放下新記錄為止.......可憐我看 配置文檔 后的想象,一直以為它會幫我在整個Redis里找空閑時間最長的。

好,收拾心情再看 3.0版的改進 :現在每次隨機五條記錄出來,插入到一個長度為十六的按空閑時間排序的隊列里,然后把排頭的那條刪掉,然后再找五條出來,繼續嘗試插入隊 列.........嗯,也就好了一點點吧,起碼每次隨機多了兩條,起碼不只在一次隨機的五條里面找最久那條,會連同之前的一起做比較......

Memcached

相比之下,Memcached實現的是再標準不過的LRU算法,專門使用了一個教科書式的雙向鏈表來存儲slab內的LRU關系,代碼在 item.c 里,詳見 memcached源碼分析-----LRU隊列與item結構體 ,元素插入時把自己放到列頭,刪除時把自己的前后兩個元素對接起來,更新時先做刪除再做插入。分配內存不夠時,很自然就會從LRU的隊尾開始清理。

后來

不過后來再想想,也許Redis本來就不是主打做Cache的,這種內存爆了需要通過LRU刪掉一些元素不是它的主要功能,默認設置都是noeviction——內存不夠直接報錯的,所以就懶得建個雙向鏈表,而且每次訪問時都要更新它了。

再瞄了一眼 Ehcache的Eviction算法 ,看文檔居然和Redis2.6一樣,直接隨機15條記錄,找出最舊那條......你是專門做Cache的呀,也這么懶。

另外,還看了下Memcached如何主動刪除過期的數據,也就是那個文不對題的 LRU爬蟲 ,和Redis的有點像,也是可以控制多久跑一次(默認100毫秒),每次檢查LRU隊列中的N條數據,沿著列尾一直檢查過去,比Redis的隨機選擇N條數據好一點。

</div>

 本文由用戶 b36g 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!