Docker下Redis Cluster集群搭建实战:从配置到故障转移全流程

发布时间:2026/9/16 21:10:42
Docker下Redis Cluster集群搭建实战:从配置到故障转移全流程 前两天有个读者私信我说公司压测环境里Redis单实例CPU直接打到80%老板丢给他一句上集群吧他翻了一晚上教程不是讲原理讲得云里雾里就是用Ruby脚本搭建的老古董方案一执行就是一堆依赖报错整个人直接懵掉。他问我的时候我其实挺能理解这种感受。Redis Cluster本身并不难难的是网上教程要么太散、要么太久远很多还是Redis 3.x时代用redis-trib.rb那套东西放到今天早就不适用了。再加上Docker的引入很多教程只贴命令不解释为什么抄完一出问题根本不知道从哪排查。所以我决定把最近一次在Docker里搭建Redis Cluster的完整过程重新梳理一遍写成一篇真正每一步都能照着做的实战记录。这篇教程会覆盖从环境准备、配置文件编写、容器创建、集群初始化到故障切换验证和常见问题排查的完整链路。所有命令我都会把预期输出写清楚你执行完如果看到的东西和文章对不上那就是哪一步出了问题可以直接跳到后面的排查章节对号入座。这篇内容适合谁看刚接触Redis集群、想在本地用最少成本搞一套完整环境的人被各种编译安装折磨过、想用最清爽的方式快速验证集群特性的开发者以及准备在生产环境上Redis Cluster想先在测试环境把坑都踩一遍再上线的运维同学。1. 搭建前必须想清楚Redis Cluster到底解决什么问题1.1 单机Redis的瓶颈在哪里很多人一上来就急着敲命令建集群但我觉得动手前花五分钟搞清楚为什么需要集群更重要。单机Redis最直接的三个天花板第一是容量一台机器的内存是有限的Redis数据全在内存里单机上到一两百G之后成本直线上升第二是并发Redis虽然是单线程模型但极限QPS也就十万到二十万级别一旦业务量上去单实例扛不住第三是高可用单机部署意味着这台机器挂了服务就断了只能靠重启恢复。传统的主从复制哨兵方案可以解决高可用问题主节点挂了从节点顶上但容量和并发这两个问题依然只能靠单机解决。不管你是加大内存还是加CPU单机的物理瓶颈始终在哪里。Redis Cluster解决的就是这个问题。它把数据自动切分到多个节点上每个节点只负责一部分数据同时每个主节点下面挂着从节点实现自动故障转移。这样容量可以横向扩展并发能力也随着节点数增加而提升高可用也一并解决了。1.2 Redis Cluster的三个核心机制Redis Cluster不太容易理解的地方是它和主从复制、哨兵那套方案不是一回事。它的核心设计可以拆成三个部分来看。第一是数据分片。Cluster把整个键空间划分成16384个哈希槽hash slot每个key通过CRC16(key) % 16384计算出一个槽位。我们建集群的时候指定了3个主节点Redis会自动把这16384个槽位平均分配到3个节点上也就是每个主节点负责大约5461个槽位。客户端读写时先算出key落在哪个槽如果这个槽不是当前连接的节点负责的节点会返回一个MOVED错误并告诉客户端应该去哪个节点访问。这就像一本大百科全书被拆成三册你想查某个词先得知道这个词收录在哪一册里。第二是主从复制。每个主节点可以挂多个从节点从节点实时同步主节点的数据。一旦某个主节点宕机了它的从节点会通过选举晋升为新的主节点继续对外服务。这个过程是自动的对客户端来说几乎无感知。第三是节点间通信。集群里每个节点都知道整个集群的拓扑状态这些信息通过Gossip协议在节点之间不断传播。节点之间除了正常的6379端口默认端口之外还会额外开一个端口用于集群节点间通信默认是客户端端口10000也就是16379。另外有一个概念必须搞清楚Cluster和哨兵是不一样的。哨兵负责监控主从架构并切换但它不参与数据分片而Cluster既管分片又管高可用。两者方案选一个就好不需要同时上。1.3 为什么推荐用Docker搭建集群环境早期搭建Redis Cluster有多痛苦经历过的老人都懂。你得准备多台服务器或者虚拟机每台上装Redis改配置然后用redis-trib.rb这个Ruby脚本去创建集群而Ruby环境本身就可能折腾半天。折腾完一轮时间消耗少说一两个小时。用Docker之后这个流程被压缩到十分钟以内。原因很简单Docker容器本身就是独立的运行环境镜像把Redis二进制文件、运行依赖全部打包好了我们只需要关注配置和网络。一条docker run命令就能起一个节点起六个节点也只不过是多执行五次的问题。而且Docker可以在一台机器上模拟出完整的集群网络拓扑。容器之间通过网络互访不代表真实多机部署但对学习和预演生产环境来说机制完全一样。这意味着你可以在自己电脑上把集群的所有特性、坑、调试手段先跑一遍再带着经验去碰生产环境。提示如果你的最终目标是生产环境建议集群节点至少3主3从。这个方案我会在下文完整演示它既是学习的最低配置也是生产环境的最小可用配置。2. 环境准备Docker和Redis镜像的选择2.1 先检查你的Docker环境这一步虽然基础但很多人栽在这里。不同操作系统装Docker的方式不一样如果是Windows和macOS目前主用是Docker DesktopLinux发行版则直接装Docker Engine。我在本地测试机上的环境是Linux Docker 24.x但为了保证这篇教程对Windows和macOS用户同样适用我把版本检查需要满足的基本条件统一列一下docker --version docker compose version这两条命令能正常输出版本号说明Docker本体和Compose插件都可用。Compose在这个教程里不是必需的但后面如果想把整个集群配置成文件管理会用到它顺手确认一下没坏处。然后运行一条关键命令docker info注意看输出的末尾有没有关于docker.sock、存储驱动overlay2、CPU/内存资源是否充足的信息。如果docker info报cannot connect to the Docker daemon那就是Docker服务没启动Linux下用systemctl start dockerWindows和macOS打开Docker Desktop等待它完成启动。这里要特别提醒Windows用户在安装Docker Desktop时如果报virtualization support not detected一般是BIOS里的虚拟化没开。进BIOS找到Intel VT-x或AMD-V开启后重启电脑。这个问题和系统版本、Docker Desktop版本无关纯粹是硬件虚拟化开关问题。2.2 Redis镜像版本怎么选Redis官方镜像在Docker Hub上维护得很勤官方镜像仓库是redis不需要加第三方前缀。版本选择上有一个分水岭Redis 5.0之前创建集群要依赖外部的redis-trib.rb脚本Ruby环境Redis 5.0发布后官方把集群创建能力直接集成到了redis-cli里不再需要Ruby。所以如果你看到某篇教程让你装Ruby、装redis-trib.rb再执行redis-trib create那基本上是上古时代的方案可以直接关掉。我这次演示用的是redis:7.0。选7.0而不是更新的7.2或7.4理由很简单7.x版本在集群协议上已经非常稳定和当前生产环境主流版本一致网上遇到问题的案例也更多排查起来有参考。你用7.2或者7.4也没问题命令基本通用。这里建议固定镜像版本号不要用redis:latest不然哪天官方把latest推到新大版本语法有变化你之前写的脚本可能悄无声息地就失效了。先拉取镜像docker pull redis:7.02.3 准备Redis配置文件Redis在Docker里跑最重要的就是配置文件。镜像里默认是没有任何配置文件的我们用docker run的时候可以通过命令行参数传配置也可以把配置写在文件里挂载进容器。配置项多的时候文件方式更清晰、可维护性更好。我在/opt/redis-cluster目录下按照端口来组织目录结构每个端口一个目录里面放一份redis.conf。三个主节点三个从节点一共六个端口7000、7001、7002、7003、7004、7005。mkdir -p /opt/redis-cluster/{7000,7001,7002,7003,7004,7005}然后每个目录里创建redis.conf内容如下port 6379 cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 appendonly yes protected-mode no逐项解释一下关键配置的作用port容器内Redis监听的端口。这里不需要每个容器改成对应7000、7001因为我们在启动容器时会把宿主机的7000端口映射到容器的6379端口-p 7000:6379。换句话说容器内部统一跑6379外面看到的端口不同。这样做的好处是配置文件可以六份完全一样不用维护六份不同的端口。cluster-enabled yes打开集群模式这一步决定节点是普通Redis实例还是集群节点没这个配置后面初始化必然报错。cluster-config-fileRedis自动生成的集群状态文件记录当前节点和其他节点的关系。这个文件不用我们创建Redis会自己写。cluster-node-timeout 5000节点间通信超时时间单位毫秒。节点超过这个时间没收到另一个节点的响应就会判定对方离线。5000毫秒是官方推荐值我在实验里也验证过这个参数恰到好处既不会因为网络抖动误报也不会让故障切换拖太久。appendonly yes开启AOF持久化。集群模式运行中的数据安全更加重要主节点宕机后从节点晋升AOF能保证晋升后数据不丢太多。protected-mode no关闭保护模式允许外部网络访问。如果是测试环境问题不大生产环境建议配合ACL和防火墙来限制访问来源。如果你对ACL机制有要求还可以在配置里加用户、密码但为了不干扰集群内部通信的演示我先保持最简配置把网络和集群机制讲明白之后再谈安全加固。还有一个配置项appendfilename不用动默认值是appendonly.aof。如果目录下有残留的这个文件初始化集群时可能会出现数据不一致建议在前面建的六个目录保持干净状态。3. 创建Redis Cluster集群网络与容器3.1 为什么要先建Docker自定义网络搭建集群和跑单个容器最大的区别是集群里的节点要能互相通信并且是通过节点名称解析到对方的IP。Docker默认的bridge网络其实没有DNS解析能力容器之间只能通过IP通信。问题是容器每次重启IP可能变化集群节点之间记录的IP就废了。解决办法是创建一个自定义网络在自定义网络里容器可以通过名称直接访问到对方的IP而且这个解析关系是实时更新的。docker network create redis-cluster-net创建完可以用docker network ls确认。网络类型默认是bridge这没问题因为我们后面还会用-p参数把容器的端口映射到宿主机上外部客户端将通过宿主机IP加映射端口访问集群这正是一台机器模拟多节点的正确姿势。3.2 启动6个Redis节点容器网络创建好后开始起容器。我手动逐个启动同时展示完整命令这样你能清楚看到每个参数的含义。虽然实际工作中会用for循环批量启动但初次学习还是一步一步来比较稳妥。先启动第一个节点docker run -d \ --name redis-7000 \ --network redis-cluster-net \ -p 7000:6379 \ -p 17000:16379 \ -v /opt/redis-cluster/7000/redis.conf:/usr/local/etc/redis/redis.conf:ro \ -v /opt/redis-cluster/7000/data:/data \ redis:7.0 \ redis-server /usr/local/etc/redis/redis.conf这条命令的信息量不小我拆开解释--name redis-7000容器名这个名称同时是集群内的节点标识自定义网络里的其他容器可以通过它来访问。--network redis-cluster-net加入前面创建的网络。-p 7000:6379宿主机的7000端口映射到容器的6379端口这是客户端访问端口。-p 17000:16379宿主机的17000端口映射到容器的16379端口这是集群节点间通信的端口。如果不映射不同Docker网络里跑多个节点组多集群时端口就冲突了。-v第一个挂载把宿主机上写好的redis.conf挂载到容器里ro表示只读防止容器内部改动配置。-v第二个挂载把容器的数据目录挂载到宿主机Redis的AOF文件、RDB文件、集群状态文件都会落在宿主机磁盘容器删了数据还在。按照相同方式启动剩下的五个节点需要改的地方只有--name、两个端口映射和数据卷路径docker run -d \ --name redis-7001 \ --network redis-cluster-net \ -p 7001:6379 \ -p 17001:16379 \ -v /opt/redis-cluster/7001/redis.conf:/usr/local/etc/redis/redis.conf:ro \ -v /opt/redis-cluster/7001/data:/data \ redis:7.0 \ redis-server /usr/local/etc/redis/redis.conf后面四个类似需要用7002、7003、7004、7005替换对应的位置。等六个容器都启动后用一下命令确认它们都处于Up状态docker ps六个容器全部在列表里说明容器都正常启动了。这一步我建议你仔细对一下端口映射列0.0.0.0:7000-6379/tcp、0.0.0.0:17000-16379/tcp每个容器都是两条映射。3.3 初始化集群一条命令建立三主三从六个Redis节点现在都只是独立的集群模式节点它们彼此还不知道对方的存在。要让它们组成一个集群需要在任意一个节点上执行集群创建命令。redis-cli --cluster create是Redis 5.0之后官方推荐的方式。命令格式是把六个节点的地址以容器名:端口的方式列出来然后指定每个主节点配几个从节点。docker exec -it redis-7000 \ redis-cli --cluster create \ redis-7000:6379 redis-7001:6379 redis-7002:6379 \ redis-7003:6379 redis-7004:6379 redis-7005:6379 \ --cluster-replicas 1参数说明前三个节点会成为主节点后面三个自动分配为从节点每个主节点一个从节点。这正好对应了3主3从的最小高可用集群。执行之后Redis会先做一轮健康检查然后打印出一份分配方案。这块内容是重点你要记住它长什么样 Performing hash slots allocation on 6 nodes... Master[0] - Slots 0 - 5460 Master[1] - Slots 5461 - 10922 Master[2] - Slots 10923 - 16383 Adding replica redis-7003 to redis-7000 Adding replica redis-7004 to redis-7001 Adding replica redis-7005 to redis-7002这里最关键的信息是槽位分配。整个集群有16384个哈希槽被均分成了三段0-5460归第一个主节点5461-10922归第二个主节点10923-16383归第三个主节点。将来任何一个key写入时先算槽位再看槽位属于谁就去对应的主节点读写。接着Redis会询问你Can I set the above configuration? (type yes to accept):你必须手动输入yes回车。这一步是在确认节点信息和主从关系无误如果自动化脚本里忘了这个交互步骤创建过程就会卡在这里直到超时。确认后Redis会逐个节点发送配置最终打印一段类似下面的信息[OK] All 16384 slots covered看到All 16384 slots covered就说明集群初始化成功了16384个槽位全部有主节点负责没有漏掉任何一个。4. 集群验证与常用操作4.1 用cluster info和cluster nodes检查集群状态集群创建完之后不能急着写业务代码先做一轮验证确保集群真正处于健康状态。连接集群中的任意一个节点执行docker exec -it redis-7000 redis-cli cluster info输出里最核心的三行cluster_state:ok cluster_slots_assigned:16384 cluster_known_nodes:6cluster_state:ok集群状态正常。一旦这个值变成fail说明有槽位丢失或主节点长时间不可用集群会拒绝所有读写请求。cluster_slots_assigned:16384所有槽位都已分配。cluster_known_nodes:6集群里已知的节点总数主从加在一起是6个。再看一下节点间的角色关系docker exec -it redis-7000 redis-cli cluster nodes输出类似c89456c2c1547d5cf579017f7f64e594fcdccb6d 172.20.0.2:637916379 myself,master - 0 1718000000000 1 connected 0-5460每一行代表一个节点。注意看myself,master表示当前这个节点是主节点0-5460表示它负责的槽位范围。对应关系如下redis-7000master槽位0-5460从节点是redis-7003redis-7001master槽位5461-10922从节点是redis-7004redis-7002master槽位10923-16383从节点是redis-70054.2 客户端写入数据并验证hash槽自动跳转接下来动手写入一些key验证集群的读写机制。这里要用redis-cli -c-c表示集群模式。docker exec -it redis-7000 redis-cli -c -p 6379进入交互式命令行后依次执行127.0.0.1:6379 set name zhang - Redirected to slot [5798] located at 172.20.0.3:6379 OK 127.0.0.1:6379 get name - Redirected to slot [5798] located at 172.20.0.3:6379 zhang注意输出里的Redirected to slot。name这个key按CRC16算出来的槽位是5798不属于redis-7000它管0-5460而是落在redis-7001管5461-10922上所以客户端自动跳转到了另一个节点。用redis-cli -c的好处是客户端会自动跟踪重定向。但如果你的业务代码用的客户端库不支持集群模式它会收到一个MOVED错误然后需要自己处理重定向逻辑。现在主流语言客户端比如Java的Jedis、Python的redis-py-cluster、Go的go-redis都支持集群模式就会自动处理这块。4.3 测试故障转移把主节点停掉看从节点如何顶上集群相比手动主从切换的强大之处在于自动故障转移。我们直接做一个小实验把redis-7000这个主节点停掉看它下面的从节点redis-7003会不会自动晋升为主节点。先在主节点上存一个key方便后面验证数据有没有丢docker exec -it redis-7000 redis-cli -c -p 6379 set demo-key before-failover然后直接停止容器docker stop redis-7000等待几秒让集群检测到节点下线。在redis-cluster配置中我们设置了cluster-node-timeout 5000所以大约5秒后集群会认定redis-7000离线。此时从任意存活节点比如redis-7001查看集群节点状态docker exec -it redis-7001 redis-cli cluster nodes你会发现redis-7003的角色从slave变成了master这个变化一般发生在停止容器后5~15秒之间取决于节点间心跳的检测周期。然后验证之前存的那个keydocker exec -it redis-7001 redis-cli -c -p 6379 get demo-key如果返回before-failover说明数据已经从主节点同步到了从节点并且新主节点能正常提供读取服务。这一步直观展示了Redis Cluster在主节点宕机后如何自动完成数据保护和故障转移。再把redis-7000容器启动起来看一下它回来后的角色docker start redis-7000 docker exec -it redis-7001 redis-cli cluster nodes你会发现redis-7000重新加入集群但角色变成了slave它的主节点是原来的从节点redis-7003。这就是集群的自我修复机制掉线的主节点恢复了不会抢回原来的位置而是作为从节点继续复制新主节点的数据。注意这一步测试很重要生产环境发生故障切换后原主节点恢复并不代表它自动再次成为主节点。你需要确认这个行为否则可能误解集群状态。4.4 客户端连接和可视化管理工具集群搭建完成后不管是写代码还是用工具连都要注意集群模式这一点。如果你用命令行从宿主机直接访问redis-cli -h 127.0.0.1 -p 7001 -c-c参数必须带上。不带的话当你访问一个不归该节点管的key客户端只会收到一个MOVED错误提示而不会自动跳转。如果用Java连接Jedis有专门针对集群的APISetHostAndPort nodes new HashSet(); nodes.add(new HostAndPort(127.0.0.1, 7000)); nodes.add(new HostAndPort(127.0.0.1, 7001)); nodes.add(new HostAndPort(127.0.0.1, 7002)); JedisCluster jedisCluster new JedisCluster(nodes); jedisCluster.set(name, zhang); String value jedisCluster.get(name);注意这里只需要传三个主节点的地址即可JedisCluster会从集群里自动获取完整的节点拓扑信息。也可以把六个节点全传进去效果一样。对了很多人在Windows下用Redis Desktop Manager连集群时发现只能连单个节点、看不到完整数据。原因很简单Redis Desktop Manager对集群模式的支持不完整它连接的是单个Redis实例当你访问的key不在这个节点上时工具不知道该往哪跳。早期版本基本只能做单节点操作如果你需要图形化界面我更推荐用Another Redis Desktop Manager它对集群模式的支持会好一些。5. 常见问题与排查技巧实录5.1 问题速查表把踩过的坑直接列给你搭建过程中最容易出的问题我按出现频率排个序做成了一张速查表你可以直接保存报错信息 / 现象原因解决办法ERR Slot 0 is already busy数据目录里有旧的集群状态残留清空对应节点的data目录nodes.conf、appendonly.aof等重启容器creating cluster: unknown commandRedis版本太老不支持集群创建命令升级Redis镜像到5.0及以上Could not connect to Redis at redis-7000:6379容器间网络不通确认所有容器在同一个自定义网络docker inspect 容器名查看Network[ERR] Node redis-7000 is not empty容器里的数据目录还有数据清空节点数据目录后重新初始化客户端连接超时宿主机防火墙未放行端口或者端口映射写错检查docker ps里的端口映射列确认宿主机防火墙放行7000-7005集群初始化卡在等待确认没输入yes命令行交互必须手动输入yesCluster state changed: fail某个主节点长时间不可用且没有从节点故障转移检查宕机节点是否恢复确认主节点上的从节点配置是否正常5.2 三个最容易踩的坑第一个坑容器重启后节点身份信息变了。Redis集群节点在首次启动时会生成一个ID记录在nodes.conf文件里。如果你创建容器时没有挂载数据目录每次重建容器都会生成新的节点ID老节点ID在集群里就变成了幽灵节点表现为历史节点状态残留。解决办法是始终挂载数据卷并且不要随意删除挂载目录下的nodes.conf。第二个坑用错误地址执行集群创建命令。这是新手高频错误。如果redis-cli --cluster create后面跟的是127.0.0.1:7000那Redis写入nodes.conf的节点地址会变成127.0.0.1其他容器访问这个地址时解析到的是容器自身根本连不通这个节点。所以我在前面特意强调用容器名redis-7000而不是宿主机IP来创建集群这样集群内部节点间通信走自定义网络的DNS解析客户端外部访问走宿主机端口映射两条链路互不干扰。第三个坑只清容器没清数据目录。很多时候重启容器发现集群状态还是乱的是因为数据目录里残留了旧的nodes.conf和AOF文件。容器启动时读取到旧配置以为自己还在旧集群里。建议测试过程中每次重建集群都执行一遍清理docker rm -f $(docker ps -aq --filter nameredis-70) rm -rf /opt/redis-cluster/700*/data/*5.3 一个实用的重建脚本既然说到清理那我把我每次重建集群用的脚本贴出来它能一条命令完成清空旧环境-启动六个新节点-创建集群的全流程#!/bin/bash docker rm -f $(docker ps -aq --filter nameredis-70) 2/dev/null docker network create redis-cluster-net 2/dev/null for port in 7000 7001 7002 7003 7004 7005; do rm -rf /opt/redis-cluster/${port}/data/* docker run -d \ --name redis-${port} \ --network redis-cluster-net \ -p ${port}:6379 \ -p 1${port}:16379 \ -v /opt/redis-cluster/${port}/redis.conf:/usr/local/etc/redis/redis.conf:ro \ -v /opt/redis-cluster/${port}/data:/data \ redis:7.0 \ redis-server /usr/local/etc/redis/redis.conf done sleep 3 docker exec -it redis-7000 \ redis-cli --cluster create \ redis-7000:6379 redis-7001:6379 redis-7002:6379 \ redis-7003:6379 redis-7004:6379 redis-7005:6379 \ --cluster-replicas 1这个脚本里每个动作都是上面一步一步操作汇总起来的适合反复练手时使用。我建议你自己动手敲一遍而不是直接复制这样对每条命令的职责会有更直观的感受。6. 实操过程中的几个补充建议6.1 内存和资源限制Redis是内存型数据库Docker容器如果不做资源限制一个节点可以吃掉宿主机所有可用内存。测试环境可能看不出问题但如果你在一台4G内存的机器上跑六个节点数据量一大OOM就找上门了。我建议在docker run命令里加上内存限制-m 1g --memory-swap 1g这样每个Redis容器最多使用1G内存。六个节点最多占6G但你可以在小机器上用-m 512m跑试验环境低配电脑也不会卡死。注意--memory-swap要和--memory保持一致否则容器会用swap空间性能断崖式下跌。6.2 配置持久化与备份前面说过要挂载数据目录这里再强调一下为什么。Docker容器是一次性的删除容器后容器内所有数据都会消失。如果不挂载/data目录你的Redis写进去的数据会随容器删除而灰飞烟灭。生产环境一定要挂载而且要定期备份appendonly.aof或RDB快照到独立存储。# 查看某个节点的数据落盘情况 ls -lh /opt/redis-cluster/7000/data/正常情况下会看到appendonly.aof、nodes.conf这些文件。nodes.conf可以理解为集群的人员名册删掉它不仅数据会乱节点也无法正确恢复集群关系。6.3 生产环境可以改用Host网络模式演示环境里我用的是Docker自定义bridge网络加端口映射好处是可以在单机上跑多个集群互不干扰。但生产环境部署Redis Cluster我反而建议直接用--network host。原因有两点一是端口映射本身有性能损耗虽然不大但Redis这种高QPS场景能少一层转发就少一层二是集群节点间通信的端口号是客户端端口加10000用host模式后网络拓扑更加简单节点地址就是物理网卡IP省去了容器端口映射带来的理解成本。用host模式启动时命令更简单不需要-p参数容器内直接用物理机的IP和端口对外服务docker run -d \ --name redis-7000 \ --network host \ -v /opt/redis-cluster/7000/redis.conf:/usr/local/etc/redis/redis.conf:ro \ redis:7.0 \ redis-server /usr/local/etc/redis/redis.conf但host模式有一个代价如果你在同一台机器上起多个节点端口必须不同配置文件里的port参数就要改。所以host模式更适合分布式多机部署每台机器起一两个节点bridge模式更适合本地学习和单机模拟多节点。6.4 关于安全加固整个集群目前是裸奔状态protected-mode no意味着只要有网络权限任何人都能访问。测试环境无所谓生产环境必须做安全加固用Redis内置ACL创建专门账号最小权限原则设置requirepass主密码集群节点同步也要配置masterauth用iptables/安全组限制只允许业务应用所在网段访问6379和16379端口设置rename-command禁用危险命令如FLUSHALL、CONFIG配置了密码之后集群创建命令会稍微复杂一点需要在redis-cli -a 密码或配置文件里指定密码信息。这些属于进阶内容等基础集群跑通之后再研究也来得及。6.5 集群扩容时的思考方向这套三主三从集群搭建好之后很多人的下一步是想知道如何扩容。这里我可以先给一个思路框架向集群里加入新节点可以用redis-cli --cluster add-node然后通过redis-cli --cluster reshard把一部分槽位从旧主节点迁移到新主节点。这两步操作的实际效果相当于把百科全书的某一册拆成两册原有数据不会丢失但键的分布会重新洗牌。扩容中值得注意的是会触发大key的迁移导致网络和磁盘IO瞬时升高。生产环境做扩容最好选择业务低峰期并且提前用redis-cli --bigkeys检查有没有超大key。写在最后这套Docker里跑Redis Cluster的流程我前前后后在不同机器上搭过很多遍从最开始一头雾水到后来十分钟搞定最大的感触是会者不难这四个字背后全是踩坑积累出来的经验。如果你按这篇文章一步步走完遇到问题能自己定位到是网络、配置还是数据残留那说明你真的入门了。我个人在实际操作中的体会是命令本身不是难点真正决定你能不能顺利把集群跑起来的是对几个关键机制的透彻理解——槽位怎么分、节点怎么通信、主从怎么切换。建议你把这篇文章里的命令反复敲几遍每跑通一遍你对Redis Cluster的理解就会深一层。后面如果想继续深入建议自己动手做一次集群扩容和缩容那才是真正检验理解程度的好方法。最后分享一个小技巧每次实验前把docker logs和nodes.conf文件都保留好集群报错时先把这两个地方的日志看完80%的问题就已经有了头绪。