redis过期key监听事件 「爱情、让人受尽委屈。」 2022-11-06 14:00 218阅读 0赞 ### 文章目录 ### * redis安装 * * docker拉取 * 启动 * redis 配置 * 命令监听 * 问题 * 程序监听 * * 具体监听类 * 效果 * 总结 > redis常用语缓存操作,但是redis功能不仅仅于此。今天我们来看看redis的key失效事件 # redis安装 # * 为了方便安装。我们直接使用docker安装redis。这里不多赘述docker了。直接贴出代码自己搞成脚本执行就可以了 ## docker拉取 ## `docker pull redis:3.2` ## 启动 ## docker run -p 6379:6379 -v /opt/soft/docker/redis/redis.conf:/etc/redis/redis.conf -v /opt/soft/docker/redis/data:/data --name=myredis --restart=always -d redis:3.2 redis-server /etc/redis/redis.conf --requirepass "password" --appendonly yes * 为了安全我们还是设置下密码,将上述脚本password修改为自己的密码即可 * 上面的/opt/soft/docker/redis/data这个我们只需要创建空文件夹就行了,这个我们是为了将redis日志映射出来方便定位问题。 * redis.conf文件去官网上下载就行了。docker安装的redis默认没有配置文件。或者直接复制我这里的。 # Redis配置文件样例 # Note on units: when memory size is needed, it is possible to specifiy # it in the usual form of 1k 5GB 4M and so forth: # # 1k => 1000 bytes # 1kb => 1024 bytes # 1m => 1000000 bytes # 1mb => 1024*1024 bytes # 1g => 1000000000 bytes # 1gb => 1024*1024*1024 bytes # # units are case insensitive so 1GB 1Gb 1gB are all the same. # Redis默认不是以守护进程的方式运行,可以通过该配置项修改,使用yes启用守护进程 # 启用守护进程后,Redis会把pid写到一个pidfile中,在/var/run/redis.pid daemonize no # 当Redis以守护进程方式运行时,Redis默认会把pid写入/var/run/redis.pid文件,可以通过pidfile指定 pidfile /var/run/redis.pid # 指定Redis监听端口,默认端口为6379 # 如果指定0端口,表示Redis不监听TCP连接 port 6379 # 绑定的主机地址 # 你可以绑定单一接口,如果没有绑定,所有接口都会监听到来的连接 # bind 127.0.0.1 # Specify the path for the unix socket that will be used to listen for # incoming connections. There is no default, so Redis will not listen # on a unix socket when not specified. # # unixsocket /tmp/redis.sock # unixsocketperm 755 # 当客户端闲置多长时间后关闭连接,如果指定为0,表示关闭该功能 timeout 0 # 指定日志记录级别,Redis总共支持四个级别:debug、verbose、notice、warning,默认为verbose # debug (很多信息, 对开发/测试比较有用) # verbose (many rarely useful info, but not a mess like the debug level) # notice (moderately verbose, what you want in production probably) # warning (only very important / critical messages are logged) loglevel verbose # 日志记录方式,默认为标准输出,如果配置为redis为守护进程方式运行,而这里又配置为标准输出,则日志将会发送给/dev/null logfile stdout # To enable logging to the system logger, just set 'syslog-enabled' to yes, # and optionally update the other syslog parameters to suit your needs. # syslog-enabled no # Specify the syslog identity. # syslog-ident redis # Specify the syslog facility. Must be USER or between LOCAL0-LOCAL7. # syslog-facility local0 # 设置数据库的数量,默认数据库为0,可以使用select <dbid>命令在连接上指定数据库id # dbid是从0到‘databases’-1的数目 databases 16 ################################ SNAPSHOTTING ################################# # 指定在多长时间内,有多少次更新操作,就将数据同步到数据文件,可以多个条件配合 # Save the DB on disk: # # save <seconds> <changes> # # Will save the DB if both the given number of seconds and the given # number of write operations against the DB occurred. # # 满足以下条件将会同步数据: # 900秒(15分钟)内有1个更改 # 300秒(5分钟)内有10个更改 # 60秒内有10000个更改 # Note: 可以把所有“save”行注释掉,这样就取消同步操作了 save 900 1 save 300 10 save 60 10000 # 指定存储至本地数据库时是否压缩数据,默认为yes,Redis采用LZF压缩,如果为了节省CPU时间,可以关闭该选项,但会导致数据库文件变的巨大 rdbcompression yes # 指定本地数据库文件名,默认值为dump.rdb dbfilename dump.rdb # 工作目录. # 指定本地数据库存放目录,文件名由上一个dbfilename配置项指定 # # Also the Append Only File will be created inside this directory. # # 注意,这里只能指定一个目录,不能指定文件名 dir ./ notify-keyspace-events Ex ################################# REPLICATION ################################# # redis 配置 # * 这里的配置我在上面已经配置了。在官网下载的是默认的配置。上面我加了一个配置`notify-keyspace-events Ex` 。关于Ex下表中有解释 <table> <thead> <tr> <th>属性</th> <th>说明</th> </tr> </thead> <tbody> <tr> <td>K</td> <td>键空间通知,所有通知keyspace@ 为前缀,追对key</td> </tr> <tr> <td>E</td> <td>键事件通知,所有通知已keyspace@为前缀,追对event</td> </tr> <tr> <td>g</td> <td>DEL、EXPIRE、RENAME等类型无关的通用命令通知</td> </tr> <tr> <td>$</td> <td>字符串命令通知</td> </tr> <tr> <td>l</td> <td>列表命令通知</td> </tr> <tr> <td>s</td> <td>集合命令通知</td> </tr> <tr> <td>h</td> <td>哈希命令通知</td> </tr> <tr> <td>z</td> <td>zset命令通知</td> </tr> <tr> <td>x</td> <td>过期事件通知,每当key过期就会触发</td> </tr> <tr> <td>e</td> <td>驱逐事件,每当有键因为maxmemory策略被清楚是触发</td> </tr> <tr> <td>A</td> <td>g$lshzxe总称</td> </tr> </tbody> </table> # 命令监听 # * 完成上述配置后,我们打开redis客户端 docker exec -it myredis redis-cli * myredis是上面安装redis容器的别名。这个读者可以自己设置 * 因为设置了密码,连接后我们需要进行密码验证 auth password * 然后注册监听器 `PSUBSCRIBE __keyevent@*__:expired` * 其中expired就是我们注册类型 , @ 后面的\* 表示DB。这里我们监听所有数据库的key过期事件。 # 问题 # * 比如我们想监听DB0的key删除事件。我们可以这么注册`PSUBSCRIBE __keyevent@0__:del` ![4c0f1f14e873e8eace107728574c69ba.png][] * 127.0.0.1:6379后面没有数字说明使用的是默认的db0。 ![bf93271643d26f0c9146c9ceaa5c2959.png][] * 切换到DB1中查看hello没有查到。且6379后面有了数据库索引值。这个时候在DB1新增hello并进行删除。看看另外一个监听DB0的监听器会不会有响应 \[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iqZTXZ18-1615339350729)(http://oytmxyuek.bkt.clouddn.com/20190310003.jpg)\] * 很明显,我们没有任何的通知。现在我们在DB0 中进行删除hello。看看监听器的效果 * 这个时候在DB0 中执行删除也没有监控到信息。这里不知道为什么。还望指点 # 程序监听 # * springboot程序添加依赖 <!-- redis --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> @Configuration public class RedisConfig { @Bean public RedisMessageListenerContainer redisMessageListenerContainer(RedisConnectionFactory redisConnectionFactory) { RedisMessageListenerContainer redisMessageListenerContainer = new RedisMessageListenerContainer(); redisMessageListenerContainer.setConnectionFactory(redisConnectionFactory); return redisMessageListenerContainer; } } * 这里只是为了演示过期事件的监听。所以这里的redisConfig没有加入太多的配置。 spring: redis: host: 39.102.60.114 port: 6379 database: 0 password: password timeout: 1000s ## 具体监听类 ## @Slf4j @Component public class RedisKeyExpireListener extends KeyExpirationEventMessageListener { public RedisKeyExpireListener(RedisMessageListenerContainer listenerContainer) { super(listenerContainer); } @Override public void onMessage(Message message, byte[] pattern) { log.info("接受到消息:{},{}",message,new String(pattern)); } } ## 效果 ## ![7d1c6f9b6b0424406ff7dd5a27df6def.png][] # 总结 # * key过期事件的监听实际使用的不是很多。因为redis大部分都是缓存作用。缓存本来就会可有可无的。所以监听意义不大。但是也可以在不少场景下使用。 * 订单30分钟未付款自动取消场景 * 系统定时提醒功能 [4c0f1f14e873e8eace107728574c69ba.png]: /images/20221023/9cc5aabcb0374504842b305a8aca72ae.png [bf93271643d26f0c9146c9ceaa5c2959.png]: /images/20221023/5b66658162ac415c9b29344e285e766e.png [7d1c6f9b6b0424406ff7dd5a27df6def.png]: /images/20221023/4a3977373fce410ba6f97fc195ffb1d0.png
还没有评论,来说两句吧...