Redis集群配置
Windows 下搭建 Redis 7.4.0 单机伪集群实战(linux基本也一样,改配置和启动)
最近在本机测试 Redis 集群功能时,我没有单独准备多台机器,而是直接在 Windows 上通过多个 Redis 实例,搭了一个 3 主 3 从 的单机伪集群。整个过程适合本地学习、接口联调和集群命令验证,记录一下,方便后面自己查,也给有同样需求的同学一个参考。
需要先说明一点:本文场景是 Windows 本地开发和学习验证,并不适合生产环境。真正线上部署,还是建议按 Redis 官方建议使用 Linux。
一、我的环境说明
这次使用的是 Windows 版 Redis 7.4.0,目录里可以看到一个基础安装包目录,以及 6 个用于集群的实例目录:
Redis-7.4.0-Windows-x64-cygwin-with-ServiceRedis-7.4.0-8001Redis-7.4.0-8002Redis-7.4.0-8003Redis-7.4.0-8004Redis-7.4.0-8005Redis-7.4.0-8006
其中:
Redis-7.4.0-Windows-x64-cygwin-with-Service可以理解为原始 Redis Windows 版本目录Redis-7.4.0-8001到Redis-7.4.0-8006是我复制出来的 6 个实例目录- 每个目录对应一个 Redis 节点
- 最终组成一个
3 主 3 从的集群
二、为什么要用 6 个目录
Redis Cluster 至少需要 3 个主节点,才能完成槽位分片和基本的高可用验证。
如果还希望每个主节点再挂一个从节点,那么最常见的实验结构就是:
- 8001:主节点
- 8002:主节点
- 8003:主节点
- 8004:从节点
- 8005:从节点
- 8006:从节点
这样正好构成:
- 3 个 master
- 3 个 slave
对应的好处是:
- 可以验证哈希槽分配
- 可以测试主从关系
- 可以测试故障切换
- 可以模拟更接近真实集群的运行方式
三、单个 Redis 节点需要改哪些配置
每个实例目录里,我都保留了独立的 redis.conf。不同节点最核心的区别,主要是下面几项:
port 8001
bind 127.0.0.1 -::1 #对应自己的主机ip
protected-mode yes
appendonly yes
cluster-enabled yes
cluster-config-file nodes-8001.conf
cluster-node-timeout 5000
上面这些配置里,需要重点关注以下几个参数:
1. port
每个节点端口必须不同,比如:
- 8001
- 8002
- 8003
- 8004
- 8005
- 8006
2. cluster-enabled yes
开启集群模式。如果不开这个,节点只能按单机 Redis 启动,无法参与 Redis Cluster。
3. cluster-config-file
每个节点都要有自己独立的集群配置文件,例如:
nodes-8001.confnodes-8002.confnodes-8003.conf
这个文件会在集群创建后自动写入节点关系、槽位信息和主从拓扑。
4. appendonly yes
我这里顺手也开启了 AOF 持久化,目录下会自动生成 appendonlydir,便于本地实验时保留数据。
5. bind 127.0.0.1 -::1
我的场景是本机测试,所以 Redis 只监听本地回环地址,更安全一些。
四、如何启动这 6 个 Redis 实例
每个目录里都有一个 start.bat,内容非常简单:
@echo off
cd /d %~dp0
redis-server.exe redis.conf
pause
它的作用就是:
- 切换到当前目录
- 使用当前目录下的
redis.conf启动 Redis
因此我的启动方式很直接:
- 分别进入
Redis-7.4.0-8001到Redis-7.4.0-8006 - 每个目录执行一次
start.bat - 保持 6 个窗口都不要关闭
如果你喜欢命令行,也可以直接执行:
redis-server.exe redis.conf
五、创建 Redis 集群
当 6 个实例都启动完成后,就可以进入任意一个 Redis 目录,执行集群创建命令。
我实际使用的命令如下:
redis-cli --cluster create 127.0.0.1:8001 127.0.0.1:8002 127.0.0.1:8003 127.0.0.1:8004 127.0.0.1:8005 127.0.0.1:8006 --cluster-replicas 1
这条命令的含义是:
- 使用 6 个节点创建一个 Redis 集群
--cluster-replicas 1表示每个主节点分配 1 个从节点(主/从比例)
执行后,Redis 会自动完成:
- 3 个 master 的槽位分配
- 3 个 slave 的主从绑定
- 集群元数据写入各自的
nodes-xxxx.conf
从命令输出可以看到,Redis 会先做哈希槽分配,再自动关联主从关系。
从输出结果里,可以看到集群大致分配为:
8001负责槽位0-54608002负责槽位5461-109228003负责槽位10923-163838004、8005、8006分别作为从节点挂到不同主节点上
六、确认集群是否创建成功
创建过程中,Redis 会做一次 Cluster Check。
如果你看到类似下面的信息,说明集群已经正常建立:
[OK] All nodes agree about slots configuration.
[OK] All 16384 slots covered.
这两句非常关键:
All nodes agree about slots configuration:说明所有节点对槽位配置认知一致All 16384 slots covered:说明 Redis Cluster 的 16384 个槽位已经全部被分配完成
另外,从某个节点目录里的 nodes-8001.conf 也能看到当前集群拓扑已经写入成功,例如:
- 3 个 master
- 3 个 slave
- 各主节点各自负责一段槽位
这说明集群已经不是“临时内存状态”,而是已经持久化了节点关系。
七、这套目录结构背后做了什么
从我当前目录来看,这套单机伪集群本质上做了三件事:
1. 复制出多个 Redis 实例
通过复制 Redis 安装目录,得到 6 份彼此独立的运行目录。
2. 修改不同实例的配置
每个实例使用不同端口、不同 cluster-config-file,这样它们才能作为不同节点加入同一个集群。
3. 用 redis-cli --cluster create 自动组装
Redis 官方自带的 cluster 工具会自动完成:
- master 选举初始化
- slave 分配
- 槽位切分
- 节点间
MEET
整个过程比手动 cluster meet 一台台组装要省事很多。
八、踩坑提醒
这部分是我觉得最容易出问题的地方。
1. 不同节点端口一定不能重复
如果 6 个目录里有两个节点写了同一个端口,启动时一定会冲突。
2. cluster-config-file 不能写成同一个文件名
比如 8001 和 8002 都写成 nodes.conf,虽然不一定立刻报错,但非常容易把节点信息搞乱。最稳妥的方式就是像我这样一一对应:
- 8001 对应
nodes-8001.conf - 8002 对应
nodes-8002.conf - 8003 对应
nodes-8003.conf
3. 6 个实例必须先全部启动
如果有节点没启动,执行 redis-cli --cluster create 时会直接失败,或者建出来的拓扑不完整。
4. Windows 版本适合学习,不建议生产使用
我当前使用的这个 Windows 版本目录里,README 也明确说明了更适合本地开发测试场景。线上环境还是建议部署在 Linux。
九、简单验证一下集群是否可用
集群建好以后,可以先连某个节点试试:
redis-cli -p 8001
然后查看集群信息:
cluster info
cluster nodes
如果想在集群模式下写入 key,建议使用:
redis-cli -c -h 127.0.0.1 -p 8001
这里的 -c 很重要,它表示启用集群模式重定向。否则当 key 落到其他槽位时,客户端不会自动跳转。
你可以简单测试:
set name redis-cluster
get name
十、Spring Boot 整合 Redis Cluster
上面集群已经搭好了,接下来就是项目里怎么接。
如果你的项目是 Spring Boot,整合 Redis Cluster 最常见的方式就是:
- 使用
spring-boot-starter-data-redis - 底层客户端使用 Lettuce
- 在
application.yml里直接配置集群节点
对于日常业务项目来说,这套方式已经够用了。
十一、引入依赖
如果你使用 Maven,可以先引入 Redis 的 Starter:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
一般情况下,Spring Boot 会自动带上 Lettuce,所以大多数项目不需要再单独引入 Jedis。
十二、配置 application.yml
因为我本地这个集群使用的是 8001-8006 这 6 个端口,所以在 Spring Boot 里可以直接这样配。
如果你用的是 Spring Boot 3.x,可以写成:
spring:
data:
redis:
timeout: 5000ms
connect-timeout: 5000ms
lettuce:
pool:
max-active: 16
max-idle: 8
min-idle: 2
max-wait: 3000ms
cluster:
nodes:
- 127.0.0.1:8001
- 127.0.0.1:8002
- 127.0.0.1:8003
- 127.0.0.1:8004
- 127.0.0.1:8005
- 127.0.0.1:8006
max-redirects: 3
如果你项目还是 Spring Boot 2.x,很多场景下配置前缀还是:
spring:
redis:
cluster:
nodes:
- 127.0.0.1:8001
- 127.0.0.1:8002
- 127.0.0.1:8003
- 127.0.0.1:8004
- 127.0.0.1:8005
- 127.0.0.1:8006
这里几个点需要注意:
cluster.nodes写的是集群节点地址,不需要只写 master,通常把可连接节点都配上更稳妥max-redirects表示发生槽位跳转时,客户端最多重定向多少次- 本地开发可以先写
127.0.0.1,如果后面部署到服务器,就换成真实节点 IP
十三、配置一个更顺手的 RedisTemplate
默认的 RedisTemplate 可用,但序列化结果不够友好。实际项目里我更建议自己配一下序列化方式,至少把 key 和 value 处理清楚。
可以新建一个配置类:
package com.example.demo.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
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 RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(connectionFactory);
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
GenericJackson2JsonRedisSerializer jsonRedisSerializer =
new GenericJackson2JsonRedisSerializer();
redisTemplate.setKeySerializer(stringRedisSerializer);
redisTemplate.setHashKeySerializer(stringRedisSerializer);
redisTemplate.setValueSerializer(jsonRedisSerializer);
redisTemplate.setHashValueSerializer(jsonRedisSerializer);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
}
这样处理后:
- key 会按字符串存储
- value 会按 JSON 序列化
- 在排查 Redis 数据时比默认二进制结果更直观
如果你项目里只存简单字符串,也可以直接用 StringRedisTemplate。
十四、写一个简单测试接口
下面给一个最小可运行示例,方便验证 Spring Boot 是否真的连上了集群。
1. Service
package com.example.demo.service;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
@Service
public class RedisClusterService {
private final StringRedisTemplate stringRedisTemplate;
public RedisClusterService(StringRedisTemplate stringRedisTemplate) {
this.stringRedisTemplate = stringRedisTemplate;
}
public void set(String key, String value) {
stringRedisTemplate.opsForValue().set(key, value);
}
public String get(String key) {
return stringRedisTemplate.opsForValue().get(key);
}
}
2. Controller
package com.example.demo.controller;
import com.example.demo.service.RedisClusterService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/redis")
public class RedisClusterController {
private final RedisClusterService redisClusterService;
public RedisClusterController(RedisClusterService redisClusterService) {
this.redisClusterService = redisClusterService;
}
@GetMapping("/set")
public String set(@RequestParam String key, @RequestParam String value) {
redisClusterService.set(key, value);
return "ok";
}
@GetMapping("/get")
public String get(@RequestParam String key) {
return redisClusterService.get(key);
}
}
3. 测试方式
项目启动后,可以直接访问:
http://localhost:8080/redis/set?key=name&value=redis-cluster
http://localhost:8080/redis/get?key=name
如果能够正常写入和读取,说明 Spring Boot 已经成功接入 Redis Cluster。
十五、Spring Boot 连接集群时的几个坑
这部分非常实用,建议一定要写进文章里,不然后面读者复制代码后很容易卡住。
1. Redis Cluster 默认只支持 db 0
很多人以前用单机 Redis 时,会写这种配置:
spring:
data:
redis:
database: 1
但是在 Redis Cluster 里,逻辑数据库切换并不支持,默认只能使用 0 号库。所以如果你之前项目里有 database: 1、database: 2 这种配置,接入集群后要去掉。
2. 多 key 操作不一定都能直接用
Redis Cluster 是按槽位分片的,不同 key 可能落在不同节点上。所以像下面这类操作:
mgetmset- Lua 脚本里同时操作多个 key
- 事务里同时操作多个分散 key
如果 key 不在同一个槽位,就可能报错。
如果业务上必须让多个 key 落到同一槽位,可以使用 hash tag,例如:
order:{1001}:info
order:{1001}:status
花括号里的内容相同,这两个 key 就会被路由到同一个槽位。
3. 本地单机伪集群没问题,不代表服务器部署也没问题
我这篇文章里的环境是:
- 所有节点都在同一台机器
- 地址都是
127.0.0.1
这只适合本地开发验证。
如果后面把 Redis Cluster 部署到服务器上,还要额外关注:
- 节点真实 IP 是否可达
- 集群总线端口是否放行
- 防火墙是否拦截
- 应用服务器是否能访问到所有节点
4. 不要把单机 Redis 的使用习惯原封不动搬到集群
比如有些老项目会:
- 随意切库
- 大量使用跨 key 批量操作
- 对 Lua 脚本中的 key 设计比较随意
这些在单机模式下问题不大,但到了集群模式就需要重新审视 key 设计。
十六、总结
这篇文章从 Windows 下搭建 Redis 7.4.0 单机伪集群,一直写到了 Spring Boot 接入,基本把本地联调这条链路串起来了。
前半部分解决的是 Redis 集群怎么搭,后半部分解决的是 Java 项目怎么连。整体思路并不复杂,核心还是三步:
- 准备 6 个独立 Redis 实例目录
- 修改每个实例的
redis.conf - 使用
redis-cli --cluster create完成集群创建
最终得到的是一套 3 主 3 从 的本地 Redis Cluster 环境,并且还能直接接到 Spring Boot 项目里,足够用于:
- 本地学习 Redis 集群原理
- 测试集群读写
- 验证槽位分配
- 模拟主从结构和故障切换
- 验证 Spring Boot 对 Redis Cluster 的接入方式
如果你也只是想在 Windows 本机快速体验 Redis 集群,这种方式确实很直接、很实用。
附:本文用到的核心命令
启动单个节点
redis-server.exe redis.conf
创建集群
redis-cli --cluster create 127.0.0.1:8001 127.0.0.1:8002 127.0.0.1:8003 127.0.0.1:8004 127.0.0.1:8005 127.0.0.1:8006 --cluster-replicas 1
连接集群节点
redis-cli -c -p 8001
查看集群信息
cluster info
cluster nodes
如果你后面还想继续折腾,也可以在这套环境上继续测试:
- 主节点下线后的故障转移
- 槽位迁移
MOVED与ASK重定向- Spring Boot 连接 Redis Cluster 的配置方式
这篇先记录到这里。






浙公网安备 33010602011771号