Redis偶发Cannot determine a partition for slot报错问题
- 一、背景
- 二、问题定位
- 1、报错位置
- 2、lettuce定时刷新任务
- 3、本地缓存masterCache先清理后写入的问题
- 三、解决方案:版本升级
一、背景
线上系统(springboot)经常报错Cannot determine a partition for slot,搜索过后发现已有的解决方案大多是Redis集群的配置不对。对于我们的线上系统来说,这显然是不可能的,经过和DBA确认,报错时间点Redis集群无变更。
Caused by: io.lettuce.core.cluster.PartitionSelectorException:
Cannot determine a partition for slot 5586.
二、问题定位
我们系统使用的是lettuce的6.2.0.RELEASE
1、报错位置
根据报错信息搜索报错的代码位置,可以看到是通过slot槽获取Redis节点信息时,返回值为null。
2、lettuce定时刷新任务
下面分析masterCache的写入机制。
而对于lettuce而言,开启拓扑定时刷新后,会提交定时刷新任务到Schedule线程池(ScheduledExecutorService)中。
对于拓扑刷新的核心步骤分为三步
3、本地缓存masterCache先清理后写入的问题
在lettuce定时刷新任务的第三步时,会进行本地缓存的刷新,其先进行本地缓存的清理,再写入新的缓存,那对于本地缓存已清理新缓存还未写入的这段时间差,如果有Redis操作,则会找不到节点,即抛出Cannot determine a partition for slot异常。
三、解决方案:版本升级
将lettuce升级至最新版本6.2.6.RELEASE,可以看到其刷新本地缓存的逻辑已经进行了优化,只有当节点信息为空的时候才会清理本地缓存,直接用新的缓存信息覆盖旧缓存。