Redis过期监听场景
业务中有类似等待一定时间之后执行某种行为的需求 , 比如30分钟之后关闭订单 . 网上有很多使用Redis过期监听的Demo , 但是其实这是个大坑 , 因为Redis不能确保key在指定时间被删除 , 也就造成了通知的延期 . 不多说 , 跑个测试
测试情况
先说环境 , redis 运行在Docker容器中 ,分配了 一个cpu以及512MB内存, 在Docker中执行 redis-benchmark -t set -r 100000 -n 1000000
结果如下:
1 | 复制代码====== SET ====== |
其实这里有些不严谨 benchmark
线程不应该在Docker容器内部运行 . 跑分的时候大概 benchmark 和redis 主线程各自持有50%CPU
测试代码如下:
1 | 复制代码@Service |
大概意思就是每小时56分的时候 , 会增加一批在接下来16小时过期的key , 过期时间间隔8秒 , 且过期时间都在55分之前
1 | 复制代码@Slf4j |
这里是监测到过期之后打印当前的dbSize 以及滞后时间
1 | 复制代码@Bean |
设置Redis的过期监听 以及线程池信息 ,
最后的测试结果是当key数量小于1万的时候 , 基本上都可以在10s内完成过期通知 , 但是如果数量到3万 , 就有部分key会延迟120s . 顺便贴一下我最新的日志
1 | 复制代码2020-05-13 22:16:48.383 : 过期key:2020-05-13 11:56:02@2020-05-13 22:14:08 ,当前size:57405 ,滞后时间160 |
可以看到 ,当数量到达5万的时候 , 大部分都已经滞后了两分钟 , 对于业务方来说已经完全无法忍受了
总结
可能到这里 , 你会说Redis 给你挖了一个大坑 , 但其实这些都在文档上写的明明白白
尤其是在 Timing of expired events 中 , 明确的说明了 “Basically expired
events are generated when the Redis server deletes the key and not when the time to live theoretically reaches the value of zero.” , 这两个文章读下来你会感觉 , 卧槽Redis的过期策略其实也挺’Low’的
其实公众号看多了 , 你会发现大部分Demo都是互相抄来抄去 , 以及翻译官方Demo . 建议大家还是谨慎一些 , 真要使用的话 , 最好读一下官方文档 , 哪怕用百度翻译也要有一些自己的理解 .
文章比较枯燥 , 感谢大家耐心阅读 , 如有建议 恳请留言.
本文转载自: 掘金