Redis内存淘策略及内存管理

Redis 的过期策略以及内存淘汰策略

比如你 redis 只能存 5G 数据,可是你写了 10G,那会删 5G 的数据。怎么删的?还有,你的数据已经设置了过期时间,但是时间到了,内存占用率还是比较高?答案: redis 采用的是定期删除 + 惰性删除两种策略

定期删除:用一个定时器来负责监视 key,过期则自动删除。虽然内存及时释放,但是十分消耗 CPU 资源。在大并发请求下,CPU 要将时间应用在处理请求,而不是删除 key,因此没有采用这一策略

过期策略

定期删除 + 惰性删除是如何工作的

redis 默认会每隔 100ms 检查是否有过期的 key,如有过期的 key 则删除。需要说明的是,redis 不是每隔 100ms 将所有的 key 检查一次,而是随机抽取进行检查(如果每隔 100ms 对全部的 key 进行检查,那 redis 岂不是卡死)

因此,如果只采用定期删除策略,会导致很多 key 过期了,而没有删除。于是,惰性删除派上用场。也就是说在你获取某个 key 的时候 redis 会检查一下,这个 key 如果设置了过期时间那么是否过期了?如果过期了此时就会删除(并不是 key 到了过期时间,就会被删除掉。而是在你获取查询这个 key 时,redis 再惰性的检查一下)

采用定期删除 + 惰性删除就没其他问题了么

不是的,如果定期删除没有删除 key。然后你也没即时去请求 key,也就是说惰性删除也没生效。这样,redis 的内存会越来越高。那么就应该采用内存淘汰机制

内存淘汰策略

Redis 提供了 6 种的淘汰策略,配置方法如下

 maxmemory-policy volatile-lru
  • noeviction默认使用的策略,当内存不足以容纳新写入数据时,新写入操作会报错。不推荐使用
  • allkeys-lru:当内存不足以容纳新写入数据时,移除最近最少使用的 key。也就是从所有 key 中使用 LRU 算法进行淘汰。推荐使用
  • allkeys-random:当内存不足以容纳新写入数据时,随机移除某个 key。应该也没人用吧,你不删最少使用 Key ,去随机删
  • volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的 key 中使用 LRU 算法进行淘汰这种情况一般是把 redis 既当缓存,又做持久化存储的时候才用。不推荐
  • volatile-random:当内存不足以容纳新写入数据时,在从设置了过期时间的 key 中随机淘汰。依然不推荐
  • volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的 key 中,根据 key 的过期时间进行淘汰,越早过期的越优先被淘汰

当使用 volatile-lru、volatile-random、volatile-ttl 这三种策略时,如果没有 key 可以被淘汰,则和 noeviction 一样返回错误

如果 Redis 内存满了怎么办

我们知道 Redis 是一个非常常用的内存型数据库,数据从内存中读取是它非常高效的原因之一,那么但是如果有一天,Redis 分配的内存满了怎么办?遇到这个问题不要慌,这种问题我们分为两角度回答就可以

  • 我们可以怎么做
  • Redis 会怎么做

我们可以怎么做

我们可以增加 Redis 的可用内存

增加 Redis 可用内存

这种方法很暴力,也很好用。我们直接通过增加 Redis 可用内存就可以了, 有两种方式

通过配置文件配置

通过在 Redis 安装目录下面的 redis.conf 配置文件中添加以下配置设置内存大小

扫描二维码关注公众号,回复: 13047453 查看本文章
// 设置 Redis最大占用内存大小为 1000M 
maxmemory 1000mb

通过命令修改

Redis 支持运行时通过命令动态修改内存大小


// 设置redis最大占用内存大小为 1000M  
127.0.0.1:6379> config set maxmemory 1000mb

这种方法的确立竿见影,Redis 内存总归受限于机器的内存,也不能无限制的增长。那么如果没有办法再增加 Redis 的可用内存怎么办呢?我们可以看看 Redis 的内存淘汰策略

Redis 会怎么做

既然可以设置 Redis 最大占用内存大小,但 Redis 内存总归受限于机器的内存,也不能无限制的增长。那么如果没有办法再增加 Redis 的可用内存怎么办呢?实际上 Redis 定义了几种内存淘汰策略用来处理这种情况

Redis 的内存淘汰策略如上所述,Redis 提供了 6 种的淘汰策略

获取内存淘汰策略

127.0.0.1:6379> config get maxmemory-policy

通过配置文件设置内存淘汰策略

maxmemory-policy allkeys-lru

通过命令设置内存淘汰策略

127.0.0.1:6379> config set maxmemory-policy allkeys-lru

LRU 算法

什么是 LRU 算法

LRU 算法:即最近最少使用,是一种缓存置换算法。在使用内存作为缓存的时候,缓存的大小一般是固定的。当缓存被占满,这个时候继续往缓存里面添加数据,就需要淘汰一部分老的数据,释放内存空间用来存储新的数据。其核心思想是:如果一个数据在最近一段时间没有被用到,那么将来被使用到的可能性也很小,所以就可以被淘汰掉

LRU 算法在 Redis 中的实现

Redis 使用的是近似 LRU 算法,它跟常规的 LRU 算法还不太一样。近似 LRU 算法通过随机采样法淘汰数据,每次随机出 5(默认)个 key,从里面淘汰掉最近最少使用的 key

可以通过 maxmemory-samples 参数修改采样数量

maxmemory-samples 10

maxmenory-samples 配置的越大,淘汰的结果越接近于严格的 LRU 算法

Redis 为了实现近似 LRU 算法,给每个 key 增加了一个 24bit 的字段,用来存储该 key 最后一次被访问的时间

LFU 算法

LFU 算法与 Redis 4.0

LFU 算法是 Redis4.0 里面新加的一种淘汰策略。它的核心思想是根据 key 的最近被访问的频率进行淘汰,很少被访问的优先被淘汰,被访问的多的则被留下来

LFU 算法能更好的表示一个 key 被访问的热度。假如你使用的是 LRU 算法,一个 key 很久没有被访问到,只刚刚是偶尔被访问了一次,那么它就被认为是热点数据,不会被淘汰,而有些 key 将来是很有可能被访问到的则被淘汰了。如果使用 LFU 算法则不会出现这种情况,因为使用一次并不会使一个 key 成为热点数据

LFU 一共有两种策略

  • volatile-lfu:在设置了过期时间的 key 中使用 LFU 算法淘汰 key
  • allkeys-lfu:在所有的 key 中使用 LFU 算法淘汰数据

设置使用这两种淘汰策略跟前面讲的一样,不过要注意的一点是这两种策略只能在 Redis4.0 及以上设置,如果在 Redis4.0 以下设置会报错

猜你喜欢

转载自blog.csdn.net/weixin_38192427/article/details/115301173