Redis 缓存逐出策略

  1. 把 Redis 当做缓存使用时,有时你可以方便的让它在新数据时自动逐出旧数据。这一点大家都比较清楚,因为 memcached 默认也会这么干

  2. Redis 仅支持 LRU 逐出策略。下文主要讲述 Redis maxmemory 指令,这个指令用于限定内存使用量,以及讲述了 Redis 使用到的 LRU 算法,这是一种近似LRU算法。

  3. maxmemory 配置指令

maxmemory 指令用于限定内存使用量。可以在 redis.conf 文件中设置,也可以通过 CONFIG SET 命令在运行时设置。

  1. 例如在 redis.conf 文件中添加如下指令将内存限定在 100M 以内

maxmemory 100mb

  1. 设置成 0 时表示无限制。64位系统下默认无限制,32位系统则强制指定为 3GB

  2. 当内存使用达到限定值时,可以选择几种不同的策略。例如 Redis 可以在调用指令时直接返回错误(这些指令会导致更多内存使用),或者是逐出老数据,给新数据纳出空间,让内存占用保持在限定一下。

  3. 逐出策略

具体的逐出策略通过 maxmemory-policy 指令进行配置,主要有如下策略:

noeviction:调用某些指令时返回错误(主要是绝大多数的写指令,DEL 和 部分其他指令不包括)

  1. allkeys-lru:对全键进行LRU

  2. volatile-lru:对指定了过期时间(expire set)的键进行LRU

  3. allkeys-random:对全键进行随机逐出

  4. volatile-random:对指定了过期时间的键随机逐出

  5. volatile-ttl:对指定了过期时间,并且 TTL 较短的键进行逐出

  6. volatile-* 系列指令在无键值满足条件时(例如未设置过期时间),表现为 noeviction

  7. 不同的应用选择不同的逐出策略,当然你可以根据命中率(INFO指令)在运行时动态调整策略。

  8. 可以参考以下的经验法则:

allkeys-lru,预期的请求符合长尾理论。或是啥都不懂时配成这个不会太差

  1. allkeys-random,会持续轮询所有的键。或者预期的请求符合均匀分布

  2. volatile-ttl,在生成缓存对象时指定不同的 ttl 值,所以你得控制好

  3. 你在单实例上同时存储缓存数据,以及一些持久化数据时,volatile-lru 和 volatile-random 会比较适合。但是通常建议缓存数据和持久化数据用不同的实例存储。

  4. 另外,对一个键设置过期时间会占用额外的内存,所以在内存压力较大时 allkeys-lru 的内存使用率会较好。

  5. 逐出过程是如何实现的

最好从以下几个方面来了解逐出过程

客户端运行了一个消耗内存的指令

  1. Redis 检查内存占用后发现超限,执行逐出策略

  2. 执行一个新的指令,如此循环

  3. 即反复的让 Redis 的内存占用在限定值上下波动,来观察和验证逐出策略

  4. 当一个指令消耗较多内存时,一定时间范围内可以观察到明显的内存超限

  5. 近似LRU算法

Redis 使用的 LRU 算法是一个近似实现,即逐出Key并不一定真正访问最少的键。它采用的方式是,对逐出范围内的键进行采样,然后对样本进行逐出。什么鬼。

  1. 在 Redis 3.0中有了一些改进,在提升性能的同时,让近似LRU的结果更加接近真实LRU。

  2. Redis LRU挺重要的一点是,你可以调整算法精度,即调整每次逐出时的取样数。可以通过这个指令进行调整:

maxmemory-samples 5

  1. Redis 使用 近似LRU 的目的主要还是为了节省内存,对于应用来说,近似与真实,实际上是等效的。

UI设计

  1. 在 Redis 中填充满指定数目的数据,顺序访问所有的键,在LRU下,第一个键是最佳逐出对象。然后增加50%的键值,逐出一半的老数据。

  2. 图中的三种点形成了三条不同的条纹

浅灰色表示已经逐出的

  1. 灰色表示未被逐出的

  2. 绿色表示新增的

  3. 理论LRU的结果完全符合预期,前一半的老数据逐出。Redis LRU 则是概率上的逐出老数据。

  4. 可以看到,取样数为5时,Redis 3.0 比 Redis 2.8 效果要好很多,2.8逐出了不少刚刚被访问过的数据。取样数为10时,Redis 3.0 的表现跟理论LRU就非常接近了。

  5. 如果请求符合长尾法则,那么真实LRU与Redis LRU之间表现基本无差异。

  6. 你可以在增加一定CPU消耗的情况下,提高取样数,然后检查命中率是否有变化

  7. 在生产环境,通过 CONFIG SET maxmemory-samples 指令可以方便的设置取样数。

关键字:redis, 逐出, lru, 指令

版权声明

本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处。如若内容有涉嫌抄袭侵权/违法违规/事实不符,请点击 举报 进行投诉反馈!

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部