抛出问题:redis监听过期key不及时
现在时间09:00, 有个key设置一分钟后过期,也就是我在09:01的时候redis会告知我这个key过期了。
但是如果redis存储了海量数据,可能会导致这个的不及时通知,意思就是可能09:02才通知你
出现这种情况通知不及时很可能影响到业务操作,所以我们需要解决这个问题
分析问题:为什么会出现通知不及时的情况?
我们首先得了解redis底层是如何知道key过期的,它有三种方案:
redis默认采用的是定期删除+惰性删除
定期删除的过程:
每隔一段时间,Redis 会分别去各个库随机拿 20 个非永久 Key,判断它们是否过期,过期则删除,如果这一次拿的 key 中有超过 1/4 的数据过期,则再执行一遍过程 1,直到过期数据不超过当次拿出来的 20 条记录的 1/4。
(可以通过配置 redis.conf 中的 hz 修改 Redis 执行定期删除的频率,默认 hz=10,即每 100ms 执行一次,1/4 与每次拿的数量 20 暂时未找到配置项);
如果当前数据库没有非永久 key,则跳过当前数据库;
如果 key 已过期,但没有被定期删除,由于惰性删除策略,在下次请求获取该数据时会将该数据删除;
平时我们都是把所有key都存在一个库里,它去随机获取的时候不一定能拿到过期key,所以就可能造成key过期没有及时通知
解决方案:
1.将缓存数据与监听数据分离,即把不同功能类型的数据分库存放(Redis 默认有 16 个库,库的数量可在 redis.conf 配置修改),例如把缓存数据存在 database0,把监听数据存在 database1;
2. 让进行监听的库中 key 尽量少,如果不同业务的监听超时时间差异较大,则考虑将不同业务的超时监听数据存放到不同的数据库;存放不同的库之后意味着执行命令需要动态切换库,就能获得动态切库组件了
redis多库动态切换组件:https://github.com/it235/knife4j-redis-lettuce