文章目录
过期数据
Redis是一种内存级数据库,所有数据均存放在内存中,内存中的数据可以通过TTL
指令获取其状态
- XX:具有时效性的数据
- -1:永久有效的数据
- -2:已经过期的数据或被删除的数据或未定义的数据
时效数据的存储结构
删除策略
redis中的过期数据,真的会立马删除掉吗,事实上是不会的,redis的过期数据并不会立马删除掉,会保留在内存中很长时间,这就会导致内存占用过高,过期数据什么删除呢,这就是需要用户来告诉redis了,为此redis提供了三种删除策略
删除策略的目标
在内存占用与CPU占用之间寻找一种平衡,顾此失彼都会造成整体redis性能的下降,甚至引发服务器宕机或内存泄漏
定时删除(策略)
创建一个定时器,当key设置有过期时间,且过期时间到达时,由定时器任务立即执行对键的删除操作
- 优点:节约内存,到时就删除,快速释放掉不必要的内存占用
- 缺点:CPU压力很大,无论CPU此时负载量多高,均占用CPU,会影响redis服务器响应时间和指令吞吐量
- 总结:用处理器性能换空间,用数据结构来说,就是拿时间换空间
惰性删除(策略)
过期数据不会立即删除,只有在下次访问的时候才会删除过期数据,这就是惰性删除,redis里面有个函数expireIfNeeded()
,与get操作绑定,这个函数是检查数据是否过期的
- 优点:节约CPU性能,发现必须删除的时候才删除
- 缺点:内存压力很大,出现长期占用内存的数据
- 总结:用存储空间换取处理器性能,用数据结构来说,就是拿空间换时间
定期删除(策略)
定时删除和惰性删除策略都在某一方面太极端了,那有没有平衡一点的策略呢,答案是有:定期删除策略。redis默认是每隔100ms就随机抽取一些设置了过期时间的key,检查其是否过期,如果过期就删除。注意这里是随机抽取的。为什么要随机呢?假如redis存了几十万个key,每隔100ms就遍历所有的设置过期时间的key的话,就会给CPU带来很大的负载。
定期删除的策略,在一定时间里,对每一个数据库进行轮询,在每次一次对某个数据库访问时,随机抽取一些key检查,如果有过期的就删除
周期性轮询redis库中的时效性数据,采用随机抽取的策略,利用过期数据占比的方式控制删除频度
特点1:CPU性能占用设置有峰值,检测频度可自定义设置
特点2:内存压力不是很大,长期占用内存的冷数据会被持续清理
总结:周期性抽查存储空间(随机抽查,重点抽查)
定期删除的步骤
- Redis启动服务器初始化时,读取配置server.hz的值,默认为10,可以通过
info
命令查看
- 每秒钟执行server.hz次
serverCron()
–>databasesCron()
–>activeExpireCycle()
,serverCron()
函数发起定期删除,databasesCron()
对redis内每个数据库进行轮询,activeExpireCycle()
对每个数据库【redis可以配置多个数据库】逐一进行检测,每次执行250ms/server.hz
。对某个数据库检测时,随机挑选W
个key检测:如果key超时,删除key;如果一轮中删除的key的数量<=W*25%
,检查下一个数据库,如果一轮中删除的key的数量>W*25%
,循环该过程,【W
取值=ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP
属性值,可以通过配置文件设置】【参数curret_db
用于记录activeExpireCycle()
进入哪个数据库执行,如果activeExpireCycle()
执行时间到期,下次从current_db
继续向下执行】
三种删除策略的对比
策略 | 对内存的影响 | 对CPU的影响 | 总结 |
---|---|---|---|
定时删除 | 节约内存,无占用 | 不分时段占用CPU资源,频率高,增加了CPU的负载 | 拿时间换空间 |
惰性删除 | 内存占用验证 | 延时执行,对CPU的压力极低 | 拿空间换时间 |
定期删除 | 内存定期随机清理 | 每秒花费固定的CPU资源维护内存 | 随机抽查,重点抽查 |
逐出算法
新数据进入检测:当新数据进入redis时,如果内存不足怎么办?如果redis里面都是永久数据,那么删除策略就不管用了
- Redis使用内存存储数据,在执行每一个命令前,会调用freeMemoryIfNeeded()检测内存是否充足。如果内存不满足新加入数据的最低存储要求,redis要临时删除一些数据为当前指令清理存储空间。清理数据的策略称为逐出算法。
- 注意:逐出数据的过程不是100%能够清理出足够的可使用的内存空间,如果不成功则反复执行。当对所有数据尝试完毕后,如果不能达到内存清理的要求,将出现错误信息。
逐出算法的相关配置
下面的配置都在redis.conf文件里面可以配置
1.最大可使用内存
占用物理内存的比例,默认值为0,表示不限制。通常设置在50%以上
maxmemory 0
2.每次选取待删除数据的个数
每次选取待删除数据的个数,默认5个, 选取数据时并不会全库扫描,导致严重的性能损耗,降低读写性能。因此采用随机获取数据的方式作为待检测删除数据
maxmemory-samples 5
3.内存不足时的删除策略
maxmemory-policy 达到最大内存后,对被选出来的数据进行删除的策略,redis提供了很多种方案,默认方案
noeviction
maxmemory-policy noeviction
方案名称 | 方案作用 |
---|---|
noeviction | 不逐出任何内容,会引发内存泄漏,导致内存不够用(redis-4.0.0中默认策略) |
volatile-lru | 从已设置过期时间的数据集中挑选最近最少使用的数据淘汰 |
allkeys-lru | 当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key(最常用) |
volatile-lfu | 从已设置过期时间的数据集中挑选最不经常使用的数据淘汰 |
allkeys-lfu | 当内存不足以容纳新写入数据时,在键空间中,移除最不经常使用的key |
volatile-random | 从已设置过期时间的数据集中任意选择数据淘汰 |
allkeys-random | 从数据集中任意选择数据淘汰 |
volatile-ttl | 从已设置过期时间的数据集中挑选将要过期的数据淘汰 |
4.数据逐出策略配置依据
使用INFO命令输出监控信息,查询缓存hit和miss的次数,根据业务需求调优Redis配置