1、问题背景
1.1 问题介绍:
在哨兵模式下,使用redission的StringRedisTemplate的set方法和get方法时,
当set完以后立即get获取数据,就会存在获取不到最新set的数据;
1.2 问题原因:
由于redission的StringRedisTemplate 的 get方法默认读取的是从节点,set操作的是主节点,会存在主从同步的延迟,在get获取结果的时候,就会存在获取不到最新数据的情况。
2、问题定位
2.1 set 方法代码追踪
stringRedisTemplate.opsForValue().set 方法;
进入org.springframework.data.redis.core.DefaultValueOperations#set(K, V)中;
进入org.redisson.spring.data.connection.RedissonConnection#set(byte[], byte[])方法
通过org.redisson.command.CommandAsyncService#async方法中的,入参readOnlyMode为flase
可以看出set方法操作的是主节点。
2.2 get 方法
stringRedisTemplate.opsForValue().get 方法;
进入org.springframework.data.redis.core.DefaultValueOperations#get(java.lang.Object)方法中
进入org.redisson.spring.data.connection.RedissonConnection#get方法:
跳转read(byte[] key, Codec codec, RedisCommand<?> command, Object... params)
org.redisson.command.CommandAsyncService#async的入参readOnlyMode 为true 判断get默认使用的是从库。
3、问题解决方法
3.1 方案一
配置强制读主节点:
config.useClusterServers()
.setReadMode(ReadMode.MASTER); // 配置强制读主
3.2 方案二
使用jedis,jedis是同步阻塞式通信机制,并且单一连接保持时序,保证各条获取到最新set数据。
注:记录工作中遇到的问题及解决方案,大家有更优的解决方案,欢迎补充!