Redis占用内存
Redis作为内存型数据库,在业务量过大的情况下,会出现内存不够的情况(达到[maxmemory]设置值),当然机器内存足够强大,数据可承受范围会更大,但是这不是解决问题的方法。
Redis提供了两种解决方法:
- 设置key的超时时间
- LRU算法
设置数据的超时时间(TTL)
关于设置数据的超时时间这个方法,是我们经常用到的,同时设置超时时间还可以在某些场景下满足我们的业务需要:
- 验证码的失效时间
- 用户token的失效时间
- ......
但是有没有想过TTL的过期策略是什么呢?
Redis的过期策略
redis的过期策略分为:定期删除 和 惰性删除
定期删除
Redis会将每个设置了过期时间的 key 放入到一个独立的字典中,以后会定期遍历这个字典来删除到期的 key。
Redis 默认会每秒进行十次过期扫描(100ms一次),过期扫描不会遍历过期字典中所有的 key,而是采用了一种简单的贪心策略:
- 从过期字典中随机20个key
- 删除这 20 个 key 中已经过期的 key
- 如果过期的 key 比率超过 1/4,那就重复步骤 1
这里随机抽取就是为了在数据量过大的情况下,遍历大量的key,给CPU增加负担
惰性删除
惰性删除就是在客户端访问这个key的时候,redis对key的过期时间进行检查,如果过期了就立即删除,不会给你返回任何东西。通常情况下我们在日常的使用过程中查询已经过期的key,是比较容易触发该机制的。
定期删除是从比较大的层面做key的过期删除,因为其随机性,导致会有过期key不能及时删除的情况发生,惰性删除是在某些情况下对定期删除的一种弥补策略。
LRU
什么是LRU算法?
- 新增key value的时候首先在链表结尾添加Node节点,如果超过LRU设置的阈值就淘汰队头的节点并删除掉HashMap中对应的节点。
- 修改key对应的值的时候先修改对应的Node中的值,然后把Node节点移动队尾。
- 访问key对应的值的时候把访问的Node节点移动到队尾即可。
Redis使用的是近似LRU算法:近似LRU算法通过随机采样法淘汰数据,每次随机出5(默认)个key,从里面淘汰掉最近最少使用的key,可以通过maxmemory-samples参数修改采样数量: 例:maxmemory-samples 10 maxmenory-samples配置的越大,淘汰的结果越接近于严格的LRU算法,但是同时对内存的消耗也越大。
Redis使用近似LRU算法,在基本满足策略需要的情况,尽可能的降低了内存的消耗,CPU的占用,在硬件满足的情况的下,也可以通过maxmemory-samples的调整,无线接近于标准LRU算法。
Redis为了实现近似LRU算法,给每个key增加了一个额外增加了一个24bit的字段,用来存储该key最后一次被访问的时间。
Redis3.0对近似LRU算法进行了一些优化。新算法会维护一个候选池(大小为16),池中的数据根据访问时间进行排序,第一次随机选取的key都会放入池中,随后每次随机选取的key只有在访问时间小于池中最小的时间才会放入池中,直到候选池被放满。当放满后,如果有新的key需要放入,则将池中最后访问时间最大(最近被访问)的移除。当需要淘汰的时候,则直接从池中选取最近访问时间最小(最久没被访问)的key淘汰掉就行。
内存淘汰策略
1. noeviction:当内存使用超过配置的时候会返回错误,不会驱逐任何键
2. allkeys-lru:加入键的时候,如果过限,首先通过LRU算法驱逐最久没有使用的键
3. volatile-lru:加入键的时候如果过限,首先从设置了过期时间的键集合中驱逐最久没有使用的键
4. allkeys-random:加入键的时候如果过限,从所有key随机删除
5. volatile-random:加入键的时候如果过限,从过期键的集合中随机驱逐
6. volatile-ttl:从配置了过期时间的键中驱逐马上就要过期的键
7. volatile-lfu:从所有配置了过期时间的键中驱逐使用频率最少的键(Reidis4之后)
8. allkeys-lfu:从所有键中驱逐使用频率最少的键(Reidis4之后)
LFU
LFU是在Redis4.0后出现的,LRU的最近最少使用实际上并不精确,考虑下面的情况,如果在|处删除,那么A距离的时间最久,但实际上A的使用频率要比B频繁,所以合理的淘汰策略应该是淘汰B。LFU就是为应对这种情况而生的。
A~~A~~A~~A~~A~~A~~A~~A~~A~~A~~~|
B~~~~~B~~~~~B~~~~~B~~~~~~~~~~~~B|
参考:
https://zhuanlan.zhihu.com/p/105587132
https://www.cnblogs.com/vegetableDD/p/11890570.html
https://www.bilibili.com/video/BV1Cb411j7RA?p=8
https://segmentfault.com/a/1190000017555834