上面这段代码实现了一个简单的LUR算法,代码很简单,也加了注释,仔细看一下很容易就看懂 。LRU在Redis中的实现近似LRU算法Redis使用的是近似LRU算法,它跟常规的LRU算法还不太一样 。
近似LRU算法通过随机采样法淘汰数据,每次随机出5(默认)个key,从里面淘汰掉最近最少使用的key 。
可以通过maxmemory-samples参数修改采样数量:例:maxmemory-samples 10 maxmenory-samples配置的越大,淘汰的结果越接近于严格的LRU算法Redis为了实现近似LRU算法,给每个key增加了一个额外增加了一个24bit的字段,用来存储该key最后一次被访问的时间 。
Redis3.0对近似LRU的优化Redis3.0对近似LRU算法进行了一些优化 。新算法会维护一个候选池(大小为16),池中的数据根据访问时间进行排序,第一次随机选取的key都会放入池中
随后每次随机选取的key只有在访问时间小于池中最小的时间才会放入池中,直到候选池被放满 。
当放满后,如果有新的key需要放入,则将池中最后访问时间最大(最近被访问)的移除 。
当需要淘汰的时候,则直接从池中选取最近访问时间最小(最久没被访问)的key淘汰掉就行 。
LRU算法的对比我们可以通过一个实验对比各LRU算法的准确率,先往Redis里面添加一定数量的数据n,使Redis可用内存用完,再往Redis里面添加n/2的新数据,这个时候就需要淘汰掉一部分的数据
如果按照严格的LRU算法,应该淘汰掉的是最先加入的n/2的数据 。
生成如下各LRU算法的对比图:

文章插图
你可以看到图中有三种不同颜色的点:
- 浅灰色是被淘汰的数据
- 灰色是没有被淘汰掉的老数据
- 绿色是新加入的数据
LFU算法LFU算法是Redis4.0里面新加的一种淘汰策略 。它的全称是Least Frequently Used
它的核心思想是根据key的最近被访问的频率进行淘汰,很少被访问的优先被淘汰,被访问的多的则被留下来 。
LFU算法能更好的表示一个key被访问的热度 。假如你使用的是LRU算法,一个key很久没有被访问到,只刚刚是偶尔被访问了一次,那么它就被认为是热点数据,不会被淘汰,而有些key将来是很有可能被访问到的则被淘汰了 。
如果使用LFU算法则不会出现这种情况,因为使用一次并不会使一个key成为热点数据 。
LFU一共有两种策略:
- volatile-lfu:在设置了过期时间的key中使用LFU算法淘汰key
- allkeys-lfu:在所有的key中使用LFU算法淘汰数据
设置使用这两种淘汰策略跟前面讲的一样,不过要注意的一点是这两周策略只能在Redis4.0及以上设置,如果在Redis4.0以下设置会报错问题最后留一个小问题,可能有的人注意到了,我在文中并没有解释为什么Redis使用近似LRU算法而不使用准确的LRU算法 。
关于这个问题,大家可以打开脑洞思考一下,一起讨论学习 。
推荐阅读
- Redis为什么会这么快,看完这七点你就知道了
- Redis Sentinel基本实现原理
- 彻底搞懂Redis的线程模型
- Redis不只是缓存,还有n多种你没发现的妙用
- 8年程序员跳槽,60天面试腾讯百度等70家公司,总结出几个共同点
- 如何设计秒杀系统?
- 面试最后一问:你还有什么想了解的,正确的回答是这样
- 开会时被问“你有什么意见?”这样讲,就能让老板“高看一眼”
- 小米Redis的K8s容器化部署实践
- 浅析scrapy与scrapy_redis区别
