准备
redis可以做读写分离,不过这个要看应用的客户端是否支持。
这里使用Lettuce客户端做了下读写分离验证。
首先搭建哨兵模式,可以参考这篇文章 https://blog.csdn.net/u012772064/article/details/94452211
哨兵模式搭建后的节点环境:
192.168.80.130:6379 master
192.168.80.130:6380 replication
192.168.80.130:6381 replication
192.168.80.130:26379 sentinel
192.168.80.130:26380 sentinel
192.168.80.130:26381 sentinel
环境搭建完毕,下面我们来验证哨兵模式下读写分离的效果
代码
准备以下代码验证读写分离
使用LettuceClient进行读写分离
@Configuration
@ComponentScan("com.redis")
public class RedisConfig {
@Bean
public LettuceConnectionFactory redisConnectionFactory() {
// return new LettuceConnectionFactory(new RedisStandaloneConfiguration("192.168.80.130", 6379));
RedisSentinelConfiguration sentinelConfig = new RedisSentinelConfiguration()
.master("mymaster")
// 哨兵地址
.sentinel("192.168.80.130", 26379)
.sentinel("192.168.80.130", 26380)
.sentinel("192.168.80.130", 26381);
LettuceClientConfiguration clientConfig = LettuceClientConfiguration.builder().
readFrom(ReadFrom.SLAVE_PREFERRED).build();
return new LettuceConnectionFactory(sentinelConfig, clientConfig);
}
@Bean
public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate redisTemplate = new RedisTemplate();
redisTemplate.setConnectionFactory(redisConnectionFactory);
// 可以配置对象的转换规则,比如使用json格式对object进行存储。
// Object --> 序列化 --> 二进制流 --> redis-server存储
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
return redisTemplate;
}
}
测试代码
代码逻辑:每隔100ms向redis set 100个数字 紧接着再读取这100个数字
public class RedisTest {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(RedisConfig.class);
StringRedisTemplate redisTemplate = (StringRedisTemplate) context.getBean("stringRedisTemplate");
for (int i = 0; i < 100; i++) {
redisTemplate.opsForValue().set(String.valueOf(i), String.valueOf(i));
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (int i = 0; i < 100; i++) {
redisTemplate.opsForValue().get(String.valueOf(i));
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
结果
可以使用monitor命令,查看redis服务节点所执行的命令
redis-cli -p 6379 monitor
redis-cli -p 6380 monitor
redis-cli -p 6381 monitor
分别监控 6379、6380、6381三个redis节点,观察结果
6379端口
6380端口
6381端口
可以看到写操作set命令,三个节点都有执行。实际上是主节点执行,并同步到从节点
而读操作get命令,只有6381端口的从节点执行,说明读写分离起到了作用,但都走到了同一个从节点。
个人理解,redis的读写分离比较鸡肋。
首先有些业务需求可能对redis数据要求有较高的实时性,毕竟读写分离有读延迟。
其次如果redis真的有访问压力,完全可以用redis cluster模式。
另外有的客户端不支持redis读写分离。
redis的从节点的意义主要还是为了高可用而存在的。