大家好呀,我是 31 岁、爱喝奶茶、爱写 bug、爱分享技术的小米同学。
今天继续给大家讲一个我亲身经历的——被 Redis Cluster 当场“拷打” 的面试故事。
事情是这样的。
开局:我满怀自信进场,结果第一问就被“击倒”
那天我穿着我最喜欢的“小恐龙卫衣”,满怀信心走进一家互联网公司的会议室。
面试官看了我一眼,笑了一下,说:“你写 Java,这几年应该用过 Redis 吧?”
我心里说:那必须哇!缓存我天天写,Redis 我恨不得能背着跑。
结果他下一句:
“那说说 Redis Cluster 是怎么回事?slot 分片是什么?为什么 16384?集群怎么保证高可用?脑裂怎么解决?Java 程序用 Redis Cluster 要注意什么?Multi-key 操作是不是支持?”
我当场:???
这哪是一个问题,这是整个 Redis Cluster 全家桶啊!但作为一个“技术博主小米”,我当然不能怂。
于是这个故事,今天我就用最轻松的方式,全部讲给你听。
Redis Cluster 是什么?我用一个快递站点的故事解释
我跟面试官说:“要是让我用一句话讲,它就是 Redis 的分布式集群解决方案。”
为了让对方觉得我不是背书,我给他讲了个故事:
想象 Redis 是一个快递站点,一个站点最多只能送这么多包裹。
当包裹越来越多时,就要建更多快递站点,并且把包裹按照一定规则分到不同站点存放。
而 Redis Cluster 就是——
把所有键按 slot 分片,分到多个节点上,每个节点就像一个快递分站,负责一部分包裹(key)。
面试官点点头。我继续说:
Redis Cluster 主要解决两个问题:
数据分片——怎么把数据分散到多个节点?
高可用——一个节点挂了怎么办?服务是否还能继续?
Redis Cluster 两者都解决了。于是我们来说重头戏:slot。
16384 个 slot 是怎么回事?我用红包分配来解释
我继续讲故事:
你想象一下,你是个超有钱的人,想拆分 16384 个红包,
然后把它们分别塞到各个“红包袋”(Redis 节点)里面。
每个红包袋负责固定数量的红包。
客户端只要知道一个 key 的 slot 落在哪个红包袋,就能准确找到它的值。
这时候面试官忍不住笑了:“这么解释不错,你讲具体一点。”
于是我(小米)就把关键点讲出来:为什么是 16384?
因为:
- 槽位越多,集群越均匀,迁移成本越低
- 16384 是 2^14,足够均匀,又不会使节点处理 slot 消息太慢
- Redis 作者 antirez 考虑了性能和可维护性,最终定这个值
slot 怎么算?
Redis 用 CRC16:slot = CRC16(key) % 16384
这个公式我没背,但意思我说对了。面试官点点头——表示我过关了第一轮。
Cluster 的主从结构:我用“备胎节点”把面试官逗笑了
接着他问:“分片之后怎么保证高可用?”
我说:“Redis Cluster 每个主节点(master)都会挂一个备胎(slave)。”
面试官乐了:“备胎听上去不错,你继续说。”
我继续把故事说完整:
每个 master 负责部分 slot
每个 slave 复制对应 master 的数据
当 master 掉线后
集群会自动把它的 slave 扶正变成新的 master
整个过程不会让业务停顿
用图来说就是:
这就是 Redis Cluster 高可用的基础。这些内容面试官继续满意地点头。
故障检测:Redis Cluster 的“自我修复能力”
面试官紧接着问:“那 Redis 怎么知道哪个节点挂了?”
我立刻说:
Redis Cluster 有 gossip 协议 + 心跳机制。
每个节点都会与其它节点发送 ping/pong:
- 如果某节点连续几次没有响应,它就会被标记为:pfail(疑似宕机)
- 再进一步,大部分节点都认为它挂了,就会变成:fail(正式宕机)
- 这时 slave 就会被推举为新的 master。
这一段讲完后,面试官又点头了,感觉我已经拿到 70 分了。
真正难点:Redis Cluster 如何选举新主节点?
他接着问:“那 slave 是怎么被选举成 master 的?”
我说:选举和 Raft 一样吗?不是!
Redis Cluster 的 slave 选举逻辑更轻量。核心规则:
- 延迟最小的 slave 优先: 数据最接近最新 master
- 复制 offset 最大者优先: 意味着数据同步最完整
- 如果有多个候选人,节点 ID 小的优先: 其实是为了 deterministic
我用一句话总结:
Redis Cluster 的主从切换依赖“谁的数据最新,谁最早同步”,不是像 Raft 那样玩投票竞选,而是更简单直接。
大坑:Redis Cluster 不支持 multi-key 操作?!
讲完这些,面试官突然问:
“那 Redis Cluster 支持 multi-key 事务吗?”
我深吸一口气:终于来了。我跟他说:
答案是:不支持跨 slot 的 multi-key。
比如:MSET a 1 b 2,如果 a 和 b 的 slot 不同:会被拒绝
面试官点点头。我继续讲重点:如何让多个 key 在同一个 slot?
Redis 提供 hash tag, 比如:
因为 {order} 是相同的,所以它们会被 hash 到同一个 slot,multi-key 就能成立了。
面试官笑得更开心了:“你这讲得很完整。”
防止脑裂(split-brain):Redis Cluster 的隐藏绝招
我以为面试结束了,但没想到对方又问关键问题:
“Redis Cluster 怎么避免脑裂?如果 master 和 slave 网络分区怎么办?”
我继续讲故事:
当 master 被一部分节点认为挂了,而它自己其实还活着,这就是脑裂的前奏。Redis Cluster 的解决方式是:
至少半数 master 节点认为某 master fail 后,才会触发故障转移, 避免单节点误判。
而且 master 还能用:cluster-node-timeout,避免长时间收不到心跳的节点“误以为”对方已挂。
Java 程序如何连接 Redis Cluster?
最后面试官问:“那 Java 用 Redis Cluster,需要注意什么?”
我果断说:
1、要用支持 cluster 的客户端:
- JedisCluster
- Lettuce ClusterClient
2、客户端会自动完成 MOVED 重试
- 也就是当 key 被迁移时,Redis 会返回:MOVED 1234 10.10.1.3:7001,客户端会自动重定向。
3、最好开启连接池,多节点连接池,否则容易卡死
4、关闭 Pipeline 和事务(cluster 中不推荐)
5、key 一定要用 hash tag, 否则多 key 操作经常失败
6、业务层注意热点 key, 集群再分片,也扛不住单节点打满。
这些都是 Java 场景真正会遇到的问题。面试官非常满意,让我回去等消息。
总结:Redis Cluster 面试必背七大点
我最后在文章里帮你总结一下:
Redis Cluster 七大面试必答项:
Redis Cluster 是 Redis 的分布式分片 + 高可用方案
使用 16384 slot 分片
slot = CRC16(key) % 16384
主从结构,每个 master 对应若干 slave
故障检测:gossip + pfail/fail
主从切换:slave 根据 offset 领先度自动晋升
不支持跨 slot 的 multi-key;用 hash tag 解决
面试官一般就考这些。
END
面试结束后我去楼下买了杯奶茶。那天不是我运气好,而是我真的把 Redis Cluster 学明白了。
如果你准备 Java 社招,这篇文章就是你对 Redis Cluster 最完整的一份“通关手册”。
我是小米,一个喜欢分享技术的31岁程序员。如果你喜欢我的文章,欢迎关注我的微信公众号“软件求生”,获取更多技术干货!