redis(7)LRU缓存

一、LRU简介

LRU是Least Recently Used的缩写,即:最近最少使用。

它是内存管理中的一种页面置换算法,对于在内存中但是又不用的数据块,操作系统会根据哪些数据属于LRU而将其移除内存而腾出空间来加载另外的数据。

二、redis LRU

官方文章:https://redis.io/topics/lru-cache#using-redis-as-an-lru-cache

redis常常被用作缓存,当有新的数据进来的时候会自动驱逐旧的数据。LRU是memcached 默认的驱逐策略,在开发者当中也是常常被提及的。

1)最大内存配置

在redis LRU缓存使用中,你需要配置最大内存。最大内存的作用是限制redis的内存使用,当内存使用接近最大值的时候就会根据驱逐策略进行旧数据驱逐。

你可以通过redis.conf配置:

macmemory 100mb

当然新版的redis可以通过命令来配置你可以使用命令

config set maxmemory ‘100mb‘

来配置

2)驱逐策略

最大内存限制了内存的使用以及临界值,那么驱逐策略则定义旧数据的驱逐方式,可用的策略有以下几种:

1、noeviction: 当接近最大值的时候报错

2、allkeys-lru: 移除所有keys中最近最少使用的key

3、volatile-lru: 移除所有携带过期时间(expire set)的keys中最少使用的key

4、allkeys-random: 随机移除所有key

5、volatile-random: 随机移除所有携带过期时间(expire set)的key

6、volatile-ttl: 移除携带过期时间(expire set),且剩余过期时间更短的key

3) 执行流程

1、当客户端发送一个命令,需要新增数据

2、服务端会检查内存使用情况,如将要大于限制,它就会根据驱逐策略驱逐key以释放空间;

3、新命令被执行,以此类推。

4)近似LRU算法

事实上,Redis LRU 算法并不完全是LRU算法的实现,只能说是接近于LRU算法。尤其是在3.0版本以后已经非常接近LRU算法了。

Redis LRU 算法不会计算出所有keys当中最接近的(因为会比较耗内存),而是从所有key当中挑选出样本,然后再挑选样本的算法基础上驱逐最接近的。

你可以配置样本的数量:

maxmemory-samples 5

我们看官方网站提供的一张对比图,LRU算法和Redis LRU算法的对比:

说明:1、绿色区域是新增数据;2、灰色区域是未驱逐数据;3、浅灰色区域是驱逐数据。

左上角是LRU算法,右上角是样本为10的Redis3.0 LRU算法,左下角是样本为5的Redis 2.8 LRU算法,右下角是样本为5的Redis3.0 LRU。

很明显,相同样本的情况下,3.0版本较2.8版本有了很大程度的进步,更接近LRU算法。

在3.0版本中样本为10较样本为5的情况来说已经非常接近LRU算法。

三、Redis LFU

从redis4.0开始,提供了一种新的策略LFU (Least Frequently Used eviction mode),意识就是根据历史的最少访问频率来决定驱逐的数据。这种策略的中心思想是认为,如果该数据历史访问频率很高,那么在未来的访问频率也会很高。

LFU有两种选择:

1)volatile-lfu: 从携带过期时间的keys中选择历史访问最少的key

2) allkeys-lfu: 从所欲keys中选择历史访问最少的key

四、LFU算法介绍:

在redis中每个对象都有24bits空间来记录LRU/LFU信息:

当这24bits用作LFU时,其被分为两部分:

1、高16位用来记录访问时间(单位:分钟)

2、低8位用来记录访问频率,简称(counter)

我们来看counter:基于概率的对数计数器

我们通常计数器就是直接递增,但redis的计数器只有8bits最大值也就是2^8 - 1 = 255 ,如果采用直接递增的方式那么最多只能记录255频率。

因此,redis在这里采用了概率对数的方法,在默认概率椅子配置:lfu_log_factor = 10 的情况下,8bits可以表示100万的访问频率。

概率对数的算法让8bits可以记录很高的访问频率,但是如果计数器只做增长,就无法区分热点key。可能出现的情况就是即使长时间没有访问,它的访问频率依然很高。

针对这种情况,redis提供了一个衰减因子lfu_decay_time(单位:分钟),目的就是如果一个key长时间没有被访问那么计数器就要减少,减少的值由衰减因子来控制。

redis的默认值为1,意思是如果N分钟没有被访问,那么计数器就减 1 * N。

上面的概率因子和衰减因子,redis都有默认值,当然也可以进行配置:

lfu-log-factor 10
lfu-decay-time 1

Redis LFU算法可以参考文章:https://yq.aliyun.com/articles/278922

原文地址:https://www.cnblogs.com/lay2017/p/9271440.html

时间: 2024-08-30 02:02:10

redis(7)LRU缓存的相关文章

redis文档翻译_LRU缓存

Using Redis as an LRU cache使用Redis作为LRU缓存 出处:http://blog.csdn.net/column/details/redisbanli.html When Redis is used as a cache, sometimes it is handy to let it automatically evict old data as you add new one. This behavior is very well known in the c

redis lru缓存清理算法详解和相关配置

首先,需要先配置redis的conf文件,涉及到lru相关的配置一共有三个分别是: maxmemory,设置redis用来存放数据的最大的内存大小,一旦超出这个内存大小之后,就会立即使用LRU算法清理掉部分数据 maxmemory-policy,可以设置内存达到最大闲置后,采取什么策略来处理 (1)noeviction: 如果内存使用达到了maxmemory,client还要继续写入数据,那么就直接报错给客户端 (2)allkeys-lru: 就是我们常说的LRU算法,移除掉最近最少使用的那些k

Redis的LRU算法

Redis的LRU算法 LRU算法背后的的思想在计算机科学中无处不在,它与程序的"局部性原理"很相似.在生产环境中,虽然有Redis内存使用告警,但是了解一下Redis的缓存使用策略还是很有好处的.下面是生产环境下Redis使用策略:最大可用内存限制为4GB,采用 allkeys-lru 删除策略.所谓删除策略:当redis使用已经达到了最大内存,比如4GB时,如果这时候再往redis里面添加新的Key,那么Redis将选择一个Key删除.那如何选择合适的Key删除呢? CONFIG

mybatis整合Redis实现二级缓存

Mybatis整合ehcache实现二级缓存 导入相关依赖 <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>${spring.version}</version> </dependency> <!--mybatis与ehcache整合--

动手写一个LRU缓存

前言 LRU 是 Least Recently Used 的简写,字面意思则是最近最少使用. 通常用于缓存的淘汰策略实现,由于缓存的内存非常宝贵,所以需要根据某种规则来剔除数据保证内存不被占满. 在redis的数据淘汰策略中就包含LRU淘汰算法 如何实现一个完整的LRU缓存呢?这个缓存要满足: 这个缓存要记录使用的顺序 随着缓存的使用变化,要能更新缓存的顺序 基于这种特点,可以使用一个常用的数据结构:链表 每次加入新的缓存时都添加到链表的头节点 当缓存再次被使用时移动缓存到头节点 当添加的缓存超

redis实现二级缓存

缓存的作用就是降低数据库的使用率,来减轻数据库的负担.我们平常的操作一般都是查>改,所以数据库的有些查操作是重复的,如果一直使用数据库就会有负担.Mybatis也会做缓存,也会有一级缓存和二级缓存: 一级缓存:是SqlSession级别的缓存,使用HashMap数据结构来用于存储缓存数据的 二级缓存:是mapper级别的缓存,其作用域是mapper的同一个namespace,不同的SqlSession执行两次相同namespace下的sql语句,并且传递的参数相同,返回的结果也相同时,第一次执行

Spring整合Redis做数据缓存(Windows环境)

当我们一个项目的数据量很大的时候,就需要做一些缓存机制来减轻数据库的压力,提升应用程序的性能,对于java项目来说,最常用的缓存组件有Redis.Ehcache和Memcached. Ehcache是用java开发的缓存组件,和java结合良好,直接在jvm虚拟机中运行,不需要额外安装什么东西,效率也很高:但是由于和java结合的太紧密了,导致缓存共享麻烦,分布式集群应用不方便,所以比较适合单个部署的应用. Redis需要额外单独安装,是通过socket访问到缓存服务,效率比Ehcache低,但

redis的LRU算法(一)

最近加班比较累,完全不想写作了.. 刚看到一篇有趣的文章,是redis的作者antirez对redis的LRU算法的回顾.LRU算法是Least Recently Used的意思,将最近最少使用的资源丢掉.Redis经常被用作cache,如果能够将不常用的key移除,尽量保留常用的,那内存的利用率就相当高了.当然,LRU也有弱点,考虑下面一种情况: ~~~~~A~~~~~A~~~~~A~~~~A~~~~~A~~~~~A~~| ~~B~~B~~B~~B~~B~~B~~B~~B~~B~~B~~B~~

LRU缓存算法

引子: 我们平时总会有一个电话本记录所有朋友的电话,但是,如果有朋友经常联系,那些朋友的电话号码不用翻电话本我们也能记住,但是,如果长时间没有联系了,要再次联系那位朋友的时候,我们又不得不求助电话本,但是,通过电话本查找还是很费时间的.但是,我们大脑能够记住的东西是一定的,我们只能记住自己最熟悉的,而长时间不熟悉的自然就忘记了. 其实,计算机也用到了同样的一个概念,我们用缓存来存放以前读取的数据,而不是直接丢掉,这样,再次读取的时候,可以直接在缓存里面取,而不用再重新查找一遍,这样系统的反应能力