
Redis Cluster 中如何使用 CLUSTER MEET 命令手动加入新节点
一、为什么需要手动加入节点?
Redis Cluster 是 Redis 官方提供的分布式解决方案,它通过数据分片将键分散到多个节点上,每个节点只负责一部分数据。在实际运维中,我们经常需要扩容集群——比如业务量增长,原有的节点扛不住了,就要加入新的 Redis 实例来分担压力。虽然redis-cli --cluster add-node工具可以自动完成添加操作,但它的底层实际上调用了CLUSTER MEET命令。直接使用CLUSTER MEET不仅能让我们更精细地控制节点加入的过程,还能帮助我们深入理解 Redis Cluster 的成员发现机制。
想象这样一个场景:你已经有三个节点组成的集群,现在新启动了一个 Redis 实例(比如在 192.168.1.100:6380),想让这个新节点成为集群的一员。如果你不了解CLUSTER MEET的原理,可能会觉得这个过程很神秘。实际上,它就是一次握手——一个已有的节点主动向新节点打招呼,然后新节点通过 Gossip 协议逐渐被整个集群认识。
二、CLUSTER MEET 命令的作用与原理
2.1 命令语法与执行效果
CLUSTER MEET的完整语法非常简单:
CLUSTER MEET ip port其中ip和port是要加入集群的目标节点地址。执行这条命令的节点(我们称为“邀请方”)会主动向目标节点发送一个 MEET 消息。目标节点收到消息后,会尝试与邀请方建立 TCP 连接,双方开始交换集群元数据——包括各自的节点 ID、负责的槽位范围、主从关系等等。
这个过程就像你在一个聚会上,你(邀请方)看到一个陌生人(新节点),走过去说:“嘿,我是张三,这是我的名片,认识一下吧。” 对方回应后,你们俩就成了朋友。然后你们各自又会把自己认识的朋友介绍给对方,慢慢地整个聚会的人都相互认识了。
2.2 基于 Gossip 协议的成员扩散
Redis Cluster 的节点之间通过 Gossip 协议来传播信息。每个节点会定期随机选择几个已知节点,发送 PING 消息,收到 PONG 消息后更新对方的存活状态和元数据。当新节点通过CLUSTER MEET被一个节点认识后,这个节点会在下一次 Gossip 消息中将新节点的信息广播出去。其他节点收到后,也会尝试与新节点建立连接。经过几轮 Gossip 传播,整个集群的所有节点最终都会认识这个新节点。
需要特别注意的是,CLUSTER MEET只负责建立成员关系,并不会自动分配槽位。在 Redis Cluster 中,一共有 16384 个哈希槽,数据根据键的 CRC16 值取模后映射到某个槽,每个槽由某个主节点负责。新加入的节点如果不分配任何槽位,它就只是一个空的主节点,无法服务数据。集群状态依然是ok,因为所有槽位仍然由原有节点覆盖。要让新节点真正承载数据,还需要使用CLUSTER ADDSLOTS或CLUSTER SETSLOT命令分配槽位,或者借助redis-cli --cluster reshard工具进行槽位迁移。
2.3 为什么需要手动 MEET?
Redis 节点在正常运行时,会通过 PING/PONG 消息交换已知节点列表,但这依赖于节点之间已经建立过连接。当一个全新的节点刚刚启动时,它只知道自己的存在,集群中其他节点根本不知道它的存在。CLUSTER MEET就是打破这种信息孤岛的敲门砖——它让一个已有节点主动把新节点的地址告诉给目标节点,从而完成首次接触。后续的信息扩散则完全交给 Gossip 协议自动完成。
理解这一点很重要:如果你只是启动了新节点而不执行CLUSTER MEET,这个节点就一直是个孤岛,既不能被集群识别,也无法参与数据服务。
三、Windows 环境下准备多个 Redis 实例
3.1 下载与解压 Redis
在 Windows 上模拟 Redis Cluster,最方便的方式是单机多实例——在同一台机器上启动多个 Redis 进程,每个进程使用不同的端口和配置文件。首先,你需要下载 Windows 版的 Redis。推荐从官方 GitHub 仓库的 Releases 页面下载 zip 包(例如 Redis-x64-xxx.zip),将其解压到一个方便的位置,比如C:\Redis。注意不要解压到 Program Files 等受保护目录,否则后面写配置文件时会遇到权限问题。
3.2 创建多个实例的配置文件
假设我们要启动三个实例,端口分别为 7000、7001、7002。在C:\Redis下创建三个子目录,比如C:\Redis\7000、C:\Redis\7001、C:\Redis\7002。将解压得到的redis.windows.conf文件分别复制到这三个目录中,并修改以下关键参数:
- port:每个实例的端口,例如 7000、7001、7002。
- cluster-enabled yes:开启集群模式。
- cluster-config-file:指定集群配置文件名称,必须每个实例不同,例如
nodes-7000.conf、nodes-7001.conf、nodes-7002.conf。如果两个实例使用了相同的文件名且工作目录相同,会导致互相覆盖,集群状态混乱。 - appendonly yes:开启 AOF 持久化,便于测试时恢复数据。
- logfile:指定日志文件路径,例如
C:\Redis\7000\redis.log。 - bind 127.0.0.1:绑定本地地址,避免外部访问。如果你需要局域网内其他机器访问,可以绑定实际 IP 或 0.0.0.0。
- protected-mode no:如果绑定了 127.0.0.1,可以保留 protected-mode yes;但如果绑定 0.0.0.0,建议设置为 no,否则外部连接会被拒绝。
另外,建议将daemonize设为 no(默认),因为在 Windows 下 Redis 通常以前台方式运行,方便观察日志。
3.3 启动多个实例
打开三个命令行窗口,分别进入C:\Redis\7000、C:\Redis\7001、C:\Redis\7002目录,执行:
redis-server.exe redis.windows.conf注意:路径分隔符必须使用反斜杠,不能写成斜杠。如果启动成功,你会看到 Redis 打印出 logo 和一些启动信息,其中包括集群模式已启用。每个实例会在对应目录下生成nodes-7000.conf等文件,记录节点 ID 和初始槽位信息(此时为空)。
3.4 常见坑与注意事项
- 防火墙:Windows 防火墙可能会阻止本地回环连接,建议暂时关闭防火墙或添加入站规则允许 127.0.0.1 的端口。
- 旧集群文件:如果之前运行过集群,
nodes-*.conf文件会残留旧的集群 ID,可能导致新节点加入时出现冲突。建议每次测试前删除这些文件,让 Redis 重新生成。 - 端口占用:确保 7000、7001、7002 没有被其他程序占用。可以用
netstat -ano | findstr :7000检查。
四、使用 CLUSTER MEET 手动组建集群
4.1 建立成员关系
假设我们已经启动了 7000、7001、7002 三个实例。现在打开一个新的命令行窗口,进入C:\Redis目录,执行以下命令让 7000 节点认识 7001 节点:
redis-cli -h 127.0.0.1 -p 7000 cluster meet 127.0.0.1 7001如果成功,会返回OK。接着再让 7000 认识 7002:
redis-cli -h 127.0.0.1 -p 7000 cluster meet 127.0.0.1 7002现在,7000 已经与 7001、7002 建立了连接。由于 Gossip 协议的存在,等几秒钟后,你可以查看任意一个节点的集群节点列表:
redis-cli -h 127.0.0.1 -p 7000 cluster nodes输出应该显示三个节点,每个节点都有一个唯一的 ID,状态为connected。如果某个节点的状态是fail或handshake_fail,说明连接有问题,需要检查端口是否可达、防火墙是否拦截。
4.2 分配槽位
成员关系建立后,集群仍然无法正常工作,因为没有分配槽位。此时如果尝试写入键,会收到CLUSTERDOWN Hash slot not served错误。我们需要将 16384 个槽平均分配给三个主节点。
一种简单的方法是用redis-cli --cluster fix自动修复,但为了演示手动操作,我们可以分别连接到每个节点执行CLUSTER ADDSLOTS。例如:
- 连接到 7000:
redis-cli -h 127.0.0.1 -p 7000执行CLUSTER ADDSLOTS {0..5460}(注意:Windows 命令行不支持大括号展开,需要逐个添加或使用脚本。实际生产中建议用redis-cli --cluster add-node配合--cluster-slots参数。) - 连接到 7001:分配槽位 5461 到 10922
- 连接到 7002:分配槽位 10923 到 16383
分配完成后,再次执行cluster info可以看到cluster_state:ok,并且cluster_slots_assigned为 16384。
4.3 验证集群状态
使用redis-cli -h 127.0.0.1 -p 7000 cluster info查看集群概要信息。重点关注:
cluster_state:应为ok。cluster_slots_assigned:应为 16384。cluster_known_nodes:应为 3(如果只有主节点)。
使用cluster nodes可以查看每个节点的 ID、IP:端口、角色(master/slave)、负责的槽位范围。如果一切正常,说明手动组建集群成功。
五、验证与常见问题
5.1 验证数据读写
你可以尝试写入一个键,看看是否能正确路由到对应的节点。例如:
redis-cli -h 127.0.0.1 -p 7000 set name "hello"如果返回OK,说明集群可以正常写入。再用get name读取。注意,由于集群模式下客户端需要支持重定向,普通redis-cli默认会跟随 MOVED 重定向,所以直接使用即可。
5.2 常见问题排查
问题一:执行 CLUSTER MEET 后,节点状态为 fail
原因通常是目标节点不可达。检查目标节点的端口是否开放、防火墙是否允许、bind 配置是否正确。另外,如果目标节点已经属于另一个集群(比如之前遗留的 nodes.conf 文件),也会导致拒绝握手。解决办法是删除旧的 nodes.conf 文件并重启实例。
问题二:集群状态一直显示 cluster_state:fail
这通常是因为某些槽位没有被任何节点负责。用cluster slots命令查看槽位分配情况,如果发现某些槽位缺失,需要用CLUSTER ADDSLOTS补充。
问题三:新节点加入后,Gossip 传播很慢
Gossip 协议有一定的延迟,通常在几秒到几十秒内所有节点会相互认识。如果长时间不一致,可以尝试手动执行CLUSTER MEET让其他节点也认识新节点。或者检查节点之间的网络延迟。
问题四:Windows 下 cluster-config-file 路径问题
如果两个实例的cluster-config-file都设为nodes.conf且工作目录相同,会导致文件互相覆盖,集群状态混乱。务必为每个实例指定独立的文件名,例如nodes-7000.conf、nodes-7001.conf。
5.3 如何优雅地移除节点
当需要把节点从集群中移除时,不能直接杀死进程,否则其他节点会将其标记为fail,并且槽位可能丢失。正确做法是先迁移该节点上的槽位到其他节点,然后执行CLUSTER FORGET <node-id>在每个剩余节点上遗忘该节点。如果只是临时下线,可以正常关闭 Redis 实例,集群会在一段时间后(由node-timeout控制)将其标记为pfail,但不会立即影响服务。
六、总结
CLUSTER MEET是 Redis Cluster 成员发现的基石。通过手动执行这条命令,我们可以精确控制节点加入的时机,并且深刻理解 Gossip 协议如何让集群自动完成信息同步。在 Windows 环境下,通过单机多实例模拟集群是一种低成本的学习和测试方式,只需要注意配置文件隔离、端口不冲突、防火墙放行等细节。
掌握了CLUSTER MEET,你就掌握了 Redis Cluster 扩容的第一步。后续再结合槽位迁移、主从复制等操作,就能游刃有余地管理生产环境中的 Redis 集群了。
Redis ClusterCLUSTER MEET节点加入修改时间:2026-08-21 08:14:15