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-Service
  • Redis-7.4.0-8001
  • Redis-7.4.0-8002
  • Redis-7.4.0-8003
  • Redis-7.4.0-8004
  • Redis-7.4.0-8005
  • Redis-7.4.0-8006

其中:

  • Redis-7.4.0-Windows-x64-cygwin-with-Service 可以理解为原始 Redis Windows 版本目录
  • Redis-7.4.0-8001Redis-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.conf
  • nodes-8002.conf
  • nodes-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

因此我的启动方式很直接:

  1. 分别进入 Redis-7.4.0-8001Redis-7.4.0-8006
  2. 每个目录执行一次 start.bat
  3. 保持 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-5460
  • 8002 负责槽位 5461-10922
  • 8003 负责槽位 10923-16383
  • 800480058006 分别作为从节点挂到不同主节点上

六、确认集群是否创建成功

创建过程中,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

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: 1database: 2 这种配置,接入集群后要去掉。

2. 多 key 操作不一定都能直接用

Redis Cluster 是按槽位分片的,不同 key 可能落在不同节点上。所以像下面这类操作:

  • mget
  • mset
  • 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 项目怎么连。整体思路并不复杂,核心还是三步:

  1. 准备 6 个独立 Redis 实例目录
  2. 修改每个实例的 redis.conf
  3. 使用 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

如果你后面还想继续折腾,也可以在这套环境上继续测试:

  • 主节点下线后的故障转移
  • 槽位迁移
  • MOVEDASK 重定向
  • Spring Boot 连接 Redis Cluster 的配置方式

这篇先记录到这里。

posted @ 2026-05-16 18:37  zouyua  阅读(83)  评论(0)    收藏  举报