跳到主要内容Redis Cluster 核心原理与 3 主 3 从集群搭建实战 | 极客日志Shell / Bash
Redis Cluster 核心原理与 3 主 3 从集群搭建实战
综述由AI生成Redis Cluster 通过 16384 个哈希槽实现数据分片,结合 Gossip 协议进行节点通信。解析了 MOVED 与 ASK 重定向机制,并演示了在 Linux 环境下搭建 3 主 3 从集群的完整流程,涵盖配置、启动、扩容及缩容操作,帮助解决高可用部署中的常见问题。
霸天1 浏览 
随着业务流量增长,单节点 Redis 早已无法满足高可用、高并发需求,集群化部署成为必然选择。Redis Cluster 作为官方推荐的集群方案,核心靠哈希槽分片实现数据分布式存储,搭配 Gossip 协议保障节点通信,再通过 MOVED/ASK 重定向解决数据路由问题。本文将从核心原理入手,演示在 Linux 环境下搭建 3 主 3 从 Redis Cluster 集群,结合 redis-cli --cluster 命令实操,适合初学者参考。
一、Redis Cluster 核心原理剖析
1.1 哈希槽(Hash Slot)分片机制
Redis Cluster 将数据分片存储在不同节点,核心载体是16384 个哈希槽(0-16383),这个数量是基于集群灵活性与性能的权衡结果(过多槽位会增加节点通信开销,过少则分片粒度不足)。
核心规则:
- 每个 Redis 集群节点会负责一部分连续的哈希槽(比如节点 1 负责 0-5460,节点 2 负责 5461-10922,节点 3 负责 10923-16383)。
- 数据存储时,Redis 会对 key 执行
CRC16(key) % 16384 计算,得到对应的哈希槽,再将数据路由到负责该槽位的节点。
这种机制让数据分布更均匀,后续集群扩容或缩容时,只需迁移槽位对应的数据集,无需修改客户端配置。
1.2 集群节点通信:Gossip 协议
Redis Cluster 节点之间通过 Gossip(流言)协议实现信息同步,无需依赖中心节点,去中心化设计提升集群可用性。
核心特性:
- 节点会定期(默认 1 秒)向随机选择的几个节点发送 Gossip 消息,包含自身状态、集群拓扑、槽位分配等信息。
- 消息类型主要有:ping(节点心跳检测 + 信息同步)、pong(响应 ping 消息,同时同步自身信息)、meet(新增节点时,邀请其加入集群)、fail(标记节点故障)。
- 优点:去中心化,节点故障时无需全局广播,降低通信压力;缺点:信息同步有延迟,集群规模过大(超过 100 个节点)时延迟会加剧。
1.3 MOVED 重定向与 ASK 重定向
客户端访问 Redis Cluster 时,可能会遇到数据不在当前连接节点的情况,此时会通过 MOVED 或 ASK 重定向获取正确节点地址,两者适用场景不同:
1.3.1 MOVED 重定向(永久重定向)
- 场景:哈希槽已明确分配给目标节点,客户端后续请求需直接连接目标节点。
- 流程:客户端连接节点 A 请求 key,节点 A 发现 key 对应的槽位已分配给节点 B,返回
MOVED 槽位 节点 BIP:端口,客户端收到后,后续请求直接转向节点 B。
1.3.2 ASK 重定向(临时重定向)
- 场景:哈希槽正在迁移(扩容/缩容过程中),部分数据在原节点,部分在目标节点。
- 流程:客户端连接节点 A 请求 key,节点 A 发现 key 对应的槽位正在迁移到节点 B,返回
ASK 槽位 节点 BIP:端口,客户端需先向节点 B 发送 ASKING 命令,再执行原请求(仅本次有效,后续请求仍需按槽位路由)。
二、Linux 环境 3 主 3 从集群搭建实操
2.1 搭建前准备
2.1.1 环境说明
- 操作系统:CentOS 7.x(Ubuntu 同理,命令略有差异)
- Redis 版本:6.2.7(推荐稳定版,避免使用过旧版本)
节点规划:6 个 Redis 节点(3 主 3 从),部署在同一台 Linux 服务器(实际生产环境建议部署在不同服务器,这里为演示方便单台部署,通过不同端口区分)
| 节点角色 | 端口 | 配置文件路径 | 数据存储路径 |
|---|
| 主节点 1 | 7001 | /etc/redis/7001.conf | /var/redis/7001 |
| 主节点 2 | 7002 | /etc/redis/7002.conf | /var/redis/7002 |
| 主节点 3 | 7003 | /etc/redis/7003.conf | /var/redis/7003 |
| 从节点 1 | 7004 | /etc/redis/7004.conf | /var/redis/7004 |
| 从节点 2 | 7005 | /etc/redis/7005.conf | /var/redis/7005 |
| 从节点 3 | 7006 | /etc/redis/7006.conf | /var/redis/7006 |
2.1.2 依赖安装与 Redis 下载
yum install -y gcc gcc-c++ make
wget https://download.redis.io/releases/redis-6.2.7.tar.gz
tar -zxvf redis-6.2.7.tar.gz -C /usr/local/
cd /usr/local/redis-6.2.7/
make && make install PREFIX=/usr/local/redis
2.2 配置节点配置文件
2.2.1 创建目录(统一管理配置、数据、日志)
mkdir -p /etc/redis
mkdir -p /var/redis/{7001,7002,7003,7004,7005,7006}
mkdir -p /var/log/redis
2.2.2 编写基础配置文件模板
以 7001 端口(主节点 1)为例,创建 /etc/redis/7001.conf,内容如下:
# 端口号
port 7001
# 绑定 IP(生产环境建议绑定内网 IP,这里允许所有 IP 访问)
bind 0.0.0.0
# 开启集群模式
cluster-enabled yes
# 集群配置文件(自动生成,无需手动修改)
cluster-config-file nodes-7001.conf
# 集群节点超时时间(毫秒,超过该时间视为节点故障)
cluster-node-timeout 15000
# 数据存储目录
dir /var/redis/7001
# 日志文件路径
logfile /var/log/redis/7001.log
# 后台运行
daemonize yes
# 允许跨网段访问(如果集群节点在不同网段)
protected-mode no
# 开启 AOF 持久化(可选,根据需求配置)
appendonly yes
appendfilename "appendonly-7001.aof"
# 禁用 protected-mode(避免外部无法访问)
protected-mode no
2.2.3 复制配置文件到其他节点并修改
将 7001.conf 复制到其他 5 个节点的配置文件路径,然后批量修改端口号、目录等关键信息:
for port in {7002..7006}; do
cp /etc/redis/7001.conf /etc/redis/$port.conf
sed -i "s/7001/$port/g" /etc/redis/$port.conf
done
2.3 启动所有 Redis 节点
for port in {7001..7006}; do
/usr/local/redis/bin/redis-server /etc/redis/$port.conf
done
ps -ef | grep redis-server | grep -v grep
正常情况下,会显示 6 个 redis-server 进程,分别对应 7001-7006 端口。
2.4 用 redis-cli --cluster 创建集群
Redis 5.0+ 版本提供了 redis-cli --cluster 命令(原 redis-trib.rb 工具的替代方案),可快速创建集群。
2.4.1 执行创建命令
/usr/local/redis/bin/redis-cli --cluster create \
127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 \
127.0.0.1:7004 127.0.0.1:7005 127.0.0.1:7006 \
--cluster-replicas 1
--cluster-replicas 1:表示每个主节点对应 1 个从节点,6 个节点会自动分配为 3 主 3 从。
2.4.2 确认集群创建
执行命令后,会显示哈希槽分配方案(默认 3 个主节点平均分配 16384 个槽位),输入 yes 确认:
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0-5460
Master[1] -> Slots 5461-10922
Master[2] -> Slots 10923-16383
Adding replica 127.0.0.1:7004 to 127.0.0.1:7001
Adding replica 127.0.0.1:7005 to 127.0.0.1:7002
Adding replica 127.0.0.1:7006 to 127.0.0.1:7003
>>> Trying to optimize slaves allocation for anti-affinity
[WARNING] Some slaves are in the same host as their master
M: 0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b 127.0.0.1:7001 slots:[0-5460] (5461 slots) master
M: 1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b 127.0.0.1:7002 slots:[5461-10922] (5462 slots) master
M: 2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b 127.0.0.1:7003 slots:[10923-16383] (5461 slots) master
S: 3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b 127.0.0.1:7004 replicates 0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b
S: 4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b 127.0.0.1:7005 replicates 1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b
S: 5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b 127.0.0.1:7006 replicates 2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b
Can I set the above configuration? (type
2.4.3 验证集群状态
- 连接集群(通过任意节点连接,
-c 表示启用集群模式)
/usr/local/redis/bin/redis-cli -c -h 127.0.0.1 -p 7001
127.0.0.1:7001> cluster info
cluster_state:ok
class_slots_assigned:16384
class_slots_ok:16384
class_slots_pfail:0
class_slots_fail:0
class_known_nodes:6
class_size:3
class_current_epoch:6
class_my_epoch:1
class_stats_messages_ping_sent:102
class_stats_messages_pong_sent:98
class_stats_messages_meet_sent:3
class_stats_messages_sent:203
class_stats_messages_ping_received:93
class_stats_messages_pong_received:105
class_stats_messages_meet_received:0
class_stats_messages_received:198
127.0.0.1:7001> cluster nodes
至此,Linux 环境下 3 主 3 从 Redis Cluster 集群搭建完成。
三、集群扩容与缩容实操
3.1 集群扩容(新增 1 主 1 从节点)
3.1.1 新增节点准备
新增两个节点(7007 主节点、7008 从节点),创建配置文件并启动:
cp /etc/redis/7001.conf /etc/redis/7007.conf
cp /etc/redis/7001.conf /etc/redis/7008.conf
sed -i "s/7001/7007/g" /etc/redis/7007.conf
sed -i "s/7001/7008/g" /etc/redis/7008.conf
/usr/local/redis/bin/redis-server /etc/redis/7007.conf
/usr/local/redis/bin/redis-server /etc/redis/7008.conf
3.1.2 新增主节点到集群
/usr/local/redis/bin/redis-cli --cluster add-node 127.0.0.1:7007 127.0.0.1:7001
3.1.3 迁移哈希槽到新主节点
/usr/local/redis/bin/redis-cli --cluster reshard 127.0.0.1:7001
- 输入需要迁移的槽位数量(比如迁移 1000 个槽位);
- 输入目标主节点 ID(7007 节点的 ID,可通过 cluster nodes 查看);
- 输入源节点 ID(需要从哪些主节点迁移槽位,输入多个后按 done 结束);
- 确认迁移计划,输入 yes 执行。
3.1.4 新增从节点并关联主节点
/usr/local/redis/bin/redis-cli --cluster add-node 127.0.0.1:7008 127.0.0.1:7001 --cluster-slave --cluster-master-id 7007 节点 ID
3.2 集群缩容(移除 1 主 1 从节点)
3.2.1 迁移待移除主节点的槽位
将 7007 主节点的槽位迁移到其他主节点(步骤同扩容迁移,只是目标节点为其他主节点):
/usr/local/redis/bin/redis-cli --cluster reshard 127.0.0.1:7001
注意:必须将待移除主节点的所有槽位迁移完成,才能移除该节点。
3.2.2 移除从节点(7008)
/usr/local/redis/bin/redis-cli --cluster del-node 127.0.0.1:7008 7008 节点 ID
3.2.3 移除主节点(7007)
/usr/local/redis/bin/redis-cli --cluster del-node 127.0.0.1:7007 7007 节点 ID
3.2.4 停止节点进程
/usr/local/redis/bin/redis-cli -p 7007 shutdown
/usr/local/redis/bin/redis-cli -p 7008 shutdown
四、常见问题排查
4.1 集群启动后 cluster_state:fail
- 原因 1:部分节点未启动,或节点间网络不通(防火墙拦截端口);
- 原因 2:节点超时时间设置过短,调整
cluster-node-timeout 为 30000(30 秒);
- 解决:修改所有节点配置文件,重启节点。
检查所有节点进程,关闭防火墙(或开放 7001-7006 端口):
systemctl stop firewalld
systemctl disable firewalld
4.2 客户端连接集群提示 MOVED 但无法重定向
- 原因:客户端未启用集群模式(连接时未加
-c 参数);
- 解决:连接集群时添加
-c 参数,如:redis-cli -c -h 127.0.0.1 -p 7001。
4.3 槽位迁移失败
- 原因:目标节点或源节点状态异常,或槽位已被占用;
- 解决:检查节点状态(
cluster info),确保节点正常,重新执行迁移命令。
五、总结
本文详细讲解了 Redis Cluster 集群的核心原理(哈希槽分片、Gossip 协议、重定向机制),并结合 Linux 环境完成了 3 主 3 从集群的搭建实操,同时演示了集群扩容/缩容的完整流程。Redis Cluster 通过去中心化设计和灵活的分片机制,有效解决了单节点 Redis 的高可用和高并发问题,是生产环境中 Redis 集群的首选方案。
后续使用过程中,需重点关注集群状态、槽位分配和节点健康,避免因节点故障导致集群不可用。建议结合实际业务场景,合理规划集群节点数量和槽位分配,确保数据安全和服务稳定。
相关免费在线工具
- Base64 字符串编码/解码
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
- Base64 文件转换器
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
- Markdown转HTML
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
- HTML转Markdown
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online
- JSON 压缩
通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online
- JSON美化和格式化
将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online