删除策略

过期数据

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

  • XX:具有时效性的数据
  • -1:永久有效的数据
  • -2:已经过期的数据或被删除的数据或未定义的数据

时效性数据的存储结构

Redis删除策略

删除策略是对expires的维护。

删除数据的策略

定时删除

​ 创建一个定时器,当key设置有过期时间,且过期时间到达时,由定时器任务立即执行对键的删除操作。

当前时间和expires中对过期时间一致时,定时器触发删除。

优点:节省内存,到时间就删除,快速释放不必要的内存占用。

缺点:CPU压力较大,无论CPU此时负载情况如何,均占用CPU来执行删除,会影响Redis服务器的响应时间和指令吞吐量。

时间换空间

惰性删除

​ 数据到达过期时间,不做处理,等下次访问该数据等时候执行删除。

在获取数据时,内部会调用expirelfNeeded()方法,来确定数据是否到期。

  • 未到期,返回数据。
  • 到期,删除,返回不存在。

优点:节约cpu性能,到了必须删除的时候才执行删除。

缺点:内存压力较大,会出现长期占用内存的数据。

空间换时间

定期删除

​ Redis的存储空间中,每个db都有一个expires。整体的结构如下:

Redis删除策略

  1. Redis服务器启动初始化的时候,读区配置中的server.hz,默认为10。代表每秒执行10次serverCron()操作。
  2. 在serverCron()中会调用databasesCron()来轮询每一个db(即循环expire[*])。
  3. 在databasesCron()中会调用activeExpireCycle()方法,对每一个expire[*]进行检测,每次执行的时长伟250ms/server.hz。
  4. 对某个expire[*]检测时,随机挑选W个key进行检测。如果key超时,即删除。
  5. 如果第四步中,删除的key的数量大于W*25%,则继续在此expire[*]上检测执行。
  6. 如果第四步中删除的key的数量小于等于W*25%,则检测下一个expire[*]。(从0-15循环,Redis默认为16个DB)

​ 其中W值,可以在配置文件中配置,对应的属性为ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP;

​ 在第四步中的activeExpireCycle()方法执行检测的时候,因为时间长度时固定的,下一次activeExpireCycle()方法执行为了接着上一次中断的位置执行,用参数current_db来记录当前检测的expire。

特点:对cpu的使用有峰值,也有一定的自定义空间。删除过程中,内存的压力也不是很大。

Redis采用的策略:惰性删除+定期删除。

逐出策略

​ Redis使用内存存储数据,在执行每一天命令前,都会调用freeMemorylfNeeded()检测内存释放充足,如果内存不满足要加入数据的最低要求,redis会临时删除一些数据为当前指令清理存储空间。清理数据的策略称为逐出算法。

​ 逐出策略并不保证100%能清理出可使用的内存空间,如果不成功就反复执行。当对所有数据尝试完成后,如果不能达到内存清理的要求,将出现错误信息(OOM)。

相关配置

maxmemory:最大可使用内存。占用物理内存的比例,默认0代表不限制。

maxmemory-samples:每次选取的带删除数据的个数。每次选取数据并不是全库扫描,而是随机选取一部分。

maxmemory-policy:逐出策略。当内存100%使用之后,对挑选出来的数据删除的策略。

策略

易丢失数据(可能会过期的数据集,server.db[*].expire)

  • volatile-lru:挑选最近最少使用的数据淘汰
  • volatile-lfu:挑选最佳使用次数最少的数据淘汰
  • volatile-ttl:挑选将要过期的数据进行淘汰
  • volatile-random:随机选择数据淘汰

检测全库数据(所有数据集,server.db[*].dict)

  • alikeys-lru:挑选最近最少使用的数据淘汰
  • alikeys-lfu:挑选最佳使用次数最少的数据淘汰
  • alikeys-random:随机选择数据淘汰

放弃数据逐出

  • no-enviction:禁止数据逐出,会引发OOM(out of memory)

策略配置在配置文件中的maxmemory-policy属性。

相关文章: