redis缓存是在内存中保存数据,避免业务从数据库中读取数据,从而提升系统的响应速度。内存相比于磁盘访问速度时快了,但是内存的成本时远高于磁盘的,所以不可能将所有的数据都放在内存中,所以当缓存空间满了以后就涉及到缓存淘汰的问题。
redis缓存有哪些淘汰策略
大概有八种,如下图
下面逐个介绍下
- noevction:一旦数据被写满了,再有写请求的时候直接返回错误
- volatile-ttl 在筛选时,会针对设置了过期时间的键值对,根据过期时间的先后进行删除,越早过期的越先被删除。
- volatile-random 就像它的名称一样,在设置了过期时间的键值对中,进行随机删除。
- volatile-lfu 会使用 LFU 算法选择设置了过期时间的键值对。
- allkeys-randoms:从所有键值对选择并随机删除
- allkeys-lru策略:使用lru算法在所有数据中筛选
- allkeys-lfu:使用lfu算法在所有数据中筛选
###LRU
LRU算法全称是Least Recently Used,就是按照最近最少使用原则来筛选数据,最不常用的数据会被筛选出来,最频繁使用的数据会留在缓存中
LRU会将所有的数据维护在一个链表中,链表的头和尾分别是MRL、LRU端,分别代表最长使用和最不常用的数据,如下图
LRU算法其实很好理解,就是认为刚刚访问的数据可能还会被访问到,就放在MRU端,长时间不访问的数据放在LRU端,缓存满了就删除它
不过因为LTR需要用链表管理所有数据,会带来额外的开销,而且每次数据访问时需要移动数据,会比较耗时,降低redis的缓存性能。
所以redis对LRU做了简化,redis会记录每条数据最近一次访问的时间戳,然后redis在淘汰数据时会随机选出N个数据,作为一个候选集合,接下来redis会比较这N个数据份lru字段。把其中最小的淘汰出去
Redis 提供了一个配置参数 maxmemory-samples,这个参数就是 Redis 选出的数据个数 N。例如,我们执行如下命令,可以让 Redis 选出 100 个数据作为候选数据集:
CONFIG SET maxmemory-samples 100
当需要再次淘汰数据时,Redis 需要挑选数据进入第一次淘汰时创建的候选集合。这儿的挑选标准是:能进入集合数据的lru字段必须小于集合中最小的lru值。当有新数据进入候选数据集后,如果候选数据集中的数据个数达到了 maxmemory-samples,Redis 就把候选数据集中 lru 字段值最小的数据淘汰出去。