redis 5 内存更新(淘汰策略)

Redis的数据是存储在内存中的,而服务器的内存大小是有限制的,除非宕机,否则这些数据会一直存在,对于一些不再使用的key,也应当进行删除,否则会浪费内存空间。而且有些场景需要这种有失效性的数据,比如限时优惠活动、用户session、验证码等。过了一定的时间就需要删除这些数据。为了解决这个问题,Redis提供了可以为这个值设置一个过期的时间功能,当达到这个过期时间后,将这个数据进行删掉来释放内存空间

零、redis的删除策略

  • 定时删除
    在设置键的过期时间的时候创建一个定时器,当过期时间到的时候立马执行删除操作,此种方式对 正常业务读写影响较大。
  • 定期删除
    redis数据库默认每隔100ms就会进行 随机抽取 一些设置过期时间的key进行检测,过期则删除。
  • 惰性删除
    对定期删除没有『随机抽取』到的key进行删除,当访问这个key的时候,才会删除这个key

一、过期时间

redis对存储值的过期处理实际上是针对该值的键(key)处理的,即时间的设置也是设置key的有效时间。Expires字典保存了所有键的过期时间,Expires也被称为过期字段。Redis提供了四种处理策略:

EXPIRE 将key的生存时间设置为ttl秒
PEXPIRE 将key的生成时间设置为ttl毫秒
EXPIREAT 将key的过期时间设置为timestamp所代表的的秒数的时间戳
PEXPIREAT 将key的过期时间设置为timestamp所代表的的毫秒数的时间戳
1、2两种方式是设置一个过期的时间段,如处理验证码最常用的策略,设置三分钟或五分钟后失效,把分钟数转换成秒或毫秒存储到redis中。
3、4两种方式是指定一个过期的时间 ,比如优惠券的过期时间是某年某月某日,只是单位不一样。

例如:

127.0.0.1:6379> set messageCode 8223
OK
127.0.0.1:6379> expire messageCode 100
(integer) 1

使用ttl命令查看剩余生命周期:

127.0.0.1:6379> ttl messageCode
(integer) 91

在小于2.1.3的版本里,只能对key设置一次expire。2.1.3和之后的版本里,可以多次对key使用expire命令,更新key的expire time。如果对key使用set或del命令,那么也会移除expire time。
设置了过期时间的key会被在过期后会被删除掉,那么redis是以何种方式删掉的呢?

二、LRU/LFU/FIFO算法剔除

1.八种策略

  • redis会对过期的key进行清除,但是如果插入的速度大于清除的速度的话,服务器的内存迟早会满的。
  • 此时需要一种淘汰策略来对内存中的key再进行处理,Redis会根据用户配置的淘汰策略清除无用的key释放来内存空间

redis 5 提供了以下八种(redis 4是四种)中内存淘汰的策略:

  • volatile-lru: 从设置过期时间的数据集中挑选出最近最少使用的数据淘汰。没有设置过期时间的key不会被淘汰,这样就可以在增加内存空间的同时保证需要持久化的数据不会丢失。

  • allkeys-lru:从数据集中挑选最近最少使用的数据淘汰,该策略要淘汰的key面向的是全体key集合,而非过期的key集合。 (应用最广泛的策略)

  • volatile-random:从已设置过期时间的数据集中随机选择数据淘汰

  • allkeys-random:从全体的key集合中任意选择数据淘汰

  • volatile-ttl:除了淘汰机制采用LRU,策略基本上与volatile-lru相似,从设置过期时间的数据集中挑选将要过期的数据淘汰,ttl值越大越优先被淘汰。

  • noeviction:禁止驱逐数据,也就是当内存不足以容纳新入数据时,新写入操作就会报错,请求可以继续进行,线上任务也不能持续进行,采用no-enviction策略可以保证数据不被丢失,这也是的一种淘汰策略。

  • volatile-lfu:从所有配置了过期时间的键中驱逐使用频率最少的键

  • allkeys-lfu:从所有键中驱逐使用频率最少的键。

    一般来说,volatile-lru使用的场景偏多,在开发中,对于那些重要的,绝对不能丢弃的数据(如配置类数据等),应不设置有效期,这样Redis就永远不会淘汰这些数据;对于那些相对不是那么重要的,并且能够回源的数据,可以设置有效期,这样在内存不够时Redis就会淘汰这部分数据。

2.设置淘汰策略:

到redis的bin目录下使用如下命令:

redis-cli -p 6379 config set maxmemory-policy volatile-lru

或者直接修改redis.conf配置:

maxmemory-policy volatile-lru

Redis中的淘汰机制是从性能和可用性方面考虑的,并不是完全可靠,我们在开发中应尽量对不需要永久保存的数据主动设置或更新key的expire时间,主动删除这部分数据,提升Redis整体性能和空间。

特点,所有的设置的过期了的key的淘汰策略名称都是volatile开头的,这是因为设置了过期时间的key都是属于不稳定的key,这里也是见名知意。

Redis中的LRU与常规的LRU实现并不相同,常规LRU会准确的淘汰掉队头的元素,但是Redis的LRU并不维护队列,只是根据配置的策略要么从所有的key中随机选择N个(N可以配置)要么从所有的设置了过期时间的key中选出N个键,然后再从这N个键中选出最久没有使用的一个key进行淘汰。LRU的最近最少使用实际上并不精确,为了解决这个缺陷,Redis4.0提供了LFU(Least Frequently Used)算法,也就是最频繁被访问的数据将来最有可能被访问到。思想类似redis会每个key维护一个计数器。每次key被访问的时候,计数器增大。计数器越大,可以约等于访问越频繁。

三、主动更新

应用方对于数据的一致性要求高,需要在真实数据更新后,
立即更新缓存数据。例如可以利用消息系统或者其他方式通知缓存更新。

你可能感兴趣的:(redis 5 内存更新(淘汰策略))