Redis|SpringBoot整合Redis集群读写分离(Lettuce客户端)



文章目录

  • 一. 问题背景
  • 二. 版本说明
  • 三. 前言
  • 四. 如何实现读写分离?
  • 五. 动手实现读写分离
    • 5.1 整合Lettuce
    • 5.1 向Spring注册连接组件
    • 5.2 测试

一. 问题背景
前面研究了SpringBoot整合Redis集群(Lettuce客户端),然后尝试玩玩读写分离,客户端使用Lettuce(SpringBoot2.x已经默认支持Lettuce了,就不再研究Jedis客户端了)。虽然最新版的Redis Cluster集群架构不推荐读写分离,但是还是想玩玩。文末提供源码
参考自:
  • Redis 架构演变与 Redis-cluster 群集读写方案
  • Lettuce官方文档的ReadFrom Settings部分
二. 版本说明
技术栈 版本
SpringBoot 2.3.7
Redis集群 Redis是5.0版本,推荐5.x以上版本,推荐集群架构是Redis Cluster(不是以前说的主从架构、哨兵集群。Redis Cluster已经集成了主从、哨兵,是最新版的Redis集群架构),如何搭建Redis Cluster可参考基于Docker搭建Redis集群
Docker 19.03.13
三. 前言
后面章节只会列出最核心的内容,如看不懂,可以先阅读SpringBoot整合Redis集群(Lettuce客户端),甚至可以阅读笔者写的Redis系列相关的文章。
四. 如何实现读写分离?
Lettuce客户端如何实现读写分离?去看看Lettuce官方文档的ReadFrom Settings部分的介绍,如下:
Redis|SpringBoot整合Redis集群读写分离(Lettuce客户端)
文章图片

解释:
  • 流程大概就是先获取到集群的节点
  • 然后创建集群客户端
  • 然后创建连接
  • 拿到连接,往连接里面设置ReadFrom.REPLICA
  • 最后拿到命令行对象,通过命令行对象调用它提供的API与Redis交互
  • 其实核心的代码就是connection.setReadFrom(ReadFrom.REPLICA)
五. 动手实现读写分离
使用SpringBoot整合Lettuce客户端实现Redis集群的读写分离
5.1 整合Lettuce
加入依赖
org.springframework.boot spring-boot-starter-data-redis org.apache.commons commons-pool2 2.9.0

配置文件
spring: redis: database: 0 cluster: timeout: 1000 max-redirects: 3 nodes: 192.168.199.130:6379,192.168.199.130:6380,192.168.199.130:6381,192.168.199.130:6382,192.168.199.130:6383,192.168.199.130:6384 lettuce: pool: max-idle: 10 # 连接池中的最大空闲连接 max-wait: 500 # 连接池最大阻塞等待时间(使用负值表示没有限制) max-active: 8 # 连接池最大连接数(使用负值表示没有限制) min-idle: 0 # 连接池中的最小空闲连接

解释:spring.redis.cluster.nodes的值就是redis集群各个节点所在的ip地址以及端口
5.1 向Spring注册连接组件
其实就是获取到Redis的连接
/** * @Author Androidla * @Date 2021/2/14 13:40 * @Description **/ @Configuration @Slf4j public class RedisConfig {@Value("${spring.redis.cluster.nodes}") private String CLUSTER_NODES; @Bean public StatefulRedisClusterConnection statefulRedisClusterConnection() { String[] clusterNodes = CLUSTER_NODES.split(","); ArrayList redisURISList = new ArrayList<>(); for (String node : clusterNodes) { String[] ipAndPort = node.split(":"); redisURISList.add(new RedisURI(ipAndPort[0], Integer.parseInt(ipAndPort[1]), Duration.ofDays(10))); // Duration.ofDays(10)随便设置,关系不大 } RedisClusterClient redisClusterClient = RedisClusterClient.create(redisURISList); StatefulRedisClusterConnection, String> connection = redisClusterClient.connect(); connection.setReadFrom(ReadFrom.REPLICA); return connection; } }

上面的代码块中最核心的就是下面这三行:
RedisClusterClient redisClusterClient = RedisClusterClient.create(redisURISList); StatefulRedisClusterConnection, String> connection = redisClusterClient.connect(); connection.setReadFrom(ReadFrom.REPLICA);

5.2 测试
可以自行创建一套controller到service的业务代码,然后用postman发送请求试试。下面给出核心的测试代码:
public void readFromReplica() { String key = "10010"; log.info("read from replica..."); log.info("connection class is: {}", connection.getClass()); RedisAdvancedClusterCommands sync = connection.sync(); sync.set(key, "中国联通"); Object value = https://www.it610.com/article/sync.get(key); log.info("value is: {}", value); // 官方文档上是有将connection以及client关闭掉的 //connection.close(); //client.close(); }

注意:官方文档给出的代码,最后是要将connection关闭、client关闭的,这里笔者只是演示读写分离,就不再做过多的优化了
【Redis|SpringBoot整合Redis集群读写分离(Lettuce客户端)】源码:前往Gitee下载源码

    推荐阅读