原外包项目redis cluster
三主三从没有密码,后面因申请三级等保,要求需要密码,这时项目尚未交接,于是让外包公司把集群密码补上。
补上密码之后看似也没有任何问题,就这样跑了三个月。
中间因项目框架升级替换了外包原有封装的jedis
客户端为redisson
,将spring3.1.2
升级成springboot
项目,然后将项目中原本使用 redisUtil
的地方全部替换成redisTemplate
,并且将分布式锁替换成redissonclient
,这个时候也没有问题。
直到某一天一个开发用redissoncleint
去set
,get
值发现set
成功了但是get
为null
,但是在开发环境下同样的集群又好用,开发环境原本是单机的,是后面我们自己部署的集群,于是就开始找问题;各种猜测,得出两个结论:
- 集群配置的有问题
redisson client
配置有问题
又想既然redistemplate
的set
,get
又正常,那应该是redisson
配置有问题的可能性比较大,于是看了下redisson
的默认配置,发现readmode
默认配置为slave
,于是改了下readmode
为master
、或者maste_slave
之后就好用了,于是这里得出一个结论是不是slave
节点没同步导致的,顺着这个思路去看了下生产的日志发现 这样一个报错Unexpected reply to PSYNC from master: -NOAUTH Authentication required
立马get
到问题所在,配置了密码却没有配置集群凭证,导致写的时候写master
,读的时候读slave
,但是slave
数据无法同步到,于是就出现如上情况。
于是技术追溯为什么之前外包写的client
没问题?一看代码发现他们的写法是循环拿到所有节点,一个个遍历去取,这是什么写法,看似很笨,但是确实把这个问题完美规避掉了,看到这里只能给他们竖起一根大大的大拇指。
又看了下为什么redisTemplate
也没问题,发现redisTemplate
走的是默认配置用的是LettuceConnectionConfiguration
和JedisConnectionConfiguration
共同继承自RedisConnectionConfiguration
,这里设置max-redirect
参数,意味着在从节点找不到会返回客户端重定向到新得节点去获取,这里就是被重定向到master
节点去获取,所以没问题,然而redissonConnectionFactory
与这两者实现不一样,并没有max-redirect
参数,所以它就不行了。
总结
外包项目真的是只有把你坑死了才知道坑在哪。