起因:随着项目的进一步推广,数据量的增大,直接访问mysql数据库获取数据所使用的时间越来越长,为解决当前主要矛盾,决定引入redis非关系型数据库作为缓存层,使得数据并不能直接命中数据库,减少访问数据库带来的压力,从而加快运行速度。
1. Redis内部事件订阅机制keyspace&keyevent
# 进入redis的客户端
subscribe java php #订阅了两个通道
pubstribe java springboot #发布通道
psubscribe j* p* #通配频道
1.1. 应用的业务场景
订单超时2小时未支付,需要关闭,如何实现?
- Quartz来做任务调度,定时执行巡检任务,5分钟巡检一次,会有4分59秒的巡检超时
- Timer,java的定时器,秒为单位,数据量大的时候性能就成瓶颈了
- Quartz+Timer ,Quartz拿出5分钟内将要充实的订单,然后在启用多线程以Timer每秒的方式去检查,但业务功能就比较复杂了
- 有没有一种功能,有个hook能通知我们我失效了?通知我执行业务
- 假设:expire 7200 秒过期后通知我,这就是实现了第4种方案了?
Redis在2.8版本后,推出keyspace notifcations特性,类似数据库的trigger触发器
keyspace notifications是基于sub/pub发布订阅机制的,可以接收对数据库中影响key操作的所有事件:比如del、set、expire(过期时间)
1.2. 接收的事件类型
有两种:keyspace、keyevent
keyspace : 是key触发的事件的具体操作
keyevent : 是事件影响的键名
# pub这个动作是系统自动发布的
127.0.0.1:6379> del mykey
# 数据库0会发布以下两个信息
publish __keyspace@0__:mykey del
publish __keyevent@0__:del mykey
1.3. 开启系统通知
redis.conf配置文件里
# 这都是配置项
# K Keyspace events, published with __keyspace@<db>__ prefix.
# E Keyevent events, published with __keyevent@<db>__ prefix.
# g Generic commands (non-type specific) like DEL, EXPIRE, RENAME, ...
# $ String commands
# l List commands
# s Set commands
# h Hash commands
# z Sorted set commands
# x Expired events (events generated every time a key expires)
# e Evicted events (events generated when a key is evicted for maxmemory)
# A Alias for g$lshzxe, so that the "AKE" string means all the events.
# 开关 在redis.conf配置里
notify-keyspace-events "" #默认空字符串,是关闭状态
notify-keyspace-events "KEx" #配置文件里只配置了space和event的expried事件,就只自动发布这个事件
统配订阅
notify-keyspace-events "KEA"
set username gavin ex 10 #set事件,expire事件
psubscribe __key*@*__:*
#返回事件通知
4) "set"
1) "pmessage"
2) "__key*@*__:*"
3) "__keyevent@0__:set"
4) "username"
1) "pmessage"
2) "__key*@*__:*"
3) "__keyspace@0__:username"
4) "expire"
1) "pmessage"
2) "__key*@*__:*"
3) "__keyevent@0__:expire"
4) "username"
1) "pmessage"
2) "__key*@*__:*"
3) "__keyspace@0__:username"
4) "expired"
1) "pmessage"
2) "__key*@*__:*"
3) "__keyevent@0__:expired"
4) "username"
subscribe __keyevent@0__:expired
1.4. Springboot订阅通知
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
不要以为每天把功能完成了就行了,这种思想是要不得的,互勉~!
网友评论