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

朱雀 2022-10-29 15:20 105阅读 0赞

在这里插入图片描述

文章目录

  • 一. 问题背景
  • 二. 版本说明
  • 三. 前言
  • 四. 如何实现读写分离?
  • 五. 动手实现读写分离
    • 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部分的介绍,如下:

在这里插入图片描述

解释:

  • 流程大概就是先获取到集群的节点
  • 然后创建集群客户端
  • 然后创建连接
  • 拿到连接,往连接里面设置ReadFrom.REPLICA
  • 最后拿到命令行对象,通过命令行对象调用它提供的API与Redis交互
  • 其实核心的代码就是connection.setReadFrom(ReadFrom.REPLICA)

五. 动手实现读写分离

使用SpringBoot整合Lettuce客户端实现Redis集群的读写分离

5.1 整合Lettuce

加入依赖

  1. <!-- SpringBoot 整合 Redis -->
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter-data-redis</artifactId>
  5. </dependency>
  6. <!-- lettuce pool 缓存连接池-->
  7. <dependency>
  8. <groupId>org.apache.commons</groupId>
  9. <artifactId>commons-pool2</artifactId>
  10. <version>2.9.0</version>
  11. </dependency>

配置文件

  1. spring:
  2. redis:
  3. database: 0
  4. cluster:
  5. timeout: 1000
  6. max-redirects: 3
  7. 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
  8. lettuce:
  9. pool:
  10. max-idle: 10 # 连接池中的最大空闲连接
  11. max-wait: 500 # 连接池最大阻塞等待时间(使用负值表示没有限制)
  12. max-active: 8 # 连接池最大连接数(使用负值表示没有限制)
  13. min-idle: 0 # 连接池中的最小空闲连接

解释:spring.redis.cluster.nodes的值就是redis集群各个节点所在的ip地址以及端口

5.1 向Spring注册连接组件

其实就是获取到Redis的连接

  1. /** * @Author Androidla * @Date 2021/2/14 13:40 * @Description **/
  2. @Configuration
  3. @Slf4j
  4. public class RedisConfig {
  5. @Value("${spring.redis.cluster.nodes}")
  6. private String CLUSTER_NODES;
  7. @Bean
  8. public StatefulRedisClusterConnection statefulRedisClusterConnection() {
  9. String[] clusterNodes = CLUSTER_NODES.split(",");
  10. ArrayList<RedisURI> redisURISList = new ArrayList<>();
  11. for (String node : clusterNodes) {
  12. String[] ipAndPort = node.split(":");
  13. redisURISList.add(new RedisURI(ipAndPort[0], Integer.parseInt(ipAndPort[1]),
  14. Duration.ofDays(10)));// Duration.ofDays(10)随便设置,关系不大
  15. }
  16. RedisClusterClient redisClusterClient = RedisClusterClient.create(redisURISList);
  17. StatefulRedisClusterConnection<String, String> connection = redisClusterClient.connect();
  18. connection.setReadFrom(ReadFrom.REPLICA);
  19. return connection;
  20. }
  21. }

上面的代码块中最核心的就是下面这三行:

  1. RedisClusterClient redisClusterClient = RedisClusterClient.create(redisURISList);
  2. StatefulRedisClusterConnection<String, String> connection = redisClusterClient.connect();
  3. connection.setReadFrom(ReadFrom.REPLICA);

5.2 测试

可以自行创建一套controller到service的业务代码,然后用postman发送请求试试。下面给出核心的测试代码

  1. public void readFromReplica() {
  2. String key = "10010";
  3. log.info("read from replica...");
  4. log.info("connection class is: {}", connection.getClass());
  5. RedisAdvancedClusterCommands sync = connection.sync();
  6. sync.set(key, "中国联通");
  7. Object value = sync.get(key);
  8. log.info("value is: {}", value);
  9. // 官方文档上是有将connection以及client关闭掉的
  10. //connection.close();
  11. //client.close();
  12. }

注意:官方文档给出的代码,最后是要将connection关闭、client关闭的,这里笔者只是演示读写分离,就不再做过多的优化了

源码:前往Gitee下载源码

发表评论

表情:
评论列表 (有 0 条评论,105人围观)

还没有评论,来说两句吧...

相关阅读