十三、 Redis过期策略和内存淘汰策略

Redis的过期策略和内存淘汰策略都是对key做删除操作。是从不同的维度来考虑的。

过期策略

过期删除策略考虑的是那些设置了删除时间的key,在什么时候以何种方式来删除key。

  1. 设置key过期的时间
    在Redis中设置key过期有两种方式:
  • 对已存在的key设置过期时间,有以下指令:
指令说明
expire <key> <n>设置key在n秒后过期 比如:expire k1 30 设置k1在30秒后过期
pexpire <key> <n>设置key在n毫秒后过期 比如: pexpire k2 30000 设置k2y在30000毫秒后过期
expireat<key> <n>设置key在某个时间戳(秒)后过期 比如: expireat k3 1594341579 设置k3在时间戳1594341579后过期,注意是精确到秒
pexpireat<key> <n>设置key在某个时间戳(毫秒)后过期 比如: expireat k4 1594341579000 设置k4在时间戳1594341579000后过期,注意是精确到毫秒
  • 在设置key时同时设置过期时间,有以下指令:
指令说明
set <key> <value> ex <n>设置键值对的同时指定过期时间,精确到秒。比如 set k1 v1 ex 30
set <key> <value> px <n>设置键值对的同时指定过期时间,精确到毫秒。比如 set k2 v2 px 30000
setex <key> <n> <value>设置键值对的同时指定过期时间,精确到秒。比如 setex k3 30 v3

查看key的过期时间: ttl <key>

127.0.0.1:6379> ttl k1
(integer) 27
127.0.0.1:6379> ttl k1
(integer) 21
127.0.0.1:6379>

取消key的过期时间: persist <key>

127.0.0.1:6379> setex k1 30 v1
OK
127.0.0.1:6379> get k1
"v1"
127.0.0.1:6379> ttl k1
(integer) 23
127.0.0.1:6379> persist k1
(integer) 1
127.0.0.1:6379> ttl  k1
(integer) -1
127.0.0.1:6379>

2 . 如何判断key已过期
Redis中维护了一个过期字典(字典类型实际上是一个哈希表)。所有设置了过期时间的key都会保持到这个字典中。
过期字典的数据结构如下:

  • 过期字典的key是一个指针,指向某个键对象;
  • 过期字典的value是一个long long类型的整数,这个整数保持了key的过期时间。

当我们查询一个key时,Redis先检查key是否存在于过期字典中:

  • 如果不存在,则正常读取值
  • 如果存在,则获取该key的过期时间,然后与当前系统时间进行比对,如果比系统时间大,则未过期,否则判定该key已过期。

3 . 过期删除策略分类及优缺点

过期策略做法优点缺点
定时删除在设置key的过期时间时,同时创建一个定时事件,当时间到达,由事件处理器自动执行key的删除操作可保证key会被尽快删除,内存可以尽快被释放。因此,定时删除对内存是最友好的在过期key较多的情况下,会大量消耗CPU资源在,影响服务器性能。因此,定时删除对CPU不友好
惰性删除不主动删除key,在读取key时判断是否过期,如果过期则删除该key只在读取key时才检查key是否过期,只消耗很小的CPU资源,因此该策略对CPU最友好如果一个key已过期,但是很长时间没有被访问,将会一直占用内存资源。因此,该策略对内存不友好
定期删除每隔一段时间随机从数据库中取出一定数量的key进行检查,并删除其中过期的key不会占用过多的CPU资源检查key是否过期,也能让一部分已过期的Key被删除减少内存被占用在内存清理方面没有定时删除效果好,同时也没有惰性删除使用的系统资源少。该策略是一个折中的选择。
  1. Redis的过期删除策略
    前面介绍的三种删除策略,都有优缺点,仅使用一种都不能满足实际需求。
    Redis使用的是【惰性删除+定期删除】这两种策略的配合,以达到CPU资源和避免内存浪费之间的平衡。

Redis在4.0版本提供了lazyfree-lazy-expire参数来配置惰性删除是异步还是同步。
Redis的定期删除是:每隔一段时间随机从数据库中取出一定数量的key进行检查。

  • 间隔时间的时长
    默认是每秒进行10次过期检查。可在redis.conf配置文件中配置 hz 键的值进行修改
hz 10
  • 随机抽取的数量
    随机抽取的数据是写死在代码中的,数值据说是20。

内存淘汰策略

内存淘汰策略说的是Redis在存储内存不足的情况下,以何种方式来淘汰掉现有的数据,让新的数据可以继续保存的问题。
首先,要开启内存淘汰策略,需要先配置 maxmemory 参数。如果未配置该参数,表示没有内存限制大小,则Redis不会对内存进行检查,直到因内存不足而导致崩溃为止。

maxmemory <bytes>

可根据单位设置

  • maxmemory 100 裸数字情况:单位是字节。
  • maxmemory 1K K:代表1000字节。
  • maxmemory 1KB KB:代表1024字节。
  • maxmemory 1M M:代表1000000字节。
  • maxmemory 1MB MB:代表1048576字节。
  • maxmemory 1G G:代表1000000000字节。
  • maxmemory 1GB GB:代表1073741824字节。

内存淘汰策略分类

  1. 不进行数据淘汰
    noeviction, Redis3.0之后默认的内存淘汰策略。表示不淘汰任何数据,直到内存不足后不在提供服务,直接返回错误。注意,该配置和上面的maxmemory配置是不冲突的。例如maxmemory设置为1GB,当数据存储到1GB时继续添加数据则直接报错。如果maxmemory不配置,则当系统内存不足时直接报错。
maxmemory-policy noeviction
  1. 进行数据淘汰
    进行数据淘汰分为下列两类:
  • 在设置了过期时间的数据中进行淘汰
配置说明
volatile-random随机淘汰设置了过期时间的任意键
volatile-ttl优先淘汰更早过期的键
volatile-lruRedis3.0之前,默认的内存淘汰策略。淘汰所有设置了过期时间的键中,最久未使用的
volatile-lfu淘汰所有设置在了过期时间的键中,最少使用的
  • 在所有数据范围内进行淘汰
配置说明
allkeys-random随机淘汰任意键
allkeys-lru淘汰所有键中最久未使用的
allkeys-lfuRedis4.0后新增的内存淘汰策略。淘汰所有键中最少使用的

查看当前内存淘汰淘汰策略

127.0.0.1:6379> CONFIG GET maxmemory-policy
1) "maxmemory-policy"
2) "noeviction"
127.0.0.1:6379>
  • 可通过命令 “config set maxmemory-policy <策略>”
    设置。优点是可以立即生效,缺点是重启Redis后就会失效。
  • 可修改配置文件设置 “maxmemory-policy <策略>”。优点是重启Redis后也生效。缺点是必须重启Redis才生效。

LRU算法和LFU算法的区别

  • LRU全称是 Least Recently Used – 最近最少使用的。它是根据访问时间来淘汰数据的,核心思想是“如果数据在相当长一段时间没有被访问,那么将来被访问到的可能性也更小”。
  • LFU全称是 Least Frequently Used – 最近最不常使用的。它是根据访问次数来淘汰数据的,核心思想是 “如果数据过去被访问多次,那么将来被访问的频率也更高”。

举个例子: 现在有key1、key2两个key。
key1在第一分钟被访问10次,在第二分钟没有被访问。
key2在第一分钟被访问5次,在第二分钟被访问3次。

如果是LRU算法,则key1被淘汰。因为key1已经一分钟没有被访问到了,它是最近最少使用的。

如果是LFU算法,则key2被淘汰。因为key2在两分钟的时间内没有key1被访问的次数多。key1虽然在第二分钟没有被访问,但是两分钟的时间内总共被访问10次,key2虽然在第二分钟也被访问了,但是两分钟的时间内总共被访问了8次。按照最近最不常用原则,key2被淘汰。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值