目录
[一、集群组建:网点 "握手结盟"](#一、集群组建:网点 “握手结盟”)
[二、槽位分片:网点 "划分服务区域"](#二、槽位分片:网点 “划分服务区域”)
[三、槽位指派:网点 "认领服务区域"](#三、槽位指派:网点 “认领服务区域”)
[五、扩缩容:网点 "动态调整服务区域"](#五、扩缩容:网点 “动态调整服务区域”)
[八、与主从、哨兵的衔接:集群的 "进阶协作"](#八、与主从、哨兵的衔接:集群的 “进阶协作”)
[九、总结:集群的 "连锁银行哲学"](#九、总结:集群的 “连锁银行哲学”)
如果把 Redis 主从、哨兵比作 "单银行的总 - 分公司 + 安保团队",那Redis 集群就是 "连锁银行的多网点协作体系"------ 多家银行网点(集群节点)分工存储客户账户,通过 "区域划分(槽位 slot)" 保证每个账户有专属网点,同时支持故障转移、动态扩缩容。
一、集群组建:网点 "握手结盟"
连锁银行的各个独立网点(初始独立的 Redis 节点),需要 "握手结盟" 才能组成集群。比如有 3 个网点(端口 7000、7001、7002),7000 网点向 7001、7002 发 "结盟请求(CLUSTER MEET
命令)",过程像
-
7000 网点(节点 A)给 7001 网点(节点 B)发 "结盟信(MEET 消息)",声明 "我是 7000,想和你结盟";
-
7001 网点收到信,给 7000 回 "收到结盟信(PONG 消息)";
-
7000 再回 "确认收到你的回复(PING 消息)",双方 "握手成功",加入同一集群。
对应 Redis 节点通过
CLUSTER MEET
建立连接,互相同步 "集群节点列表(clusterState.nodes
字典)",记录所有结盟网点。
二、槽位分片:网点 "划分服务区域"
连锁银行要给每个网点划分 "服务区域",保证每个客户账户(键)都属于某一区域。Redis 集群把 "账户区域" 抽象为16384 个槽位(slot),用算法给每个账户(键)分配槽位:
-
计算方式:
槽位 = CRC16(账户名) & 16383
(将账户名哈希后,取 0~16383 的编号,确保每个键对应唯一槽位)。 -
区域分配:比如 7000 网点负责 "0~5000 号槽位",7001 负责 "5001~10000 号槽位",7002 负责 "10001~16383 号槽位"。
客户 "张三" 的账户名哈希后对应槽位 10086,属于 7002 网点的 "10001~16383 号区域",因此 7002 网点负责处理张三的存款、取款。
三、槽位指派:网点 "认领服务区域"
每个网点要 "认领自己的服务区域(槽位)",通过CLUSTER ADDSLOTS
命令声明。比如 7000 网点执行CLUSTER ADDSLOTS 0 ... 5000
,表示 "我负责 0 到 5000 号槽位"。
-
节点内部记录 :每个节点用 二进制位数组(
slots
数组)标记负责的槽位(如槽位 0 对应数组第 0 位,值为 1 表示 "该槽位归我管")。 -
集群全局记录 :整个集群的
clusterState.slots
数组,每个槽位对应 "负责节点的指针"(如槽位 10086 的指针指向 7002 节点,所有节点都能查这张 "全局区域分配表")。
银行总部的 "区域分配表" 里,10086 号区域的负责人是 7002 网点,所有网点都能通过这张表,知道每个区域该找哪家网点。
四、客户端访问:"自动找对网点"
客户(客户端)要办业务(执行命令)时,流程像:
-
客户先找任意一个网点(比如 7000),说 "我要给张三存钱";
-
7000 网点计算张三的槽位是 10086,发现 "这不是我的区域",就告诉客户:"张三的业务归 7002 网点,你去
127.0.0.1:7002
办理(返回MOVED 10086 127.0.0.1:7002
)"; -
客户转向 7002 网点,重新发起请求,成功办理。
这就是 Redis 的MOVED
重定向机制,保证客户端最终能找到 "负责该键的节点"。
五、扩缩容:网点 "动态调整服务区域"
如果连锁银行要开新网点(如 7003),需要重新分片(调整槽位分配),由 "集群管理工具(redis-trib)" 自动完成,过程类似:
-
新网点 7003 向目标网点(比如 7002)声明 "我要接管部分区域(槽位)";
-
7002 网点把 "自己负责的部分槽位(如 12000~13000)" 的账户,原子迁移到 7003(确保迁移过程中业务不中断);
-
迁移完成后,集群更新 "全局区域分配表",让 12000~13000 号槽位的负责人变成 7003。
银行把 7002 网点的 "12000~13000 号区域客户" 整体转移到新网点 7003,客户后续业务直接找 7003,无需感知迁移。
六、高可用:"网点故障自动换班"
集群中的每个网点有 "主网点(master)"和"备用网点(slave)"。比如 7000 主网点有 7004、7005 两个备用网点:
-
若 7000 主网点故障,备用网点会竞选 "新主网点";
-
当选的新主网点(比如 7004)会 "接管原主网点的所有槽位",继续处理对应区域的业务;
-
故障主网点恢复后,会变成新主网点的 "备用网点"。
7000 网点临时停业,7004 网点自动升级为 "新主网点",接管 7000 的所有区域客户,客户办业务时无感知。
七、节点通信与故障检测:"网点间互相查岗"
集群节点之间每秒互相发送 PING/PONG 消息,检测对方是否在线:
-
若某网点长时间不回 PONG,会被标记为 "疑似下线(PFAIL)";
-
若超过半数主网点都认为该网点 "疑似下线",则标记为 "已下线(FAIL)",触发故障转移。
银行网点互相打电话查岗,若多数网点都联系不上某网点,就判定它 "停业了",立刻启动备用网点。
八、与主从、哨兵的衔接:集群的 "进阶协作"
-
集群的 "主从节点" 复用了主从复制的同步逻辑(从节点复制主节点数据);
-
集群的 "故障转移" 比哨兵更自动化(无需单独哨兵进程,节点间自主协商选举新主);
-
槽位分片是集群独有的特性,解决了 "单主节点内存 / 写能力受限" 的问题(主从、哨兵仅解决 "高可用",不解决 "数据分片")。
九、总结:集群的 "连锁银行哲学"
Redis 集群就像 "智能连锁银行":
-
用槽位分片实现 "多网点分工存储",突破单节点的内存、性能瓶颈;
-
用节点握手组成 "协作网络",共享全局槽位分配;
-
用主从 + 故障转移保证 "单点故障不影响业务";
-
用动态重分片支持 "网点(节点)的扩缩容"。
这套机制让 Redis 能支撑更大规模的业务(海量数据、高并发),同时保持高可用,如同连锁银行能服务更多客户,且某一网点停业不影响整体服务。