Redis过期策略,如何找到redis中所有过期的key
提问:如何找到redis中所有过期的key?
这个问题,我也只想到了一种办法,如果有其他比较好的方案,热烈欢迎评论区一展风采哈~
先说说Redis的删除策略。
1、定时删除
在创建key的时候,为key创建一个定时器,让定时器在key过期时间来临时,对key进行删除。
优点:内存空会尽快被释放
缺点:若过期的key有很多,删除这些key会占用很多CPU的时间,导致CPU压力大,删除的时候不会考虑CPU是否空闲,性能影响较大
2、惰性删除
key过期后不立即删除,每次从数据库获取key的时候去检测是否过期。过期才会删除,并且返回null。
优点:删除操作只发生在查询key的时刻,而且只删除当前的key,所有对CPU是比较友好的。
缺点:若大量超时的key,在很久一段时间内没有被获取过,那么可能发生内存泄漏,因为大量无用的垃圾占用了内存空间。
3、定期删除
每隔一段时间执行一次删除(在redis.conf配置文件中设置hz,1s刷新的频率)过期key的操作。
redis默认是每隔100ms就随机抽取一些设置了过期时间的key,检查其是否过期,如果过期就删除。注意这里是随机抽取的。为什么要随机呢?假如redis存了几十万个key,每隔100ms就遍历所有的设置过期时间的key的话,就会给CPU带来很大的负载。
默认hz为10,看下注释描述。
优点:
1、通过限制操作的时长和频率,来减少删除操作对CPU时间的占用,这种方式可以优化定时删除策略的缺点。
2、定期删除过期的key,这种方式可以优化惰性删除的缺点
缺点:
在内存友好方面,不如定时删除策略
在CPU方面,不如惰性删除
难点:
如何合理设置删除操作的执行时长(每次删除执行多长时间)和执行频率(每隔多长时间做一次删除)
4、对比总结:
定时删除和定期删除为主动删除:Redis会定期主动淘汰一批已过去的key
惰性删除为被动删除:用到的时候才会去检验key是不是已过期,过期就删除
惰性删除为redis服务器内置策略
定期删除可以通过:
- 第一、配置redis.conf 的hz选项,默认为10 (即1秒执行10次,100ms一次,值越大说明刷新频率越快,最Redis性能损耗也越大)
- 第二、配置redis.conf的maxmemory最大值,当已用内存超过maxmemory限定时,就会触发主动清理策略
- memcached只是用了惰性删除,而Redis同时使用了惰性删除与定期删除,这也是二者的一个不同点(可以看做是redis优于memcached的一点)
- 对于惰性删除而言,并不是只有获取key的时候才会检查key是否过期,在某些设置key的方法上也会检查(eg.setnx key2 value2:该方法类似于memcached的add方法,如果设置的key2已经存在,那么该方法返回false,什么都不做;如果设置的key2不存在,那么该方法设置缓存key2-value2。假设调用此方法的时候,发现redis中已经存在了key2,但是该key2已经过期了,如果此时不执行删除操作的话,setnx方法将会直接返回false,也就是说此时并没有重新设置key2-value2成功,所以对于一定要在setnx执行之前,对key2进行过期检查)
5、Redis采用的过期策略
惰性删除+定期删除
- 惰性删除流程
- 在进行get或setnx等操作时,先检查key是否过期,
- 若过期,删除key,然后执行相应操作;
- 若没过期,直接执行相应操作
- 定期删除流程(简单而言,对指定个数个库的每一个库随机删除小于等于指定个数个过期key)
- 遍历每个数据库(就是redis.conf中配置的"database"数量,默认为16)
- 检查当前库中的指定个数个key(默认是每个库检查20个key,注意相当于该循环执行20次,循环体时下边的描述)
- 如果当前库中没有一个key设置了过期时间,直接执行下一个库的遍历
- 随机获取一个设置了过期时间的key,检查该key是否过期,如果过期,删除key
- 判断定期删除操作是否已经达到指定时长,若已经达到,直接退出定期删除。
- 检查当前库中的指定个数个key(默认是每个库检查20个key,注意相当于该循环执行20次,循环体时下边的描述)
- 遍历每个数据库(就是redis.conf中配置的"database"数量,默认为16)
6、RDB和AOF在持久化时,是如何对过期key进行处理的
6.1、RDB对过期key的处理
过期key对RDB没有任何影响
- 从内存数据库持久化数据到RDB文件
- 持久化key之前,会检查是否过期,过期的key不进入RDB文件
- 从RDB文件恢复数据到内存数据库
- 数据载入数据库之前,会对key先进行过期检查,如果过期,不导入数据库(主库情况)
6.2、AOF对过期key的处理
过期key对AOF没有任何影响
- 从内存数据库持久化数据到AOF文件:
- 当key过期后,还没有被删除,此时进行执行持久化操作(该key是不会进入aof文件的,因为没有发生修改命令)
- 当key过期后,在发生删除操作时,程序会向aof文件追加一条del命令(在将来的以aof文件恢复数据的时候该过期的键就会被删掉)
- AOF重写
- 重写时,会先判断key是否过期,已过期的key不会重写到aof文件
7、当新数据进入redis时,如果内存不足怎么办?
Redis使用内存存储数据,在执行每一个命令前,会调用freeMemoryIfNeeded()检测内存是否充足。如果内存不满足新加入数据的最低存储要求,redis要临时删除一些数据为当前指令清理存储空间。清理数据的策略称为逐出算法。
注意:逐出数据的过程不是100%能够清理出足够的可使用的内存空间,如果不成功则反复执行。当对所有数据尝试完毕后,如果不能达到内存清理的要求,将出现错误信息。
(err)OOM command not allowed when used memory > 'maxmemory'
最大可使用内存maxmemory:占用物理内存的比例,默认值为0,表示不限制。通常设置在50%以上
每次选取待删除数据的个数:maxmemory-samples 选取数据时并不会全库扫描,导致严重的性能损耗,降低读写性能。因此采用随机获取数据的方式作为待检测删除数据
删除策略:maxmemory-policy 达到最大内存后,对被选出来的数据进行删除的策略
以上针对redis的删除策略有些是直接拷贝别人的文字,在理解上是一致的,我也就没有再打一遍文字。
现在说说如何找到redis中所有过期的key?
监听Redis的过期队列:
代码实现:
pom.xml
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>
@Configuration
public class RedisListenerConfig {@BeanRedisMessageListenerContainer container(RedisConnectionFactory factory) {RedisMessageListenerContainer container = new RedisMessageListenerContainer();container.setConnectionFactory(factory);return container;}
}
@Component
public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {super(listenerContainer);}@Autowiredprivate StringRedisTemplate redisTemplate;@Overridepublic void onMessage(Message message, byte[] pattern) {// 用户做自己的业务处理即可,注意message.toString()可以获取失效的keyString expiredKey = message.toString();System.out.println("监听到过期的key:" + expiredKey);String resultKey = redisTemplate.opsForValue().get(expiredKey);System.out.println("返回:" + resultKey);}
}
就这简单的几行代码即可,开始测试,创建一个key并设置20s过期
完事儿~ 再次说明一下,这只是一种方式实现,不是绝对的。
简单去看了一下redis的listener底层的实现,其实原理上就是和MQ类似,维护一个过期的topic队列,来监听这个队列。
Redis过期策略,如何找到redis中所有过期的key相关推荐
- redis的过期策略
Redis 所有的数据结构都可以设置过期时间,时间一到,就会自动删除.你可以想象 Redis 内部有一个死神,时刻盯着所有设置了过期时间的 key,寿命一到就会立即收割. 你还可以进一步站在死神的角度 ...
- Redis过期策略及实现原理
2019独角兽企业重金招聘Python工程师标准>>> 我们在使用redis时,一般会设置一个过期时间,当然也有不设置过期时间的,也就是永久不过期. 当我们设置了过期时间,redis ...
- java redis 数据自过期_Java架构-Redis的内存回收策略和Key过期策略,看这篇就够了...
Redis 作为当下最热门的 Key-Value 存储系统,在大大小小的系统中都扮演着重要的角色,不管是 session 存储还是热点数据的缓存,亦或是其他场景,我们都会使用到 Redis.在生产环境 ...
- Redis运维和开发学习笔记(7) 内存管理和过期策略
Redis运维和开发学习笔记(7) 内存管理和过期策略 文章目录 Redis运维和开发学习笔记(7) 内存管理和过期策略 内存回收策略 惰性删除 定时任务删除 maxmemory 过期策略allkey ...
- Redis系列教程(九):Redis的内存回收原理,及内存过期淘汰策略详解
Redis内存回收机制 Redis的内存回收主要围绕以下两个方面: 1.Redis过期策略:删除过期时间的key值 2.Redis淘汰策略:内存使用到达maxmemory上限时触发内存淘汰数据 Red ...
- 【Redis扩展篇(一)】过期策略
Redis过期策略 0. 前言 Redis所有的数据结构都可以设置过期时间,时间一到就会被自动删除.但是会不会因为统一时间太多的key过期,导致Redis执行执行出现卡顿.因为Redis是单线程的,收 ...
- 谈谈 Redis 的过期策略
在日常开发中,我们使用 Redis 存储 key 时通常会设置一个过期时间,但是 Redis 是怎么删除过期的 key,而且 Redis 是单线程的,删除 key 会不会造成阻塞.要搞清楚这些,就要了 ...
- 13. 谈谈 Redis 的过期策略
谈谈 Redis 的过期策略 定期删除策略 从库的过期策略 懒惰删除策略 unlink flush 异步队列 更多异步删除点 内存淘汰机制 LRU 算法 近似 LRU 算法 LFU 在日常开发中,我们 ...
- 关于Redis数据过期策略
前言 在项目中某场景下,需要频繁去设置redis数据的过期时间,因此去了解了下redis数据过期策略.原文地址:关于Redis数据过期策略 一.Redis中key的的过期时间 通过EXPIRE key ...
- Redis过期策略与内存淘汰机制
参考博客:https://blog.csdn.net/u010006156/article/details/124914082 Redis过期策略与内存淘汰机制 过期策略简介 作用 redis数据都是 ...
最新文章
- 分析 JDK 源码丨Java Thread
- python threading condition使用_Python threading模块condition原理及运行流程详解
- excel调用python编程-使用python集合进行EXCEL数据分析
- 64位传参利用方法LibcSearcher使用入门ROPgadget利用
- 【若依(ruoyi)】swagger 接口 @SessionAttribute 修饰的参数
- 40%美国人付不起400美元意外开销,大家怎么看?
- 7-5 图形继承与多态 (50 分)
- SQL server数据缓存依赖
- vue echart甘特图
- 丑小鸭变白天鹅 数据中心进化三部曲
- okhttp3+retrofit2+rxjava2使用
- 操作系统的概念,功能,作用
- 带蓝色的紫罗兰色——三色配色篇
- pytorch 预测手写体数字_深度学习之PyTorch实战(3)——实战手写数字识别
- 帝国CMS列表模板使用php
- postgresql查询锁表以及解除锁表
- 项目笔记一-----------------iphone官网仿制
- 微型计算机拆的步骤视频,微型计算机拆卸.ppt
- 免费实用的看图工具 Xee
- 北理889考研经验帖