当前位置:首页 > 问答 > 正文

Redis 过期事件那些事儿,教你怎么轻松搞定缓存数据管理

(引用来源:Redis官方文档,博客园“Redis过期键的删除策略”)

今天咱们来聊一个Redis里挺实用但有时候又有点让人挠头的功能——过期事件,你肯定知道,Redis能给存进去的数据设置一个存活时间,比如验证码五分钟失效,热门商品数据缓存一小时,时间一到,Redis就会自动把这条数据给删了,这能帮我们省去很多手动清理的麻烦,是管理缓存数据的基本操作。

但有时候,光删除还不够,我们可能想在数据过期的那一刻,干点别的事情,比如说,用户登录的token过期了,我们想立刻记录个日志,或者通知一下安全系统;再比如,某个热点数据失效了,我们想马上从数据库再加载一份新的放到缓存里,避免下一个请求来的时候因为要查数据库而变慢,这种“数据死了还得拉个警报”的需求,就是Redis的过期事件功能大显身手的地方。

(引用来源:Redis Keyspace Notifications 说明)

Redis 过期事件那些事儿,教你怎么轻松搞定缓存数据管理

这个功能的官方名字叫“键空间通知”,听着有点高大上,其实理解起来不难,Redis内部就像有一栋大楼,每个数据都住在一个房间里,房间号就是键,Redis允许我们订阅这栋大楼的“管理通知”,当某个房间发生特定事件时,比如租客到期被清退(键被删除),大楼管理处就会发一个广播,我们只要提前告诉Redis:“我想听某某房间到期清退的通知”,然后搬个凳子等着听广播就行了。

要实现监听过期事件,你需要搞定两件事:

第一件事,是打开Redis的“广播开关”,因为监听功能会消耗一点点CPU资源,所以Redis默认是关着的,你需要修改Redis的配置文件redis.conf,找到一行叫notify-keyspace-events的设置,把它改成Ex,这里的E意思是启用键空间事件通知,x是专门指过期事件,改完之后,记得重启一下Redis服务,或者通过命令行动态配置让它生效。

第二件事,就是写个“听众”程序,这个程序需要一直运行着,像一个忠诚的哨兵,它通过Redis提供的“发布订阅”功能,订阅一个特殊的频道,当有键过期时,Redis就会往这个频道里发布一条消息,内容大概是:“嘿,注意了,某个键已经过期啦!”你的程序收到这条消息,就能知道是哪个键过期了,然后就可以执行你预设好的那些操作了,比如调用另一个接口、写一条记录到文件或者数据库里。

Redis 过期事件那些事儿,教你怎么轻松搞定缓存数据管理

(引用来源:CSDN博客“Redis过期回调实战”)

听起来挺美好,对吧?但这里面有几个“坑”,你得留心,不然容易掉进去。

第一个坑是,这个过期事件的通知不是百分百准时的,Redis删除过期键主要有两种策略:一种是惰性删除,就是当客户端试图访问一个键时,Redis才检查它是否过期,如果过期就删除;另一种是定期删除,Redis每隔一段时间随机抽查一批键,删除其中过期的,有可能一个键已经过期了,但迟迟没有被访问,又没轮到被定期抽查到,它就会暂时还留在内存里,自然也就不会触发过期事件,只有当Redis真正执行删除动作的那一刻,事件才会被触发,这意味着,你的“警报”可能会晚点响。

第二个坑是,消息“一次性”的,Redis的发布订阅模式是“fire and forget”(发了就忘),如果你的监听程序在事件发生的那一刻刚好没运行,比如重启了或者因为网络问题断开了连接,那这条过期通知就永远丢失了,Redis不会替你存着等你上线再补发,这个机制不适合用来处理要求绝对可靠的消息队列场景,如果你的业务逻辑非常关键,不能错过任何一次过期事件,那可能需要在应用层自己再做一些额外的保障。

Redis 过期事件那些事儿,教你怎么轻松搞定缓存数据管理

(引用来源:个人项目经验总结)

那怎么才能用好它呢?这里有点小建议。

对于要求不是极端严格的场景,比如清理一些关联的临时数据、记录非关键指标的统计信息、或者尝试性地预加载数据,过期事件是一个非常轻便好用的工具,它让你能被动地响应变化,而不是傻傻地不停地去轮询检查,提高了效率。

但如果你要做的事情很重要,比如涉及到金融交易的状态更新,光靠它可能就不太放心了,这时候,你可能需要结合其他方法,除了监听Redis的过期事件,你还可以在应用代码里,在设置缓存的时候,同时往一个延迟任务队列(比如用RabbitMQ的延迟插件或者阿里云的MQ)里塞一个延迟到期的任务,做个双保险,或者,对于一些有规律的数据,干脆就用定时任务每隔一段时间去集中处理,这样更可控。

Redis的过期事件就像是一个贴心的小助手,能帮你自动化处理很多缓存数据失效后的后续工作,让你搞起缓存数据管理来更轻松,但你得清楚它的脾气——它可能有点“拖延症”,而且记性不太好(不保证消息必达),用的时候扬长避短,把它放在合适的场景里,它就能成为你工具箱里的一件得力武器。