高并发架构演进:Redis 三主三从 Cluster 集群搭建与底层机制解析

  • ~4.54K 字

这篇博客分享一下 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 节点。

  • 节点端口分配700170027003 为主节点(Master);700470057006 为从节点(Slave)。
  • 目录构建:在 /test 目录下分别创建这 6 个节点的独立数据与配置文件夹,保持环境隔离。
1
mkdir -p /test/{7001,7002,7003,7004,7005,7006}

2. Cluster 核心配置文件修改

replicaof 主从复制不的指令同,Cluster 模式需要开启专用的集群参数。我将模板 redis.conf 拷贝至 6 个目录中,并进行了核心参数的修改(以 7001 为例,其他节点同理替换端口):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# 下述代码仅仅作为展示使用
# ==================== 网络 ====================
bind 0.0.0.0
port 7001
protected-mode no

# ==================== 通用 ====================
daemonize yes
pidfile /var/run/redis_7001.pid
logfile "/test/7001/redis.log"
dir /test/7001

# ==================== 集群核心 ====================
cluster-enabled yes
cluster-config-file nodes-7001.conf
cluster-node-timeout 5000

# ==================== 持久化 ====================
appendonly yes
appendfilename "appendonly-7001.aof"
save 900 1
#save 300 10
#save 60 10000

# ==================== 安全 ====================
# requirepass your_password
# masterauth your_password

# ==================== 内存管理 ====================
# maxmemory 4gb
# maxmemory-policy volatile-lru

# ==================== 慢日志与延迟监控 ====================
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 100

注意:在 Cluster 模式初始化前,不要在配置文件里写死主从关系,主从关系的绑定将由集群创建命令自动分配。

3. 一键启动节点与集群网络构建

编写 start_redis_cluster.sh脚本或依次启动 6 个 Redis 实例后,通过 ps -ef | grep redis 确认进程全部正常运行,且进程名后带有 [cluster] 标识。

1
2
3
4
5
6
redis-server /test/7001/redis.conf
redis-server /test/7002/redis.conf
redis-server /test/7003/redis.conf
redis-server /test/7004/redis.conf
redis-server /test/7005/redis.conf
redis-server /test/7006/redis.conf

start_redis_cluster.sh脚本运行后结果
接下来,使用 redis-cli 工具正式构建集群并分配插槽与主从关系:

1
2
3
4
5
6
7
8
9
#测试使用IP
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 代表为每个 Master 分配 1 个 Slave。Redis 底层算法会自动打散主从关系(例如 7001 的从节点不会和 7001 在同一台物理机上,尽管本次是单机模拟,但机制依然保留)。执行后,系统会分配 0-16383 的哈希槽给三个主节点。

4. 哈希槽路由机制验证与读写测试

集群建立后,数据的读写不再固定于某一台机器,而是通过 CRC16(key) % 16384 算法计算出哈希槽,然后路由到对应的 Master 节点。

测试时,必须带上 -c 参数开启集群路由模式,否则遇到跨节点的数据会报错 MOVED

1
2
3
4
[root@centos test]# redis-cli -p 7001 -c
127.0.0.1:7001> set username "beibainian"
-> Redirected to slot [14315] located at 127.0.0.1:7003
OK

测试结果表明,当在 7001 节点写入属于 7003 节点哈希槽的数据时,客户端自动完成了重定向(Redirected),数据成功落盘并同步至 7003 的从节点,集群分片路由功能完美生效。

5. 核心原理解析:Cluster 的内建高可用与自动故障转移

很多人在接触集群时会有一个疑问:主节点挂了,谁来负责把它踢掉并提拔从节点?还需要额外部署哨兵(Sentinel)集群吗?

答案是:不需要。Redis Cluster 将哨兵的故障监控和选举机制直接内建到了集群节点中。它的“自动补位”流程如下:

  1. Gossip 协议“查岗”:集群内的所有节点会通过一个独立的高端口(服务端口 + 10000,例如 17001)不断互相发送 Ping/Pong 消息,交换彼此的运行状态。
  2. 疑似下线(PFAIL):如果主节点 7001 宕机,主节点 7002 在配置文件设定的 cluster-node-timeout(我设了 5000 毫秒)内没有收到 7001 的 Pong 回应,就会在内部将 7001 标记为 PFAIL(主观下线)。
  3. 确定下线(FAIL):7002 会把这个消息通过 Gossip 协议广播给全网。当集群中超过半数的主节点都确认联系不上 7001 时,7001 就会被正式升级标记为 FAIL(客观下线)。
  4. 从节点上位(Failover):7001 的从节点(如 7004)察觉到自己的 Master 已经被判死刑后,会立刻向集群中幸存的其他主节点(7002、7003)拉票。获得半数以上选票后,7004 就会自动执行内部转换,升级为新的 Master,接管原有的哈希槽,整个业务层面几乎无感知。

🔧 技术难点与踩坑记录

  1. 节点握手失败与 MOVED 报错
  • 现象:不带 -c 参数登录客户端执行 set 操作时,直接抛出 (error) MOVED 14315 192.168.68.104:7003 错误。
  • 攻克:Cluster 架构下的客户端必须是“集群感知(Cluster-aware)”的。加上 -c 参数后,客户端就能解析 MOVED 响应并自动跳转到目标节点完成操作。
  1. 集群总线端口(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
2
maxmemory 4gb
maxmemory-policy volatile-lru # 优先淘汰设置了过期时间且最少使用的 key

📊 自我评价

这个三主三从架构,其实很早就想做了 奈何与没有更多时间来完成,接下来我还需要继续学习和完善三主三从架构。Redis系列还会继续做,还会增加更多博客文档。

💖 感谢支持,点击查看收款码
你的鼓励是我持续更新的动力!
分享
扫码查看github网址,按钮查看个人网站