Redis之删除策略与逐出算法
Redis在内存中运行,数据也保存在内存中。由于内存有限而数据无限,一般给主键添加过期时间,防止数据将内存打满,就需要使用删除策略和逐出算法。
删除策略
过期数据:设置有效期的数据,到达有效期,Redis并没有立即删除。数据删除策略就是对过期数据进行处理,控制的是 expires位置。
删除策略包含三种,分别为定时删除、惰性删除和定期删除。在内存和性能之间做平衡。
定时删除
创建一个定时器,当key设置过期时间,且时间到达时,有定时器任务立即执行对键的删除操作。 优点:节约内存,到期删除,快速释放不必要的内存占用。 缺点:CPU压力大,无论CPU负载多大,均占用CPU进行删除操作,会影响Redis服务器响应时间和指令吞吐量。 总结:用处理器性能换取内存空间。
惰性删除
数据到达过期时间,不做处理,等下次访问该数据时删除。如果未过期,返回数据;发现已过期,删除,返回不存在。 优点:节约CPU性能,发现必须删除的时候才删除。 缺点:内存压力大,出现长期占用内存的数据。 总结:用内存空间换取处理器性能。
定期删除
Redis启动服务器初始化时,读取配置 server.hz 的值,默认为10。 对每个库的expires空间,expires[*](每个库都有该区间)进行一轮检测,每次执行 250ms/server.hz 时间,每秒执行 server.hz 次。
对每个 expires[*] 检测时,随机挑选W个key检测,W取值 = ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP 属性值。
如果key超时,删除key。 如果一轮中删除的key数量大于 W * 25%,循环该过程。 如果一轮中删除的key < W * 25%,检查下一个exipires[*],0-15循环。
参数current_db用于记录 该方法 进入哪个 exipires[*] 执行。 周期性轮询Redis库中的时效性数据,采取随机抽取的策略,利用过期数据占比的方式控制删除频度。 总结:周期性抽查存储空间。
删除策略对比
删除策略 | 内存占用 | CPU资源利用 | 中心思想 |
---|---|---|---|
定时删除 | 节约内存,无占用 | 不分时段占用CPU资源,频度高 | 性能换空间 |
惰性删除 | 内存占用严重 | 延时执行,CPUU利用率高 | 空间换性能 |
定期删除 | 内存定期随机清理 | 每秒花费弧顶的CPU资源维护内存 | 随机抽查,重点抽查 |
逐出算法
当数据进入Redis时,如果内存不满足加入数据的最低存储要求,Redis要临时删除一些数据为当前指令清理存储空间。清理数据的策略成为逐出算法。
逐出算法相关配置:
maxmemory 最大可用内存,默认0,无限制。 maxmemory-samples 每次选取待删除数据的个数。 maxmemory-policy 配置逐出算法。
达到最大内存后,对被挑选出的数据进行逐出的策略,其中给选取数据并不会全库扫描。
逐出算法:
检测易失数据(可能会过期的数据集 server.db[i].expires)
- volatile-lru 最近最少被使用的数据淘汰
- volatile-lfu 最近使用次数最少的数据淘汰
- volatile-ttl 要过期的数据淘汰
- volatile-random 任意选择数据淘汰
检测全库数据(所有数据集 server.db[i].dict)
- allkeys-lru
- allkeys-lfu
- allkeys-random
放弃数据驱逐
no-enviction:禁止驱逐数据,会引发 OOM
转载自:https://juejin.cn/post/7114272967135068191