开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第8天,点击查看活动详情
1.定时场景
我们在实际的业务生产当中,或多或少都会遇到一些定时任务的场景,目前公司也有类似订单超时取消的场景,为了节省成本,结合现有的redis集群跟Springboot工程项目,做了一个简单的redis定时任务。
redis里边有一个命令:expire,这个命令就是用来设置key的过期时间的,当到达过期时间之后,这个key就会被置为无效状态,然后从redis集群当中删除,那么我们的java服务如何知道这个key过期了呢?这就要用到redis的发布订阅与过期通知功能,当key过期时候,redis集群就会主动通知java服务,进行后边的过期处理。
2.开启redis的过期通知选项
在redis的命令行界面输入如下命令开始redis的过期通知功能,不用重启即刻生效。
127.0.0.1:6379> config set notify-keyspace-events Ex
127.0.0.1:6379> PSUBSCRIBE __keyevent@0__:expired
127.0.0.1:6379> PSUBSCRIBE __keyevent@0__:expired
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "__keyevent@0__:expired"
3) (integer) 1
127.0.0.1:6379> set name zhangsan EX 5
127.0.0.1:6379> PSUBSCRIBE __keyevent@0__:expired
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "__keyevent@0__:expired"
3) (integer) 1
1) "pmessage"
2) "__keyevent@0__:expired"
3) "__keyevent@0__:expired"
4) "name"
如果在这段时间之内没有去主动获取key,或者没有扫描到,那么会产生一定的延迟,因此,当数据量相对于redis服务来说不是很大的时候是推荐使用的,当数据量很大,超过redis的最佳服务范围内时候不推荐使用。
redis 会将每个设置了过期时间的 key 放入到一个独立的字典中,以后会定时遍历这个字典来删除到期的 key。除了定时遍历之外,它还会使用惰性策略来删除过期的 key,所谓惰性策略就是在客户端访问这个 key 的时候,redis 对 key 的过期时间进行检查,如果过期了就立即删除。定时删除是集中处理,惰性删除是零散处理。
redis默认的是采用定期删除跟惰性删除的方式
| 策略 | 描述 | 优点 | 缺点 |
|---|---|---|---|
| 定时删除 | 在设置key的时候给它创建一个定时器,在达到设置的过期时间时候,立即对key进行删除 | 对内存友好,在时间到了时候,会删掉key释放内存空间 | 对CPU不友好,如果存在大量的过期key,CPU的使用率会变高,对服务器造成压力 |
| 定期删除 | 建一个定时器,每隔一段时间检查一次,如果存在过期key,就进行删除 | CPU消耗比较小,有效释放内存空间 | 如果设置数据量较大,删除时间较长,就会造成CPU的占用率过大。如果执行频率较低,也会造成大量过期key得不到及时删除,浪费内存空间 |
| 惰性删除 | 获取key的时候判断是否过期了 | 对CPU友好,只有在获取key的时候才会对key进行扫描,不需要创建定时器扫描 | 对内存不友好,会有大量的key过期在内存里边得不到清除,造成内存浪费 |
redis有三种过期策略:
redis定时器虽然说,很简单,但并不是万金油,依然存在着问题,当定时任务量过大的时候,过期通知会有延期的问题,这跟Redis自动过期的实现方式有关。
3.注意事项
我们可以根据官方给出的redis客户端根据不同的开发语言自己去进行业务的封装,详细细节本篇文章不再赘述
说明通知成功
过五秒,查看第一个redis-cli命令行界面显示的内容
第二个redis-cli随便设置一个key-value以及它的过期时间
会显示如下内容
第一个redis-cli输入如下命令,进行监听
接下来先进行简单的测试,打开两个redis-cli的命令界面