📖 版块 A:知识讲解版 (温故知新)
-
Redis Cluster 的核心通信协议:Gossip Redis 集群(Redis Cluster)采用无中心化架构,节点之间通过 Gossip(流言)协议 来传播状态、发现故障和维护集群视图。
- 核心原理:每个节点会按一定频率随机挑选几个其他节点,发送
PING消息(包含自己及已知的其他节点状态);对方收到后回复PONG消息。 - 周期性触发:Gossip 通信是由 Redis 的时间事件(
clusterCron函数)周期性触发的。比如每秒执行 10 次,随机选 5 个节点,向其中最久未通信的节点发送 Ping。 - 去中心化:通过这种多轮、随机的信息交换,整个集群最终能够就哪些节点存活、哪些节点负责哪些 Hash Slot(槽位)达成一致(最终一致性)。
- 核心原理:每个节点会按一定频率随机挑选几个其他节点,发送
-
Redis Cluster 数据重定向(请求路由) 当客户端发起读写请求,但数据(Key)所在的 Slot 并不在当前连接的节点上时:
- MOVED 重定向:说明该 Slot 已经完全由其他节点负责。Redis 返回
MOVED slot_id ip:port,告诉客户端以后去找新节点。 - ASK 重定向:说明该 Slot 正在进行数据迁移,部分 Key 在旧节点,部分在新节点。如果旧节点没找到,返回
ASK ip:port告诉客户端去新节点找(仅限本次请求)。
- MOVED 重定向:说明该 Slot 已经完全由其他节点负责。Redis 返回
-
Redis Cluster 的数据迁移过程 Redis 使用
clusterState结构体来管理 16384 个哈希槽(Slot)的状态。 当集群扩容或缩容时,涉及 Slot 的迁入迁出,状态分别记录在:migrating_slots_to:当前节点负责的 Slot 正在迁往哪里。importing_slots_from:当前节点正在接收从哪里迁入的 Slot。 整体流程:
- 标记源节点迁出(MIGRATING),目标节点迁入(IMPORTING)。
- 获取需要迁移的 keys。
- 通过
MIGRATE命令实际转移数据(保证原子性)。 - 迁移完成后,清除中间状态标记,并向集群广播新的 Slot 分配信息。
🎤 版块 B:面试实战版 (高手逐字稿)
Q:讲讲Redis的Gossip协议是怎么工作的?Redis集群的数据迁移是怎么完成的?
💬 高手逐字稿:
Redis Cluster 之所以能做到去中心化的架构,底层依赖的就是 Gossip 协议。
Gossip 的工作机制就像“流言蜚语”在人群中传播一样。在 Redis 内部,它依托于时间事件驱动,也就是 clusterCron 函数周期性地触发。每个节点每秒会随机挑出几个其他节点,然后选中其中通信最久远的那一个发送 PING 消息。这个消息里面不仅有自己的心跳信息,还打包了自己所知道的集群中其他节点的状态和哈希槽(Slot)分配信息。对方收到后会回复 PONG。经过这样几轮的多点随机交互,哪怕集群有几百个节点,大家很快就能对整个集群的拓扑状态达成一致了。
谈到集群的运维,最核心的就是扩缩容导致的数据迁移。
Redis 集群把数据映射到 16384 个哈希槽里。当发生数据迁移时,比如把 Slot 1 从节点 A 迁到节点 B,在底层数据结构中,节点 A 会把自己标记为 migrating(迁出中),节点 B 标记为 importing(迁入中)。
这个过程是渐进式的。由于迁移期间系统还要对外提供服务,如果客户端向节点 A 请求一个 Key: 第一种情况:这个 Key 还没被迁走,节点 A 就会直接处理并返回。 第二种情况:这个 Key 已经被迁到了节点 B,节点 A 找不到数据,就会给客户端返回一个 ASK 错误。客户端收到 ASK 之后,知道“哦,数据搬家搬到一半了”,它会拿着这个请求临时去节点 B 请求数据。 等整个 Slot 全部迁移完毕,节点 A 和 B 就会通过 Gossip 协议向全网广播新的路由表。之后如果客户端再来找节点 A 要这个 Slot 的数据,节点 A 就会直接返回 MOVED 错误,让客户端永久性地更新本地缓存,以后直接去访问节点 B。
这种通过底层的 migrating 和 importing 状态机机制配合客户端重定向的设计,完美保证了 Redis Cluster 在动态数据迁移期间的高可用。