Redis 集群提供高可用性和分布式存储能力,适用于大规模应用场景。在 Spring Boot 2 中集成 Redis 集群,可以通过 Spring Data Redis 实现高效的数据操作。以下是详细步骤,从环境准备到代码实现,确保结构清晰、易于操作。本指南基于 Spring Boot 2.x 版本(如 2.7.x)和 Redis 6.x 集群。
1. 前提条件
- 确保已安装并运行 Redis 集群(至少 3 个主节点和 3 个从节点,推荐使用 Redis 6+)。
- 创建 Spring Boot 2 项目(使用 Spring Initializr 或 IDE 如 IntelliJ IDEA)。
- 环境要求:
- Java 8+
- Maven 或 Gradle(本指南以 Maven 为例)
- Redis 集群节点信息(如节点地址:
192.168.1.101:6379
,192.168.1.102:6379
,192.168.1.103:6379
)
2. 添加依赖
在项目的 pom.xml
文件中添加 Spring Boot Starter Data Redis 依赖。这将自动引入 Redis 客户端(如 Lettuce,默认支持集群)。
<dependencies>
<!-- Spring Boot Starter Web (可选,但推荐用于完整项目) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Data Redis 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- 连接池支持(推荐,提高性能) -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
</dependencies>
3. 配置 Redis 集群
在 application.properties
或 application.yml
中配置 Redis 集群节点、密码(如有)和连接池。以下是 application.yml
示例(更易读):
spring:
redis:
cluster:
nodes: # 集群节点列表,格式为 host:port
- 192.168.1.101:6379
- 192.168.1.102:6380
- 192.168.1.103:6381
- 192.168.1.104:6382
- 192.168.1.105:6383
- 192.168.1.106:6384
max-redirects: 3 # 最大重定向次数,处理节点故障
password: your-redis-password # 如果 Redis 设置了密码
lettuce:
pool:
max-active: 8 # 最大连接数
max-idle: 8 # 最大空闲连接
min-idle: 0 # 最小空闲连接
max-wait: -1 # 最大等待时间(毫秒),-1 表示无限等待
- 关键参数说明:
nodes
: 指定所有集群节点地址。Spring Boot 会自动发现集群拓扑。max-redirects
: 当请求重定向到其他节点时,允许的最大重试次数(推荐 3-5)。password
: 如果 Redis 集群启用了认证,必须设置此参数。lettuce.pool
: 配置连接池优化性能(避免频繁创建连接)。
4. 代码实现:使用 RedisTemplate
Spring Boot 自动配置 RedisTemplate
,但需自定义以支持集群操作。创建一个配置类,并注入 RedisTemplate
bean。
步骤 4.1: 创建配置类 在 src/main/java/com/example/demo/config
目录下创建 RedisConfig.java
:
package com.example.demo.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisClusterConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig {
@Bean
public LettuceConnectionFactory redisConnectionFactory() {
// 自动从 application.yml 加载集群配置
return new LettuceConnectionFactory(new RedisClusterConfiguration());
}
@Bean
public RedisTemplate<String, Object> redisTemplate() {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory());
// 设置序列化器:避免乱码
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
template.afterPropertiesSet(); // 初始化
return template;
}
}
- 说明:
LettuceConnectionFactory
: 使用 Lettuce 客户端,支持异步和集群。RedisTemplate
: 泛型设置为<String, Object>
,方便存储各种数据类型。- 序列化器:推荐
StringRedisSerializer
和GenericJackson2JsonRedisSerializer
,确保键值对可读。
步骤 4.2: 创建服务类操作 Redis 在 src/main/java/com/example/demo/service
目录下创建 RedisService.java
:
package com.example.demo.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
@Service
public class RedisService {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
// 存储数据
public void set(String key, Object value) {
redisTemplate.opsForValue().set(key, value);
}
// 获取数据
public Object get(String key) {
return redisTemplate.opsForValue().get(key);
}
// 删除数据
public Boolean delete(String key) {
return redisTemplate.delete(key);
}
// 示例:存储哈希表
public void setHash(String key, String field, Object value) {
redisTemplate.opsForHash().put(key, field, value);
}
public Object getHash(String key, String field) {
return redisTemplate.opsForHash().get(key, field);
}
}
步骤 4.3: 在控制器中测试 在 src/main/java/com/example/demo/controller
目录下创建 RedisController.java
:
package com.example.demo.controller;
import com.example.demo.service.RedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/redis")
public class RedisController {
@Autowired
private RedisService redisService;
@GetMapping("/set")
public String setValue() {
redisService.set("testKey", "Hello Redis Cluster!");
return "Value set successfully";
}
@GetMapping("/get")
public Object getValue() {
return redisService.get("testKey");
}
@GetMapping("/hash")
public String setHash() {
redisService.setHash("user:1", "name", "Alice");
return "Hash set successfully";
}
}
5. 测试 Redis 集群集成
- 启动应用:运行 Spring Boot 主类(如
DemoApplication.java
),确保控制台无错误。 - 测试 API:
- 访问
http://localhost:8080/redis/set
设置数据。 - 访问
http://localhost:8080/redis/get
获取数据,应返回 "Hello Redis Cluster!"。 - 访问
http://localhost:8080/redis/hash
设置哈希表。
- 访问
- 验证集群:
- 登录 Redis 任意节点,使用
redis-cli -c -h 192.168.1.101 -p 6379
命令。 - 执行
GET testKey
或HGET user:1 name
,检查数据是否一致。
- 登录 Redis 任意节点,使用
- 故障测试:手动关闭一个 Redis 节点,Spring Boot 应自动重连到其他节点(查看日志确认)。
6. 常见问题与优化
- 问题 1: 连接超时或节点不可达
- 原因:网络问题或节点配置错误。
- 解决:检查
application.yml
中的节点地址是否准确,确保防火墙开放端口。
- 问题 2: 序列化错误(乱码)
- 原因:未配置序列化器。
- 解决:在
RedisConfig
中必须设置序列化器(如代码所示)。
- 问题 3: 性能瓶颈
- 优化:增加连接池大小(如
max-active: 16
),或使用@Cacheable
注解集成 Spring Cache。
- 优化:增加连接池大小(如
- 安全建议:
- 启用 Redis 密码认证。
- 在生产环境中使用 SSL/TLS 加密连接(配置
spring.redis.ssl=true
)。
总结
通过以上步骤,您已成功在 Spring Boot 2 中集成 Redis 集群。关键点包括正确配置集群节点、使用 LettuceConnectionFactory
处理连接、以及自定义 RedisTemplate
确保序列化。Redis 集群自动处理数据分片和故障转移,提升了应用的可靠性和扩展性。如果有更多需求(如事务处理或 pub/sub),可扩展 RedisService
类。建议参考 Spring Data Redis 文档 进一步优化。