三台机器搭建Redis三主三从集群实战指南

发布时间:2026/10/12 13:36:58

三台机器搭建Redis三主三从集群实战指南 1. 为什么三台机器跑三主三从是个务实的选择很多人第一次接触 Redis 集群脑子里冒出来的第一个问题往往是我到底需要几台机器。官方文档给出的最小可用拓扑是三个主节点因为集群的故障转移和投票机制依赖多数派原则三个主节点意味着可以容忍一个主节点挂掉而不影响整个集群的可用性。但如果你只部署三个主节点一旦某个主节点宕机它上面的槽位虽然会被其他主节点接管可数据副本就没了恢复期间如果再来一次故障整个集群就可能进入不可用状态。所以生产环境里更常见的做法是给每个主节点配一个从节点形成三主三从的六节点拓扑。这时候问题来了六个节点是不是必须六台机器答案是不一定。Redis 集群的节点是逻辑概念不是物理概念你完全可以在三台物理机或虚拟机上各跑两个 Redis 实例一个当主一个当从只要端口不冲突、内存够用、网络延迟可控这套拓扑就能正常工作。我选择三台虚拟机做三主三从核心考量有三个。第一是资源成本六台机器的开销对个人学习或者中小团队来说偏高三台机器能把硬件利用率拉满。第二是故障域的模拟三台机器意味着任意一台挂掉你都能观察到集群如何重新分配槽位、如何提升从节点、如何继续对外服务这个演练价值比六台机器分散部署要高得多。第三是配置复杂度可控三台机器上的端口规划、防火墙规则、启动脚本都更容易管理排查问题时思路也更清晰。不过这里有个前提需要说清楚三台机器跑三主三从本质上是用实例级冗余换机器级冗余。如果一台物理机彻底宕机它上面的一主一从会同时消失集群的可用性会瞬间下降一个档次。所以这套方案适合学习、测试、中小规模业务如果你的业务对可用性要求极高还是老老实实上六台机器做真正的物理隔离。提示本文所有操作基于常见的 Linux 发行版和 Redis 7.x 版本不同版本在配置文件字段和集群命令上可能有细微差异建议先确认版本再动手。2. 动手之前的规划端口、目录与网络2.1 三台机器的角色分配与端口规划假设你手上有三台虚拟机IP 分别是 192.168.1.101、192.168.1.102、192.168.1.103。我的习惯是给每台机器分配两个 Redis 实例端口用 7001 和 7002其中 7001 作为主节点的候选7002 作为从节点的候选。但要注意主从关系不是你在配置文件里写死的而是由集群在运行时根据槽位分配和故障转移自动决定的。你启动的时候可以指定谁是主谁是从但后续如果发生故障转移角色会互换。具体规划如下表机器 IP实例端口初始角色数据目录日志目录192.168.1.1017001主节点/data/redis/7001/logs/redis/7001192.168.1.1017002从节点/data/redis/7002/logs/redis/7002192.168.1.1027001主节点/data/redis/7001/logs/redis/7001192.168.1.1027002从节点/data/redis/7002/logs/redis/7002192.168.1.1037001主节点/data/redis/7001/logs/redis/7001192.168.1.1037002从节点/data/redis/7002/logs/redis/7002这个规划的好处是每台机器的目录结构完全一致你写启动脚本、写监控、写备份的时候可以用同一套模板减少出错概率。端口用 7001 和 7002 而不是默认的 6379是为了避免和机器上可能已经存在的单机 Redis 冲突同时也让集群节点一眼就能认出来。2.2 系统层面的准备工作在开始装 Redis 之前有三件事必须先做否则后面会踩坑。第一是关闭透明大页Redis 官方明确建议关闭 THP因为它会导致内存分配延迟抖动。执行命令echo never /sys/kernel/mm/transparent_hugepage/enabled然后把它写进/etc/rc.local保证重启后依然生效。第二是调整文件描述符限制Redis 集群每个节点都需要维持大量连接默认的 1024 往往不够用。在/etc/security/limits.conf里加上* soft nofile 65535和* hard nofile 65535然后重新登录生效。第三是确认时间同步集群节点之间靠 Gossip 协议通信时间偏差过大会导致节点状态判断异常用ntpdate或者chronyd把三台机器的时间对齐。还有一点容易被忽略三台机器之间的网络必须互通而且不能有 NAT 转换。Redis 集群的节点会把自己的 IP 和端口告诉其他节点如果存在 NAT其他节点拿到的地址可能无法回连导致集群创建失败。如果你是在虚拟机里做实验网络模式建议用桥接或者 Host-Only不要用 NAT。2.3 Redis 安装与目录初始化安装 Redis 有两种方式一种是包管理器直接装一种是源码编译。包管理器装出来的版本往往偏旧而且配置文件路径和源码编译的不一样为了后续配置清晰我习惯用源码编译。下载 Redis 7.x 的源码包解压后执行make和make install然后把redis-server、redis-cli、redis-sentinel这几个二进制文件复制到/usr/local/bin下。接下来创建目录结构。在三台机器上分别执行mkdir -p /data/redis/7001 /data/redis/7002 mkdir -p /logs/redis/7001 /logs/redis/7002 mkdir -p /etc/redis/7001 /etc/redis/7002/data放 RDB 和 AOF 文件/logs放日志/etc/redis放配置文件。每个实例一个独立目录互不干扰。这里有个经验不要把两个实例的数据目录放在同一个磁盘分区下如果这个分区空间紧张因为 RDB 重写的时候会临时占用双倍空间两个实例同时重写可能把磁盘撑爆。3. 配置文件怎么写才不容易翻车3.1 集群模式的核心配置项Redis 集群模式的配置文件有几个关键字段写错了集群根本起不来。下面是一个 7001 实例的配置模板7002 只需要改端口和目录路径port 7001 bind 0.0.0.0 protected-mode no daemonize yes pidfile /var/run/redis_7001.pid logfile /logs/redis/7001/redis.log dir /data/redis/7001 cluster-enabled yes cluster-config-file nodes-7001.conf cluster-node-timeout 15000 cluster-announce-ip 192.168.1.101 cluster-announce-port 7001 cluster-announce-bus-port 17001 appendonly yes appendfilename appendonly.aof save 900 1 save 300 10 save 60 10000逐条解释一下。cluster-enabled yes是开启集群模式的总开关不开这个后面所有集群命令都会报错。cluster-config-file是集群节点自动维护的配置文件你不需要手动编辑它但必须保证 Redis 进程对这个文件有写权限否则集群启动时会报错。cluster-node-timeout是节点超时时间单位毫秒15000 意味着 15 秒内没收到心跳就认为节点可能挂了这个值太小会导致网络抖动时频繁触发故障转移太大则故障发现延迟高15 秒是个比较稳妥的折中。cluster-announce-ip和cluster-announce-port这两个字段在多网卡或者有 NAT 的环境里特别重要。如果你的机器有多个 IPRedis 默认可能选错 IP 广播出去导致其他节点连不上。显式指定这两个字段可以避免这个问题。cluster-announce-bus-port是集群总线端口默认是普通端口加 10000也就是 17001如果你改了普通端口总线端口也要跟着改而且防火墙必须放行这个端口。3.2 持久化策略的取舍集群模式下持久化策略需要单独考虑。我上面配了 AOF 和 RDB 同时开启这是比较保守的做法。AOF 保证数据丢失窗口小RDB 用于快速恢复和备份。但 AOF 对性能有影响如果你的业务对写入性能极其敏感可以只开 RDB或者把 AOF 的刷盘策略改成everysec而不是always。这里有个坑集群模式下每个节点都在写 AOF如果某个从节点长时间和主节点断连重新连上后会触发全量同步这时候从节点会加载 RDB 然后重放 AOF如果 AOF 文件很大这个过程会非常慢甚至导致从节点被集群踢出去。我的做法是给从节点配置appendonly no只保留 RDB因为从节点的数据可以从主节点重新同步不需要本地持久化来保证数据安全。3.3 启动实例与验证配置文件写好后在三台机器上分别启动两个实例redis-server /etc/redis/7001/redis.conf redis-server /etc/redis/7002/redis.conf启动后用ps -ef | grep redis确认进程存在然后用redis-cli -p 7001 ping测试连通性。如果返回 PONG说明实例正常。如果返回(error) DENIED Redis is running in protected mode说明protected-mode没关或者bind配置不对。这时候集群还没有创建每个节点都是孤立的cluster info会显示cluster_state:fail这是正常的。接下来才是最关键的一步用redis-cli --cluster create命令把六个节点组成集群。4. 集群创建、槽位分配与验证4.1 创建命令的完整写法与参数含义创建集群的命令看起来很长但每个参数都有明确含义redis-cli --cluster create \ 192.168.1.101:7001 192.168.1.102:7001 192.168.1.103:7001 \ 192.168.1.101:7002 192.168.1.102:7002 192.168.1.103:7002 \ --cluster-replicas 1--cluster-replicas 1表示每个主节点配一个从节点。Redis 会按照你给出的顺序把前三个当作主节点候选后三个当作从节点候选然后自动分配主从关系和槽位。执行后它会打印出一个分配方案问你是否接受输入yes回车即可。这里有个细节如果你希望主从关系按照你预期的配对方式比如 101 的从是 102需要在命令里调整节点顺序或者创建后用cluster replicate命令手动调整。自动分配的主从关系是随机的但通常会把从节点分配到不同的物理机上这其实是好事因为同一台机器的两个实例如果互为主从机器一挂就全没了。4.2 槽位分配的原理与验证Redis 集群把整个键空间分成 16384 个槽位每个主节点负责一部分。创建集群时Redis 会尽量均匀地分配三个主节点大概各分到 5461 个槽。你可以用cluster slots命令查看分配结果或者用cluster nodes看每个节点的角色和槽位范围。验证集群是否正常有几个命令必须会redis-cli -p 7001 cluster info redis-cli -p 7001 cluster nodes redis-cli -c -p 7001 set foo bar redis-cli -c -p 7001 get foocluster info里cluster_state:ok表示集群健康cluster_slots_assigned:16384表示所有槽位都已分配。cluster nodes会列出所有节点及其角色主节点后面会标注槽位范围从节点会标注它复制的是哪个主节点。-c参数是集群模式的关键它让 redis-cli 在收到 MOVED 重定向时自动跳转到正确的节点。如果你不加-c当 key 不在当前节点时你会收到一个 MOVED 错误需要手动去连目标节点。生产代码里客户端库会自动处理重定向但用命令行测试时一定要加-c。4.3 故障转移演练亲手挂掉一个主节点集群建好之后一定要做一次故障转移演练否则你永远不知道配置是否真的可靠。找一台机器把它的主节点进程杀掉redis-cli -p 7001 shutdown nosave然后立刻在另一台机器上观察cluster nodes的输出。你会看到被杀的节点状态变成fail它的从节点会在几秒内被提升为新的主节点槽位也会被接管。整个过程通常在 10 到 15 秒内完成取决于cluster-node-timeout的设置。这时候如果你用-c模式去读写原来那个主节点负责的 key会发现请求被自动重定向到新的主节点业务几乎无感知。这就是集群的价值所在。演练完成后把杀掉的节点重新启动它会自动以从节点的身份加入集群并开始同步新主节点的数据。注意故障转移演练不要在业务高峰期做虽然理论上无感知但客户端连接池可能会有短暂的报错需要做好重试逻辑。5. 日常运维中那些文档不会告诉你的事5.1 集群节点的增删与槽位迁移业务增长后可能需要加节点或者某个节点磁盘坏了需要替换。集群模式下增删节点不是简单改配置文件而是要用redis-cli --cluster的一系列子命令。加主节点用add-node然后reshard迁移槽位加从节点用add-node --cluster-slave删节点用del-node但删之前必须确保它没有负责任何槽位否则会报错。槽位迁移是个精细活reshard命令会交互式地问你迁移多少个槽、从哪些节点迁、迁到哪个节点。迁移过程中集群仍然可用但涉及迁移槽位的 key 会有短暂的访问延迟。我的经验是每次迁移不超过 1000 个槽分多次完成避免一次性迁移太多导致网络和磁盘压力过大。5.2 常见报错与排查思路集群运维中遇到最多的报错是CLUSTERDOWN Hash slot not served意思是某个槽位没有节点负责。这通常发生在集群创建不完整、节点被误删、或者槽位迁移中断的情况下。排查方法是先用cluster info看cluster_slots_assigned是否等于 16384如果不是用cluster nodes找出哪些槽位缺失然后手动用cluster addslots补上或者用reshard重新分配。另一个高频报错是MOVED和ASK重定向。MOVED表示 key 永久迁移到了另一个节点客户端应该更新路由表ASK表示 key 正在迁移中客户端应该临时去目标节点查询但不要更新路由表。如果你用的是自己实现的客户端这两个重定向必须正确处理否则会出现数据读写不一致。5.3 监控指标与容量规划集群跑起来之后至少要监控这几个指标每个节点的内存使用率、连接数、命中率、慢查询数量、以及集群状态。内存使用率超过 70% 就要考虑扩容因为 RDB 重写和主从同步都需要额外内存。连接数突然飙升可能是客户端没有正确释放连接或者有热点 key 导致某个节点压力过大。容量规划方面三主三从的写入能力大致是单机的三倍但读能力取决于从节点的数量和客户端是否开启了读写分离。如果你的业务读多写少可以给每个主节点配两个从节点把读流量分散出去。但要注意从节点越多主节点的复制压力越大网络带宽可能成为瓶颈。6. 把这套环境用起来客户端接入与压测6.1 客户端连接的正确姿势用 Python 的 redis-py 连接集群时要用RedisCluster类而不是普通的Redis类from redis.cluster import RedisCluster startup_nodes [ {host: 192.168.1.101, port: 7001}, {host: 192.168.1.102, port: 7001}, {host: 192.168.1.103, port: 7001}, ] rc RedisCluster(startup_nodesstartup_nodes, decode_responsesTrue) rc.set(foo, bar) print(rc.get(foo))注意startup_nodes只需要给部分节点客户端会自动发现完整拓扑。但至少要给两个不同机器的节点否则那个机器挂了客户端就连不上集群了。Java 的 Jedis 和 Lettuce 也都有对应的集群客户端类用法类似。6.2 用 redis-benchmark 做一轮压测集群建好后用redis-benchmark做一轮基准测试心里有个底redis-benchmark -h 192.168.1.101 -p 7001 -c 50 -n 100000 -t set,get -q-c 50表示 50 个并发连接-n 100000表示总共 10 万次操作-t set,get表示只测 set 和 get-q表示只输出结果摘要。压测时观察三台机器的 CPU 和网络如果某个节点明显偏高说明槽位分配不均匀或者有热点 key。压测结果受虚拟机配置影响很大不要拿这个数字去推断生产环境的性能。它的价值在于帮你发现配置问题比如如果 QPS 低得离谱可能是网络延迟太高、或者持久化策略太重、或者集群总线端口被防火墙限速了。6.3 数据备份与恢复的实操集群模式下的备份不能简单复制 RDB 文件因为每个节点只负责一部分数据。正确的做法是在每个主节点上执行BGSAVE然后把生成的 RDB 文件收集起来恢复时分别放到对应节点的数据目录下。但要注意如果集群拓扑变了槽位分配和 RDB 文件可能对不上恢复后需要重新分配槽位。更稳妥的备份方式是用redis-cli --cluster的backup功能或者用第三方工具做逻辑备份。逻辑备份的好处是跨版本兼容恢复时不受槽位分配影响缺点是速度慢、占用空间大。我的做法是每天做一次逻辑备份每周做一次 RDB 物理备份两者结合兼顾恢复速度和灵活性。7. 我在三台机器上踩过的那些坑第一个坑是防火墙。集群总线端口 17001 默认不在常用端口列表里很多防火墙规则只放行了 7001 和 7002结果集群创建时节点之间无法通信一直卡在Waiting for the cluster to join。解决办法是在三台机器上都放行 7001、7002、17001、17002 这四个端口TCP 和 UDP 都要放行因为集群总线同时使用两种协议。第二个坑是内存溢出。三台虚拟机如果每台只有 2GB 内存跑两个 Redis 实例加上系统本身很容易触发 OOM Killer 把 Redis 进程杀掉。我的建议是每台机器至少 4GB 内存并且给 Redis 配置maxmemory限制比如每个实例限制 1GB留足余量给系统和其他进程。maxmemory-policy建议用allkeys-lru这样内存满了会自动淘汰旧数据而不是直接报错。第三个坑是集群创建后忘记设置密码。如果 Redis 没有密码任何能访问到端口的人都可以操作你的数据。集群模式下设置密码需要在每个节点的配置文件里加requirepass和masterauth两个都要加前者是客户端连接密码后者是主从同步密码。改完密码后需要重启所有节点然后用redis-cli -a带密码重新创建集群或者更新配置。第四个坑是虚拟机快照恢复后集群状态异常。如果你用快照回滚了某台机器它的集群配置文件nodes-7001.conf可能还是旧的状态和其他节点对不上。这时候需要把该节点的nodes-*.conf删掉重启 Redis让它重新从其他节点同步集群状态。如果整个集群都回滚了那只能重新创建集群。这套三台虚拟机三主三从的环境我从最初搭建到稳定运行前后折腾了大概一周时间大部分时间都花在排查网络和配置问题上。但一旦跑通它就是一个非常趁手的实验平台你可以在这上面演练故障转移、测试客户端兼容性、验证扩容方案而不用担心影响生产环境。对于想深入理解 Redis 集群的人来说亲手搭一遍比看十遍文档都管用。
延伸阅读

更多相关文章

2026/10/12 13:36:58

Manus工作原理大揭秘:多智能体架构下如何把endpoint改到TaoToken

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 13:36:58

路径规划算法实战:Dijkstra、A*与CBS多智能体避碰详解

1. 路径规划算法的整体设计思路与选型逻辑路径规划这件事,说白了就是让一个“东西”从起点走到终点,中间还得绕开各种障碍。这个“东西”可以是游戏里的NPC、仓库里的AGV小车、无人机,也可以是多机器人系统里的每一个独立个体。我最早接触这块…

2026/10/12 13:31:58

数据库迁移容器化:DBmotion docker-compose编排避坑指南

简介:面向需要快速搭建数据库迁移环境的开发与运维人员,这套容器集合围绕 DBmotion 迁移服务整合了数据节点、监控告警、代理网关与可视化操作界面等依赖组件,借助可执行的 docker-compose.yaml 即可一次性拉起整套服务,显著降低环…

2026/10/12 14:37:09

医疗健康 AI Agent Harness Engineering:从辅助诊断到个性化治疗

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 14:37:09

MCP Server接入3D工作流:让AI真正读懂你的场景数据

1. 我的 3D 工作流里,为什么非要塞进一个 MCP server做 3D 项目做久了,你会发现一个特别拧巴的事:AI 语言模型再聪明,也看不懂我硬盘里的 .blend、.gltf、.fbx。它知道什么是"漫反射贴图",能跟你聊 PBR 材质…

2026/10/12 14:37:09

DeepSeek Harness:全插件化Agent运行时与可回放会话日志实战

做了几年Agent应用,说实话踩过的坑比写出来的代码还多。最近我把自己常用的那套Agent运行骨架重新整理了一遍,抽出了一个内部代号叫 DeepSeek Harness 的轻量级运行时,核心就两件事:全插件化的装配机制,以及一套可回放…

2026/10/12 14:37:09

旋转圆盘上的摆动模拟:非惯性系下的动力学建模与数值实现

“旋转圆盘上的摆动模拟”听起来像个物理课建模题,但真正落地做的时候,你会发现它兼顾了刚体动力学、非惯性系分析和数值稳定性这几件麻烦事。我最早是因为一个同学在某个平台团建展示了一个演示:圆盘转起来,摆锤没有老老实实顺着…

2026/10/12 14:32:08

质数子串算法:筛法预处理与贪心枚举优化

1. 从一道题看质数子串的通用解法第一次看到“Prime Substring”这个标题,很多人会下意识觉得它是一道纯字符串题,顶多再加点数论判断。但真正做过这类题的人都知道,它的核心难点从来不是“怎么判断质数”,而是“怎么在极短的时间…

2026/10/11 0:02:13

Python调用Gemini Structured Outputs实现工单路由门禁

客服工单最怕的不是模型“答错一句话”,而是它给出一段看起来合理的说明,程序却从中猜错优先级。通俗做法是:要求模型只交 JSON(JavaScript Object Notation,轻量数据格式),再让代码验证它。Gem…

2026/10/12 12:01:26

Spring Boot超市进销存系统毕设实战:从需求拆解到答辩通关

最近带的一个学生项目组里,有A同学跑来问我:选什么毕设题目最稳妥,既能让评审老师觉得工作量够,又不会在答辩时被问到语无伦次。我第一反应就是推荐基于Spring Boot的超市仓库管理系统——也就是超市进销存系统。这个题目乍一看平…

2026/10/12 12:54:07

Flutter StatefulWidget 生命周期核心解析

很多刚开始接触 Flutter 的朋友,在看完一堆“Hello World”和基础组件之后,大概率都会撞上同一堵墙:StatefulWidget 里那堆 initState、build、dispose 方法,到底什么时候被调用?为什么顺序是那样?在里面到…

2026/10/12 0:04:22

绝缘子缺陷检测数据集清洗与工业级训练实战指南

简介:本资源是面向电力AI研发人员、工业视觉工程师及智能巡检系统开发者的绝缘子缺陷检测专用YOLO格式数据集,解决无人机航拍场景下绝缘子破损、污闪、积雪等9类典型缺陷的精准识别与定位难题。数据集共2139张真实巡检图像(含训练/验证/测试集…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑