Redis是将数据放在内存中,内存是有限的而且有的业务场景需要将数据设置为过期,所以就有了过期删除策略和内存淘汰策略。
Redis过期删除策略
- 定时删除
- 惰性删除
- 定期删除
具体过程 | 对内存友好程度 | 对CPU友好程度 | 存在问题 | |
---|---|---|---|---|
定时删除 | 设置键过期的同时创建一个定时器,定时检查是否过期,如果过期进行删除 | 友好 | 不友好 | 对CPU压力大,影响用户操作 |
惰性删除 | 只有在每次进行键获取的时候进行是否过期的判断,如果过期进行删除 | 不友好 | 友好 | 如果某些键一直没被使用会一直占用内存 |
定期删除 | 定期、随机地对一定比例的键进行过期时间判断,如果过期则进行删除 | 居中 | 居中 | 因为是随机地对一定比例的键进行判断删除,所以对内存、CPU都还算友好。不过因为存在随机的可能,舍不得在极端情况下会存在一些键过期没扫描到而不会被删除的情况。针对这种情况,应对的策略是同时使用惰性删除+定期删除。 |
这里说的定时和定期的主要差别:定时会扫描全部的键,如果过期进行删除;而定期并不会扫描全部键,而只是对其中一部分进行删除。
通过这三种删除策略的对比,惰性删除+定期删除结合可以一定程度上避免内存的无效占用,但不可能完全避免。假设一下:如果某些键一直没被扫描到也没被使用,那它就会逃脱定期与惰性删除使得内存还是得不到释放,这样,我们就需要设置淘汰策略了。
当redis内存使用达到我们设置的maxmemory后,会根据淘汰策略清理内存,淘汰策略一有下面八种:
- noeviction 当内存不足以容纳写入数据时,新写入操作会报错。
- allkeys-lru 当内存不足以容纳写入数据时,移除最近最少使用的key。
- allkeys-random 当内存不足以容纳写入数据时,随机移除某个key。
- volatile-lru 当内存不足以容纳写入数据时,移除设置了过期时间里最近最少使用的key。
- volatile-random 当内存不足以容纳写入数据时,随机移除设置了过期时间的key。
- volatile-ttl 当内存不足以容纳写入数据时,优先移除更早过期时间的key。
- allkeys-lfu(Redis 4.0 以上),针对所有 Key,优先删除最少使用的 Key;
- volatile-lfu(Redis 4.0 以上),针对带有过期时间的 Key,优先删除最少使用的 Key。
有两点需要说明下:
- 一般不推荐使用random相关的淘汰策略,一些数据莫明其妙的不见给人造成困惑。不过也没有绝对,需要结合业务场景。
- 如果没设置过期时间,那volatile-lru/volatile-random/volatile-ttl的行为与noeviction差不多。