LRU缓存算法与pylru

Posted 小苹果的苹果树

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LRU缓存算法与pylru相关的知识,希望对你有一定的参考价值。

这篇写的略为纠结,算法原理、库都是现成的,我就调用了几个函数而已,这有啥好写的?不过想了想,还是可以介绍一下LRU算法的原理及简单的用法。
 
LRULeast Recently Used,最近最少使用)是一种内存页面置换算法。什么叫内存页面置换?我们知道,相对于内存的速度来讲,磁盘的速度是很慢的。我们需要查询数据的时候,不能每次都跑到磁盘去查,需要在内存里设置一块空间,把一些常用的数据放在这块空间里,以后查的时候就直接在这里查,而不必去磁盘,从而起到“加速”的作用。但是这块空间肯定是远远小于磁盘大小的。那么什么样的数据放在这里才合适呢?当然是常用的数据。那什么样的数据是“常用”的数据呢?这里就有几种策略了。比如最简单FIFO(先进先出),RR(时间片轮转)等等,当然这就是我们最熟悉的队列和堆栈的做法。LRU也是这样一种策略,它的思想是基于这样一种观察和假定:最近经常访问的数据,在所有数据中也是最常访问的。所以,在这样一块空间中,最近被访问过的页面被当做“频繁访问”的,而一直没有被访问过的则被替换出去。这种思想是操作系统存储管理中最常见的方式之一,而目前也被广泛的应用为“缓存”的概念。缓存思想应用的也是相当广泛的,比如寄存器,比如内存,还有网络、数据库、IO等等方面,只要有输入/输出速度不匹配的地方,缓存就可以作为强有力的武器。
 
扯的有点远。接下来讲讲LRU算法的原理吧。假设我们开了可怜的一小块空间作为缓存,只能存5个数,页面编号为0,1,2,3,4。然后需要查询的一串序列为:4,7,0,7,1,0,1,2,1,2,6。那么将会出现如下图所示的情况:
整个查询过程为:
查询4,缓存中不存在,到磁盘中查,并把4放在缓存中;
查询7,类似上面的情况;
查询0,类似上面的情况;
查询7,直接在缓存中查到了,那么7作为“最近”查过的数据,放在最新的位置;
查询1,缓存中不存在,到磁盘中查,并把4放在缓存中;
查询0,直接在缓存中查到了,那么0作为“最近”查过的数据,放在最新的位置;
。。。。。。
后面依此类推。
 
现在大概清楚LRU是个怎样的算法,以及为什么可以作为缓存来使用了吧。这里有一篇文章分析的不错,可以参考一下:图解缓存淘汰算法一之LRU
现在我的项目中需要用到缓存了,可是忘了名字,只记得大概的原理,就去群里问道:我需要这样一个数据结构,查询效率高,类似字典和队列,但最近访问过的数据最后出队,很久没有访问过的数据就先被踢出去。群里大神指点我去看看LRUCache,恍然大悟,就是这个名字!于是百度了一下,结果找到了不少原理和java实现(比如 http://dennis-zane.iteye.com/blog/128278),就是没看到python的。于是到群里请教大神,大神一语中的:pylru。又去百度了一下,果然有这东西!
pylru可以使用pip安装,可以到pypi上查看下载及使用方法:https://pypi.python.org/pypi/pylru/1.0.9  使用起来又炒鸡简单,按某人的话来说就是:你们python真不要脸。
这个库是纯粹用python写的,有兴趣可以看看它的实现。库十分短小精悍,只有几百行代码,注释还占了一多半。
 
测试:
有点啰嗦了,不过这样结果也很清楚。
如果将来涉及到要写缓存了,能想起来这个东西,就是幸运。这也是我们为什么建议掌握一定的算法基础,以及操作系统、体系结构等基础课程的原因:并不是在实践中让你真的去写一个排序算法,写一个缓存,而是当你在某种场合下,能突然意识到:这特么不就是个XXX算法吗,我以前接触过的。比自己吭哧吭哧半天写出来个诡异的数据结构要好的多。
 
本文参考:
1、《现代操作系统》第四章:存储管理:4.4:页面置换算法
3、360图书馆:图解缓存淘汰算法一之LRU :http://www.360doc.com/content/14/0704/09/10504424_391894263.shtml
4、ITEye:LRUCache的java版本实现:http://dennis-zane.iteye.com/blog/128278
5、PyPI:pylru下载及使用:https://pypi.python.org/pypi/pylru/1.0.9

以上是关于LRU缓存算法与pylru的主要内容,如果未能解决你的问题,请参考以下文章

吃透Redis:缓存淘汰篇-LRU算法

吃透Redis:缓存淘汰篇-LRU算法

图解数据结构与算法LRU缓存淘汰算法面试时到底该怎么写

Java 实现 LRU 缓存算法

LRU 缓存淘汰算法

缓存淘汰算法-LRU 实现原理