这篇博客分享一下 Redis 分布式高可用架构的核心实战:搭建 Redis 三主三从 Cluster 集群。
在写这个博客之前,我已经完成了“一主一从”和“一主三从”架构的部署,实现了读写分离。但面对海量数据和短时间内极高的并发写入请求,单台 Master 节点的 CPU、网络带宽和内存都会成为严重瓶颈。
为此,我进一步探索了 Redis Cluster(分片集群)模式,通过划分 16384 个哈希槽实现了数据的水平分片与多主节点的负载均衡。
本篇侧重于技术原理解析与本地集群搭建实操,并在文末补充了将此架构推向企业级生产环境所需的改造指南。
🧱 核心技术栈总览
- 操作系统与环境:CentOS 7 64位、MobaXterm
- 核心组件:Redis 6.x/7.x、Redis-cli Cluster 管理工具
- 架构机制:Hash Slots分片算法、Gossip 节点通信协议、故障自动转移
💡 核心工作与落地实现
1. 集群架构规划与目录准备
为了在单机上模拟真实的三主三从集群,我规划了 6 个独立的 Redis 节点。
- 节点端口分配:
7001、7002、7003为主节点(Master);7004、7005、7006为从节点(Slave)。 - 目录构建:在
/test目录下分别创建这 6 个节点的独立数据与配置文件夹,保持环境隔离。
1 | mkdir -p /test/{7001,7002,7003,7004,7005,7006} |
2. Cluster 核心配置文件修改
与 replicaof 主从复制不的指令同,Cluster 模式需要开启专用的集群参数。我将模板 redis.conf 拷贝至 6 个目录中,并进行了核心参数的修改(以 7001 为例,其他节点同理替换端口):
1 | # 下述代码仅仅作为展示使用 |
注意:在 Cluster 模式初始化前,不要在配置文件里写死主从关系,主从关系的绑定将由集群创建命令自动分配。
3. 一键启动节点与集群网络构建
编写 start_redis_cluster.sh脚本或依次启动 6 个 Redis 实例后,通过 ps -ef | grep redis 确认进程全部正常运行,且进程名后带有 [cluster] 标识。
1 | redis-server /test/7001/redis.conf |

接下来,使用 redis-cli 工具正式构建集群并分配插槽与主从关系:
1 | #测试使用IP |

- 原理解析:
--cluster-replicas 1代表为每个 Master 分配 1 个 Slave。Redis 底层算法会自动打散主从关系(例如 7001 的从节点不会和 7001 在同一台物理机上,尽管本次是单机模拟,但机制依然保留)。执行后,系统会分配 0-16383 的哈希槽给三个主节点。
4. 哈希槽路由机制验证与读写测试
集群建立后,数据的读写不再固定于某一台机器,而是通过 CRC16(key) % 16384 算法计算出哈希槽,然后路由到对应的 Master 节点。
测试时,必须带上 -c 参数开启集群路由模式,否则遇到跨节点的数据会报错 MOVED:
1 | [root@centos test]# redis-cli -p 7001 -c |
测试结果表明,当在 7001 节点写入属于 7003 节点哈希槽的数据时,客户端自动完成了重定向(Redirected),数据成功落盘并同步至 7003 的从节点,集群分片路由功能完美生效。
5. 核心原理解析:Cluster 的内建高可用与自动故障转移
很多人在接触集群时会有一个疑问:主节点挂了,谁来负责把它踢掉并提拔从节点?还需要额外部署哨兵(Sentinel)集群吗?
答案是:不需要。Redis Cluster 将哨兵的故障监控和选举机制直接内建到了集群节点中。它的“自动补位”流程如下:
- Gossip 协议“查岗”:集群内的所有节点会通过一个独立的高端口(服务端口 + 10000,例如 17001)不断互相发送 Ping/Pong 消息,交换彼此的运行状态。
- 疑似下线(PFAIL):如果主节点 7001 宕机,主节点 7002 在配置文件设定的
cluster-node-timeout(我设了 5000 毫秒)内没有收到 7001 的 Pong 回应,就会在内部将 7001 标记为PFAIL(主观下线)。 - 确定下线(FAIL):7002 会把这个消息通过 Gossip 协议广播给全网。当集群中超过半数的主节点都确认联系不上 7001 时,7001 就会被正式升级标记为
FAIL(客观下线)。 - 从节点上位(Failover):7001 的从节点(如 7004)察觉到自己的 Master 已经被判死刑后,会立刻向集群中幸存的其他主节点(7002、7003)拉票。获得半数以上选票后,7004 就会自动执行内部转换,升级为新的 Master,接管原有的哈希槽,整个业务层面几乎无感知。
🔧 技术难点与踩坑记录
- 节点握手失败与 MOVED 报错
- 现象:不带
-c参数登录客户端执行set操作时,直接抛出(error) MOVED 14315 192.168.68.104:7003错误。 - 攻克:Cluster 架构下的客户端必须是“集群感知(Cluster-aware)”的。加上
-c参数后,客户端就能解析MOVED响应并自动跳转到目标节点完成操作。
- 集群总线端口(Gossip协议)阻塞
- 现象:集群创建时一直卡在
Waiting for the cluster to join...。 - 攻克:正是因为上文提到的 Gossip 协议,Redis 集群除了服务端口(如 7001),还会默认开启一个总线端口(17001)。排查发现是防火墙拦截了 17000+ 频段的端口。放行端口后集群瞬间握手成功。
🚀 进阶:向企业级生产环境靠拢需要修改什么?
以上配置属于技术实验性质,侧重于理解分片与路由机制。如果要把这套三主三从架构搬到真正的企业级生产环境,还需要做以下核心维度的改造:
1. 物理拓扑的容灾隔离
- 现状:6 个节点全部跑在同一台 CentOS 服务器上。服务器一旦宕机,整个缓存集群直接挂掉。
- 改造:必须跨物理机部署。企业中通常会分配至少 3 台物理服务器/虚拟机。集群算法会自动保证 Master 和它的 Slave 绝不会落在同一台物理机上。这样任何一台物理机断电,集群都能通过其他机器上的从节点自动选举,完成 Failover。
2. 安全与权限的红线配置
- 现状:无密码裸奔,任意内网 IP 皆可连接并执行
FLUSHALL操作。 - 改造:
- 必须在
redis.conf中配置requirepass(客户端连接密码)和masterauth(主从同步鉴权密码)。 - 企业中后期普遍会升级 Redis 6.0+ 的 ACL(访问控制列表),为不同的微服务分配专属账号。例如:订单服务只能操作
order:*开头的 key,数据分析服务仅分配只读权限。
3. 内存管理与数据淘汰策略
- 现状:使用系统默认配置,无限吃内存。
- 改造:生产环境服务器内存寸土寸金,必须设置最大内存上限和淘汰策略:
1 | maxmemory 4gb |
📊 自我评价
这个三主三从架构,其实很早就想做了 奈何与没有更多时间来完成,接下来我还需要继续学习和完善三主三从架构。Redis系列还会继续做,还会增加更多博客文档。