当Redis被当做缓存来使用,当你新增数据时,让它自动地回收旧数据是件很方便的事情。这个行为在开发者社区非常有名,因为它是流行的memcached系统的默认行为。
LRU是Redis唯一支持的回收方法。本页面包括一些常规话题,Redis的maxmemory
指令用于将可用内存限制成一个固定大小,还包括了Redis使用的LRU算法,这个实际上只是近似的LRU。
Maxmemory配置指令
maxmemory
配置指令用于配置Redis存储数据时指定限制的内存大小。通过redis.conf可以设置该指令,或者之后使用CONFIG SET命令来进行运行时配置。
例如为了配置内存限制为100mb,以下的指令可以放在redis.conf
文件中。
maxmemory 100mb
设置maxmemory
为0代表没有内存限制。对于64位的系统这是个默认值,对于32位的系统默认内存限制为3GB。
当指定的内存限制大小达到时,需要选择不同的行为,也就是策略。 Redis可以仅仅对命令返回错误,这将使得内存被使用得更多,或者回收一些旧的数据来使得添加数据时可以避免内存限制。
回收策略
当maxmemory限制达到的时候Redis会使用的行为由 Redis的maxmemory-policy配置指令来进行配置。
以下的策略是可用的:
- noeviction:返回错误当内存限制达到并且客户端尝试执行会让更多内存被使用的命令(大部分的写入指令,但DEL和几个例外)
- allkeys-lru: 尝试回收最少使用的键(LRU),使得新添加的数据有空间存放。
- volatile-lru: 尝试回收最少使用的键(LRU),但仅限于在过期集合的键,使得新添加的数据有空间存放。
- allkeys-random: 回收随机的键使得新添加的数据有空间存放。
- volatile-random: 回收随机的键使得新添加的数据有空间存放,但仅限于在过期集合的键。
- volatile-ttl: 回收在过期集合的键,并且优先回收存活时间(TTL)较短的键,使得新添加的数据有空间存放。
如果没有键满足回收的前提条件的话,策略volatile-lru, volatile-random以及volatile-ttl就和noeviction 差不多了。
选择正确的回收策略是非常重要的,这取决于你的应用的访问模式,不过你可以在运行时进行相关的策略调整,并且监控缓存命中率和没命中的次数,通过RedisINFO命令输出以便调优。
一般的经验规则:
- 使用allkeys-lru策略:当你希望你的请求符合一个幂定律分布,也就是说,你希望部分的子集元素将比其它其它元素被访问的更多。如果你不确定选择什么,这是个很好的选择。.
- 使用allkeys-random:如果你是循环访问,所有的键被连续的扫描,或者你希望请求分布正常(所有元素被访问的概率都差不多)。
- 使用volatile-ttl:如果你想要通过创建缓存对象时设置TTL值,来决定哪些对象应该被过期。
allkeys-lru 和 volatile-random策略对于当你想要单一的实例实现缓存及持久化一些键时很有用。不过一般运行两个实例是解决这个问题的更好方法。
为了键设置过期时间也是需要消耗内存的,所以使用allkeys-lru这种策略更加高效,因为没有必要为键取设置过期时间当内存有压力时。
回收进程如何工作
理解回收进程如何工作是非常重要的:
- 一个客户端运行了新的命令,添加了新的数据。
- Redi检查内存使用情况,如果大于maxmemory的限制, 则根据设定好的策略进行回收。
- 一个新的命令被执行,等等。
- 所以我们不断地穿越内存限制的边界,通过不断达到边界然后不断地回收回到边界以下。
如果一个命令的结果导致大量内存被使用(例如很大的集合的交集保存到一个新的键),不用多久内存限制就会被这个内存使用量超越。
近似LRU算法
Redis的LRU算法并非完整的实现。这意味着Redis并没办法选择最佳候选来进行回收,也就是最久未被访问的键。相反它会尝试运行一个近似LRU的算法,通过对少量keys进行取样,然后回收其中一个最好的key(被访问时间较早的)。
不过从Redis 3.0算法已经改进为回收键的候选池子。这改善了算法的性能,使得更加近似真是的LRU算法的行为。
Redis LRU有个很重要的点,你通过调整每次回收时检查的采样数量,以实现调整算法的精度。这个参数可以通过以下的配置指令调整:
maxmemory-samples 5
Redis为什么不使用真实的LRU实现是因为这需要太多的内存。不过近似的LRU算法对于应用而言应该是等价的。使用真实的LRU算法与近似的算法可以通过下面的图像对比。
用于生成图像的Redis服务被填充了指定数量的键。这些键将被从头到尾访问,所以当使用LRU算法时第一个键是最佳的回收候选键。接着添加超过50%的键,用于强制旧键被回收。
你可以看到三种点在图片中, 形成了三种带.
- 浅灰色带是已经被回收的对象。
- 灰色带是没有被回收的对象。
- 绿色带是被添加的对象。
- 在LRU实现的理论中,我们希望的是,在旧键中的第一半将会过期。Redis的LRU算法则是概率的过期旧的键。
你可以看到,在都是五个采样的时候Redis 3.0比Redis 2.8要好,Redis2.8中在最后一次访问之间的大多数的对象依然保留着。使用10个采样大小的Redis 3.0的近似值已经非常接近理论的性能。
注意LRU只是个预测键将如何被访问的模型。另外,如果你的数据访问模式非常接近幂定律,大部分的访问将集中在一个键的集合中,LRU的近似算法将处理得很好。
在模拟实验的过程中,我们发现如果使用幂定律的访问模式,则真实的LRU算法和近似的Redis算法几乎没有差别。
当然你可以提升采样大小到10,消耗更多的CPU时间以实现更真实的LRU算法,同时查看下是否让你的缓存命中率有差别。
通过CONFIG SET maxmemory-samples 命令在生产环境上设置不同的采样大小是非常简单的。
相关推荐
这页包含更多一般的Redis maxmemory指令的话题用于限制内存使用到一个定额,同时它也深入的涵盖了Redis所使用的LRU算法,实际上是精确LRU的近似值。 一、Maxmemory设置指令 Maxmemory设置指令用于配置Redis的数据集...
redis有两种使用方式一是作为数据库使用,二是作为缓存使用。 将redis作为缓存,当你新增数据时,让它自动地回收旧数据是件很方便的事情。这个行为在开发者社区非常有名,因为它是流行的memcached系统的默认行为。而...
通过一个特殊的构造函数,三个参数的这种,最后一个布尔值参数表示是否要维护最近访问顺序,如果是 true 的话会维护最近访问的顺序,如果是 false 的话,只会维护插入...LinkedHashMap这种结构非常适合构造 LRU 缓存。
这页包含更多一般的Redis maxmemory指令的话题用于限制内存使用到一个定额,同时它也深入的涵盖了Redis所使用的LRU算法,实际上是精确LRU的近似值。 一、Maxmemory设置指令 Maxmemory设置指令用于配置Redis的数据集...
LRU 算法知道吗?写一下 java 代码实现? 6.缓存穿透、缓存击穿、缓存雪崩解决方案? 7.在选择缓存时,什么时候选择 redis,什么时候选择 memcached 8.缓存与数据库不一致怎么办 9.主从数据库不一致如何解决 10....
1)volatile-lru:使用LRU算法移除key,只对设置了过期时间的键(2)allkeys-lru:使用LRU算法移除key(3)volatile-ra
Redis作为缓存使用时,一些场景下要考虑内存的空间消耗问题。Redis会删除过期键以释放空间,过期键的删除策略有两种: 惰性删除:每次从键空间中获取键时,都检查取得的键是否过期,如果过期的话,就删除该键;如果...
在计算机的Cache硬件,以及主存到虚拟内存的页面置换,还有Redis缓存系统中都用到了该算法。我在一次面试和一个笔试时,也遇到过这个问题。 LRU的算法是比较简单的,当对key进行访问时(一般有查询,更新,增加,在...
无论是浏览器缓存(如果是chrome浏览器,可以通过chrome:://cache查看),还是服务端的缓存(通过memcached或者redis等内存数据库)。缓存不仅可以加速用户的访问,同时也可以降低服务器的负载和压力。那么,了解常见的...
1、LRU算法概述 redis默认情况下就是使用LRU策略的,因为内存是有限的,但是如果你不断地往redis里面写入数据,那肯定是没法存放下所有的数据在内存的 所以redis默认情况下,当内存中写入的数据很满之后,就会使
1. 列举一个常用的Redis客户端的并发模型 2. 如何实现一个Hashtable 3. 分布式缓存,一致性hash 4. LRU算法, slab分配,如何减
1. 列举一个常用的Redis客户端的并发模型 2. 如何实现一个Hashtable 3. 分布式缓存,一致性hash 4. LRU算法, slab分配,如何减
第 6 章使用 Redis 实现 Twitter(上). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 前提条件(Prerequisites) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ....
因缓存的使用相关需求,牺牲一部分服务器内存,因减少了网络数据交互,直接使用本机内存,可换取比redis,memcache等更快的缓存速度, 可做为更高一层的缓存需要 what? 用mcache能做什么? 可作为超高频率数据使用的缓存...
第 6 章使用 Redis 实现 Twitter(上). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 前提条件(Prerequisites) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ....
MongoDB更类似MySQL,支持字段索引、游标操作,其优势在于查询功能比较强大,擅长查询JSON数据,能存储海量数据,但是不支持事务。...Redis数据全部存在内存,定期写入磁盘,当内存不够时,可以选择指定的LRU算法删
特性:可存储数以百万计条目零垃圾收集负荷高并发而且线程安全的访问纯 Go 语言实现支持对象失效近乎 LRU 的算法严格限制内存使用提供一个测试用的服务器,支持一些基本 Redis 命令示例代码:cacheSize := 1024*...
王者荣耀java源码 标题 分类 内容 备注 架构 MySQL MQ 服务器 算法 ...缓存 使用redis改善数据库压力并更加实际情况定制 ...缓存 缓存 解决缓存一致性3种方案 缓存 ...LRU算法实际使用 设计模式 设计模式
什么是缓存?...请说说有哪些缓存算法?是否能手写一下 LRU 代码的实现? 常见的常见的缓存工具和框架有哪些 用了缓存之后,有哪些常见问题? 当查询缓存报错,怎么提高可用性? 如何避免缓存”雪崩”的问题?
特征存储数亿个条目零GC开销高并发线程安全访问纯Go实施过期支持近乎LRU算法严格限制内存使用附带一个玩具服务器,该玩具服务器通过管道支持一些基本的Redis命令迭代器支持表现这是基准测试结果与内置地图的比较结果...