Redis 的删除策略和内存淘汰机制

Redis 可以通过一个叫做过期字典(可以看作是 hash 表)的东西来保存存储数据时设置的过期时间。过期字典的 key 指向 Redis 数据库中的某个 key(键),过期字典的值是一个 long long 类型的整数,这个整数保存了 key 所指向的数据库键的过期时间(毫秒精度的 UNIX 时间戳)。

过期的数据的删除策略

假设我们设置了一批 key,为这些 key 设置的过期时间是 1 分钟,那么 1 分钟后,Redis 是怎么对这批 key 进行删除的呢?

常用的过期数据的删除策略就两个:

  • 惰性删除 :这种方法只会在获取 key 的时候才对数据进行过期检查,如果该 key 已经过期了,那么就删除;如果过了 1 分钟的时间甚至更久,这个 key 都没有被获取过,那么就会一直保留着。这样删除策略对 CPU 最友好,但是可能会造成太多过期 key 没有被删除。
  • 定期删除 :这种方法是每隔一段时间抽取一批 key 执行过期检查并删除的操作。并且,Redis 底层会通过限制删除操作执行的时长和频率来减少删除操作对 CPU 时间的影响。

定期删除对内存更加友好,惰性删除对 CPU 更加友好。两者各有千秋,所以 Redis 采用的是两种策略结合的一种更优策略,即定期删除+惰性/懒汉式删除

但是,仅仅通过判断给 key 设置的过期时间来进行过期数据的删除还是有很大问题的。因为还是可能存在定期删除和惰性删除漏掉了很多过期 key 的情况。这样就导致大量过期 key 堆积在内存里,然后就 Out of memory 了。

为了弥补这种缺陷,于是 Redis 推出了内存淘汰机制。

Redis 内存淘汰机制

Redis 提供了 6 种数据淘汰策略:

1.volatile-lru(least recently used):从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据执行淘汰操作;

2.volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选即将要过期的数据执行淘汰操作;

3.volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据执行淘汰操作;

4.allkeys-lru(least recently used):当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的 key(这个是最常用的)

5.allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰

6.no-eviction:禁止驱逐数据,也就是说当内存不足以容纳新写入数据时,新写入操作会报错。

Redis 4.0 版本后又增加了两种:

7.volatile-lfu(least frequently used):从已设置过期时间的数据集(server.db[i].expires)中挑选最不经常使用的数据执行淘汰操作

8.allkeys-lfu(least frequently used):当内存不足以容纳新写入数据时,在键空间中,移除最不经常使用的 key

本文参考自:Redis知识点&面试题总结 | JavaGuide

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Redis是一个开源的键值对存储数据库。它使用内存作为主要的数据存储介质,因此在处理大量数据时,需要考虑内存的使用和管理问题。Redis通过实现一些内存淘汰机制来解决这个问题。本文将对Redis内存淘汰机制进行详细解析。 一、Redis内存淘汰机制概述 Redis内存淘汰机制用于在内存使用超过预设阈值时,删除一些不常用的键值对,以释放内存空间。Redis提供了多种内存淘汰机制,包括: 1. noeviction(默认):当内存不足以容纳新写入数据时,新写入操作会报错。 2. allkeys-lru:在所有的键中,最近最少使用的键会被优先移除。 3. volatile-lru:在设置了过期时间的键中,最近最少使用的键会被优先移除。 4. allkeys-random:从所有的键中随机移除键。 5. volatile-random:从设置了过期时间的键中随机移除键。 6. volatile-ttl:从设置了过期时间的键中,根据键值对的ttl(time-to-live)值,移除最近将要过期的键。 其中,noeviction是Redis的默认策略,表示当内存不足以容纳新写入数据时,新写入操作会报错。而其他五种策略则是在内存不足时,用于删除一些键值对以释放内存空间的策略。 二、allkeys-lru淘汰策略 allkeys-lru策略是基于最近最少使用(LRU)算法的内存淘汰机制。它会在所有的键中,选择最近最少使用的键进行淘汰。 这个算法的实现依赖于Redis记录键的访问时间。当一个键被访问时,Redis会记录下当前时间,并将该时间戳与键的访问时间进行比较。当内存不足以容纳新写入数据时,Redis会选择访问时间最早的键进行淘汰。 allkeys-lru策略的优点是可以保证数据的热度。它会优先保留经常访问的数据,而淘汰不常用的数据。这样可以避免一些冷数据占用过多的内存空间,从而提高Redis的性能。 三、volatile-lru淘汰策略 volatile-lru策略是基于LRU算法的内存淘汰机制,但它只会在设置了过期时间的键中选择最近最少使用的键进行淘汰。 volatile-lru策略的实现方式与allkeys-lru相同,只是在选择淘汰键的时候,只考虑设置了过期时间的键。 volatile-lru策略的优点是可以在保证数据热度的同时,避免长期不使用的过期键占用过多的内存空间。 四、allkeys-random淘汰策略 allkeys-random策略是一种随机淘汰算法,它会从所有的键中随机选择一个键进行淘汰。 这种算法的实现方式比较简单,只需要在选择淘汰键时,从所有的键中随机选择一个即可。它的优点是可以避免一些冷数据占用过多的内存空间,但缺点是无法保证数据的热度。 五、volatile-random淘汰策略 volatile-random策略是一种随机淘汰算法,它会从设置了过期时间的键中随机选择一个键进行淘汰。 这种算法的实现方式与allkeys-random相似,只是在选择淘汰键时,只考虑设置了过期时间的键。它的优点是可以避免长期不使用的过期键占用过多的内存空间,但缺点是无法保证数据的热度。 六、volatile-ttl淘汰策略 volatile-ttl策略是根据键值对的ttl值,选择将要过期的键进行淘汰。 这种算法的实现方式比较简单,只需要在选择淘汰键时,从设置了过期时间的键中选择将要过期的键即可。它的优点是可以在保证数据热度的同时,避免长期不使用的过期键占用过多的内存空间。 七、Redis内存淘汰机制配置 Redis内存淘汰机制可以通过配置文件进行设置。在Redis的配置文件redis.conf中,可以设置maxmemory和maxmemory-policy两个参数。 maxmemory参数用于设置Redis使用的最大内存大小。当Redis使用的内存超过这个值时,就会触发内存淘汰机制。 maxmemory-policy参数用于设置Redis内存淘汰机制策略。它可以设置为noeviction、allkeys-lru、volatile-lru、allkeys-random、volatile-random和volatile-ttl中的任何一个值。 例如,以下是Redis配置文件中的maxmemory和maxmemory-policy参数设置: ``` maxmemory 1gb maxmemory-policy allkeys-lru ``` 这表示Redis最大使用1GB的内存,当内存使用超过1GB时,会使用allkeys-lru策略进行内存淘汰。 八、总结 Redis内存淘汰机制通过实现一些内存淘汰算法,可以在内存使用超过预设阈值时,删除一些不常用的键值对,以释放内存空间。其中,Redis提供了多种内存淘汰机制,包括noeviction、allkeys-lru、volatile-lru、allkeys-random、volatile-random和volatile-ttl。不同的策略有不同的优点和缺点,应该根据实际需求进行选择。在配置Redis内存淘汰机制时,需要设置maxmemory和maxmemory-policy两个参数,以控制Redis的最大内存使用量和内存淘汰策略

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值