Redis-16-Redis作为内存的删除和淘汰策略


注:当redis做为缓存时,要求的是速度。可以牺牲一部门内存来保持他的性能。反正后边还有数据库做全量的数据存储。

1:设置Redis建的过期时间

Redis提供了四个命令来设置过期时间(生存时间)。

  ①、EXPIRE <key> <ttl> :表示将键 key 的生存时间设置为 ttl 秒。

  ②、PEXPIRE <key> <ttl> :表示将键 key 的生存时间设置为 ttl 毫秒。

  ③、EXPIREAT <key> <timestamp> :表示将键 key 的生存时间设置为 timestamp 所指定的秒数时间戳。

  ④、PEXPIREAT <key> <timestamp> :表示将键 key 的生存时间设置为 timestamp 所指定的毫秒数时间戳。

  PS:在Redis内部实现中,前面三个设置过期时间的命令最后都会转换成最后一个PEXPIREAT 命令来完成。
 注:
  一、移除键的过期时间

  PERSIST <key> :表示将key的过期时间移除。
  set <key> <value> :重新对key进行改写的时候,会剔除key的过期时间

  二、返回键的剩余生存时间

  TTL <key> :以秒的单位返回键 key 的剩余生存时间。

  PTTL <key> :以毫秒的单位返回键 key 的剩余生存时间。

2:redis的过期时间原理

在Redis内部,每当我们设置一个键的过期时间时,Redis就会将该键带上过期时间存放到一个过期字典中。当我们查询一个键时,Redis便首先检查该键是否存在过期字典中,如果存在,那就获取其过期时间。然后将过期时间和当前系统时间进行比对,比系统时间大,那就没有过期;反之判 定该键过期

3:过期删除策略

1:过期删除策略有哪些

①、定时删除
  在设置某个key 的过期时间同时,我们创建一个定时器,让定时器在该过期时间到来时,立即执行对其进行删除的操作。

优点:定时删除对内存是最友好的,能够保存内存的key一旦过期就能立即从内存中删除。

缺点:对CPU最不友好,在过期键比较多的时候,删除过期键会占用一部分 CPU 时间,对服务器的响应时间和吞吐量造成影响。

②、惰性删除
  设置该key 过期时间后,我们不去管它,当需要该key时,我们在检查其是否过期,如果过期,我们就删掉它,反之返回该key。

优点:对 CPU友好,我们只会在使用该键时才会进行过期检查,对于很多用不到的key不用浪费时间进行过期检查。

缺点:对内存不友好,如果一个键已经过期,但是一直没有使用,那么该键就会一直存在内存中,如果数据库中有很多这种使用不到的过期键,这些键便永远不会被删除,内存永远不会释放。从而造成内存泄漏。

③、定期删除
  每隔一段时间,我们就对一些key进行检查,删除里面过期的key。

优点:可以通过限制删除操作执行的时长和频率来减少删除操作对 CPU 的影响。另外定期删除,也能有效释放过期键占用的内存。

缺点:难以确定删除操作执行的时长和频率。

如果执行的太频繁,定期删除策略变得和定时删除策略一样,对CPU不友好。

如果执行的太少,那又和惰性删除一样了,过期键占用的内存不会及时得到释放。

另外最重要的是,在获取某个键时,如果某个键的过期时间已经到了,但是还没执行定期删除,那么就会返回这个键的值,这是业务不能忍受的错误。

2:redis的过期删除策略

前面讨论了删除过期键的三种策略,发现单一使用某一策略都不能满足实际需求,聪明的你可能想到了,既然单一策略不能满足,那就组合来使用吧。

没错,Redis的过期删除策略就是:惰性删除和定期删除两种策略配合使用。

惰性删除:Redis的惰性删除策略由 db.c/expireIfNeeded 函数实现,所有键读写命令执行之前都会调用 expireIfNeeded 函数对其进行检查,如果过期,则删除该键,然后执行键不存在的操作;未过期则不作操作,继续执行原有的命令。

定期删除:由redis.c/activeExpireCycle 函数实现,函数以一定的频率运行,每次运行时,都从一定数量的数据库中取出一定数量的随机键进行检查,并删除其中的过期键。

注意:并不是一次运行就检查所有的库,所有的键,而是随机检查一定数量的键。

定期删除函数的运行频率,在Redis2.6版本中,规定每秒运行10次,大概100ms运行一次。在Redis2.8版本后,可以通过修改配置文件redis.conf 的 hz 选项来调整这个次数。
  在这里插入图片描述
看上面对这个参数的解释,建议不要将这个值设置超过 100,否则会对CPU造成比较大的压力。

我们看到,通过过期删除策略,对于某些永远使用不到的键,并且多次定期删除也没选定到并删除,那么这些键同样会一直驻留在内存中,又或者在Redis中存入了大量的键,这些操作可能会导致Redis内存不够用,这时候就需要Redis的内存淘汰策略了。

4:redis的内存优化(淘汰)策略

①、设置Redis最大内存
  在配置文件redis.conf 中,可以通过参数 maxmemory 来设定最大内存:
  在这里插入图片描述
不设定该参数默认是无限制的,但是通常会设定其为物理内存的四分之三。(这里有个疑惑:为啥作者不考虑将此参数设定为百分比呢?)

②、设置内存淘汰方式
  当现有内存大于 maxmemory 时,便会触发redis主动淘汰内存方式,通过设置 maxmemory-policy ,有如下几种淘汰方式:

1)volatile-lru 利用LRU算法移除设置过过期时间的key (LRU:最近使用 Least Recently Used ) 。

2)allkeys-lru 利用LRU算法移除任何key (和上一个相比,删除的key包括设置过期时间和不设置过期时间的)。通常使用该方式。

3)volatile-random 移除设置过过期时间的随机key 。

4)allkeys-random 无差别的随机移除。

5)volatile-ttl 移除即将过期的key(minor TTL)

6)noeviction 不移除任何key,只是返回一个写错误 ,默认选项,一般不会选用。

在redis.conf 配置文件中,可以设置淘汰方式:
  在这里插入图片描述

5:总结

通过上面的介绍,相信大家对Redis的过期数据删除策略和内存淘汰策略有一定的了解了。这里总结一下:

Redis过期删除策略是采用惰性删除和定期删除这两种方式组合进行的,惰性删除能够保证过期的数据我们在获取时一定获取不到,而定期删除设置合适的频率,则可以保证无效的数据及时得到释放,而不会一直占用内存数据。

但是我们说Redis是部署在物理机上的,内存不可能无限扩充的,当内存达到我们设定的界限后,便自动触发Redis内存淘汰策略,而具体的策略方式要根据实际业务情况进行选取。

<think>好的,我现在需要详细思考如何回答用户关于Redis删除策略内存淘汰机制的问题。用户希望了解它们的工作原理及配置方法,还可能需要配置示例。根据提供的引用内容,我需要先理清这两个概念的区别联系。 首先,根据引用[1][2],Redis的过期策略包括惰性删除定期删除,而内存淘汰机制是在内存达到maxmemory时触发的策略。这两部分需要分开解释,但也要说明它们的关联。 接下来,我需要明确每个部分的具体内容。惰性删除是在访问键时检查过期时间,如果过期就删除。定期删除则是每隔一段时间随机抽取一些键检查并删除过期的。这部分需要详细说明两种策略的优缺点,比如惰性删除节省CPU但可能导致内存浪费,定期删除则是一种折中。 然后是内存淘汰机制,引用[3][4]提到当内存达到上限时,Redis会根据配置策略来淘汰数据。常见的策略有volatile-lru、allkeys-lru、volatile-ttl等。需要逐一解释这些策略的区别,比如针对带过期时间的键还是所有键,使用LRU还是TTL等。 配置方法方面,用户可能需要知道如何设置maxmemory选择淘汰策略。例如,在redis.conf中设置maxmemory参数,并通过maxmemory-policy指定策略配置示例部分可以举几个例子,比如设置最大内存为1GB,使用volatile-lru策略。 还要注意引用文献的正确标注,在回答中适当的位置添加引用标识,比如在提到惰性删除定期删除时引用[1][2],在内存淘汰策略部分引用[3][4]。 另外,用户可能需要实际操作的指导,比如如何查看当前配置,如何通过CONFIG SET命令动态调整策略。Java代码示例部分可以参考引用[4],展示使用Jedis库连接Redis配置策略的例子,但需要确保代码正确且符合用户需求。 最后,生成的相关问题需要与主题紧密相关,帮助用户进一步探索。例如,如何选择合适的内存淘汰策略,不同策略的优缺点比较,或者如何监控Redis内存使用情况。 总结回答结构:先分开讲解删除策略内存淘汰机制,再说明配置方法,最后给出示例注意事项。确保每个部分清晰,并且引用正确。</think>### Redis删除策略内存淘汰机制详解 #### 一、Redis删除策略(过期键处理) Redis通过**惰性删除****定期删除**两种策略管理过期键,确保内存资源高效利用。 1. **惰性删除** 当客户端访问某个键时,Redis会检查其过期时间。若已过期则直接删除,否则正常返回数据。 - **优点**:对CPU友好,仅在访问时触发检查。 - **缺点**:可能导致内存浪费(未访问的过期键长期驻留)[^1]。 2. **定期删除** Redis每隔一段时间(默认100ms)随机抽取部分键检查过期状态,删除其中已过期的键。 - **抽样数量**:由配置文件中的`hz`参数控制,默认10次/秒。 - **优点**:减少内存泄漏风险。 - **缺点**:需平衡CPU与内存效率[^2]。 #### 二、内存淘汰机制(Eviction Policy) 当内存使用达到`maxmemory`阈值时,Redis根据配置淘汰策略释放空间。以下是常见策略: | 策略 | 描述 | |---------------------|--------------------------------------------------------------------| | `volatile-lru` | 从**设置过期时间的键**中,淘汰最近最少使用的键(LRU算法)[^3]。 | | `allkeys-lru` | 从**所有键**中淘汰最近最少使用的键。 | | `volatile-ttl` | 从**设置过期时间的键**中,淘汰剩余存活时间最短的键(TTL优先)[^3]。 | | `volatile-random` | 随机淘汰**设置过期时间的键**。 | | `allkeys-random` | 随机淘汰**任意键**。 | | `noeviction`(默认) | 禁止写入新数据,仅返回错误(需手动干预释放内存)[^3]。 | #### 三、配置方法及示例 1. **设置最大内存淘汰策略** 修改`redis.conf`文件或通过命令行动态配置: ```bash # 设置最大内存为1GB config set maxmemory 1gb # 使用volatile-lru策略 config set maxmemory-policy volatile-lru ``` 2. **Java示例(Jedis库)** ```java Jedis jedis = new Jedis("localhost"); // 设置最大内存并选择策略 jedis.configSet("maxmemory", "1gb"); jedis.configSet("maxmemory-policy", "allkeys-lru"); ``` 此配置适用于缓存场景,优先保留高频访问数据[^4]。 3. **查看当前配置** ```bash redis-cli config get maxmemory redis-cli config get maxmemory-policy ``` #### 四、注意事项 - **策略选择**:若数据均有过期时间,优先用`volatile-*`策略;若需全量数据管理,选择`allkeys-*`。 - **监控指标**:通过`INFO memory`命令关注`used_memory``evicted_keys`,评估淘汰效率[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

苍煜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值