一、什么是Redis

        Redis是一种内存级数据库,将所有的数据存放在内存当中,可以通过TTL指令来获取内存中的数据状态:

        xx:  具有时效性的数据;
        1:代表永久性数据;
        2:已经过期的数据或已经删除了的数据或未定义的数据;

Redis的删除策略:

        redis开辟了一个空间用来存放值的地址和其过期时间,删除策略是为了在内存和cpu之间找到一个平衡,一旦平衡被打破会降低redis的性能,引发服务器宕机和内存泄漏,一般来说,过期数据通常是在cpu闲暇之余被删除的。

        Redis中的过期数据删除情况:redis服务器当中有很多的操作需要被执行,执行会导致CPU的工作大大的增加,当内存的空间还足够时,已被删除的数据的内存空间并未直接释放,而是对客户端的指令先执行,

二、数据删除策略

        redis中的数据删除策略包括定时删除、惰性删除、定期删除:

1.定时删除(时间换空间)

        定时删除时给key都设置一个过期的时间,当达到删除时间节点时,立即执行对key的删除。

        优点:节约内存,到时间执行删除,释放内存空间;

        缺点:CPU资源占用率过高,当其他任务在执行时,会导致两者同时进行,会影响两者的效率,redis服务器的响应时间和指令吞吐量收到影响;

        总结:用处理器的性能换取存储空间(时间换空间),适用范围:小内存,强CPU。

2.惰性删除(空间换时间)

        惰性删除的含义是:当要删除的数据到达给定时间时,先不进行删除操作;等待下一次访问时,若数据已过期则进行删除,客户端返回不存在,数据未过期,则返回数据。

        优点:CPU的使用率大大降低,减轻其压力;

        缺点:内存空间占用率较高,会存在长期占用内存的数据

        总结:使用存储空间换取处理器性能(空间换时间),适用范围:大内存,弱CPU

3.定期删除(折中)

        定时删除是对CPU和内存消耗取得一个折中方案,通过每隔一段时间执行一次删除过期key的操作,并且通过限制删除操作执行的时长和频率来减少删除操作对CPU造成的影响,但是限制删除操作执行的时长和频率需要合理地设置,否则可能会退化为成定时删除或惰性删除。

       1. Redis启动服务器初始化时,读取配置server.hz的值,默认为10

        2.每秒钟执行server.hz次serverCron()

        3.activeExpireCycle()对每个expires[*]逐一进行检测,每次执行250ms/server.hz

        4.对某个expires[*]检测时,随机挑选W个key检测

        5.如果key超时,删除key;如果一轮中删除的key的数量>W*25%,循环该过程; 如果一轮中删除的key的数量≤W25%,检查下一个expires[],0-15循环W取值=ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP属性值

        6.参数current_db用于记录activeExpireCycle() 进入哪个expires[*] 执行

        7.如果activeExpireCycle()执行时间到期,下次从current_db继续向下执行

  • 周期性轮询redis库中的时效性数据,采用随机抽取的策略,利用过期数据占比的方式控制删除频度

  • 优点:1.CPU性能占用设置有峰值,检测频度可自定义设置;

  • 优点:2.内存压力不是很大,长期占用内存的冷数据会被持续清理;

  • 总结:周期性抽查存储空间 (随机抽查,重点抽查)

三、三种删除策略比较

内存占用CPU占用特征
定时删除节约内存,无占用不分时段占用CPU资源,频度高时间换空间
惰性删除内存占用严重延时执行,CPU利用率高空间换时间
定期删除内存定期随机清理每秒花费固定的CPU资源维护内存随机抽查,重点抽查

        在redis中会使用惰性删除和定期删除两种方式。

四、内存淘汰策略

        Redis提供8种数据淘汰策略:

1. volatile-lru:从已设置过期时间的数据集中挑选最近最少使⽤的数据淘汰。
2. volatile-random:从已设置过期时间的数据集中任意选择数据淘汰。
3. allkeys-lru:当内存不⾜以容纳新写⼊数据时,在键空间中,移除最近最少使⽤的 key(常用)
4. allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰。
5. volatile-ttl:从已设置过期时间的数据集中挑选将要过期的数据淘汰。
6. no-eviction:禁⽌驱逐数据,也就是说当内存不⾜以容纳新写⼊数据时,新写⼊操作会报错OOM。
4.0 版本后增加以下两种:
7. volatile-lfu:从已设置过期时间的数据集中挑选最不经常使⽤的数据淘汰。
8. allkeys-lfu:当内存不⾜以容纳新写⼊数据时,在键空间中,移除最不经常使⽤的 key。

五、逐出算法

        逐出算法:Redis使用内存存储之前,通常会调用freeMemoryIfNeeded()检测内存是否充足。如果内存不满足新加入数据的最低存储要求,redis要临时删除一些数据为当前指令清理存储空间。清理数据的策略称为逐出算法。

        然而,逐出过程不是100%清理足够的空间,需反复尝试,当处理完所有数据后依然不够,将出现如下错误信息:

在这里插入图片描述

影响数据逐出的相关配置

        maxmemory:redis可使用内存占物理内存的最大比例,默认为0,表示不限制redis使用内存。生产环境中根据需求设定,通常设置在50%以上;

        maxmemory-samples:每次选取待删除数据的个数,选取数据时并不会全库扫描,导致严重的性能消耗,降低读写性能。因此采用随机获取数据的方式作为待检测删除数据;

        maxmemory-policy:达到最大内存后的,对被挑选出来的数据进行删除的算法;

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐