前言
之前有做过redis的一些知识点总结,本章主要针对redis中key的过期策略和淘汰机制内容做一下总结。
过期策略
定期删除:属于主动删除策略,每隔一段时间随机选择一批key,删除其中过期的
惰性删除:通过key获取值时,判断key是否已过期,是则删除
内存淘汰机制
redis的过期策略很明显存在过期key未被及时删除而占用内存的情况。如果极端情况下漏了大量key未被及时删除,就过于浪费内存空间了。
所以redis还提供了内存淘汰机制应对这种情况:
- 内存不足时,新增操作会报错
- 内存不足时,移除最近最少使用的key
- 内存不足时,随机从所有的key中选一个移除
- 内存不足时,移除设置了过期时间且最近最少使用的key
- 内存不足时,随机从设置了过期时间的key中选一个移除
- 内存不足时,移除设置了过期时间key中,过期时间更早的
LRU算法
redis内存淘汰机制通常使用的是上述第二种,也就是LRU算法,移除最近最少使用的。
LRU实现逻辑
LRU的实现最关键的是记录key的使用顺序,那么先进先出队列就很契合。
每次调用进入队列,若队列已满则弹出尾部元素,但这里得考虑处理重复元素的情况。
所以更好的是使用双向链表,新调用的元素放在头节点,已在链表中的被调用也很容易被置换到头节点,链表满了就删除掉尾节点元素。
而reids中的LRU实现没有使用上述两个方法,他的实现逻辑如下:
- 每个key对应的value都记录了调用对应的当前时间戳
- 使用一个数组存放被调用的key,新增时如果满了就剔除时间戳最大的
- 淘汰时就针对数组中的key选择
redis基于内存占用的考虑及数据结构的设计考虑没有引用队列或双向列表去做LRU。
其逻辑是仿照LRU的实现逻辑,使用时间戳比较key的使用顺序,并且并没有对所有的key进行计算操作,而是随机的选择一些进行LRU的淘汰。
小结
本章主要总结了redis过期淘汰涉及的相关概念,重点是redis的LRU逻辑,他是一种近似LRU算
法,基于对性能的考虑并没有对所有key进行计算,而是折中的选取一些,兼顾了淘汰的结果和执
行的性能。