1. Redis 主从复制原理?全量同步和增量同步?

复制过程:

  1. 从库执行 SLAVEOF master_ip port(或配置 replicaof),发送 psync 请求
  2. 全量同步:主库生成 RDB 快照(BGSAVE)→ 传输给从库 → 从库加载。期间新写入的命令进 该从库的复制客户端输出缓冲区(受 client-output-buffer-limit replica 限制,超限会断开从库)—— repl_backlog 是主库的全局环形缓冲,只服务断线后的部分重同步,不要混淆
  3. RDB 加载完,主库把缓冲区增量命令发给从库追平
  4. 增量同步(断线重连):repl_backlog(环形缓冲)只有主库有;从库只记录自己的 master_repl_offset,断线期间主库命令仍写 backlog,重连后从库发 psync(offset),主库把 offset 之后的命令补发。offset 太旧(超出 backlog)→ 退化为全量同步

主从读写分离:主写从读。但注意:主从是异步复制,从库可能有延迟,且写主读从有"读不到刚写的"问题。

🎯 面试要点

  • 全量同步在从库重启/网络长期断开时会发生,大实例会阻塞主库 fork → 调大 repl-backlog-size(默认 1MB)
  • 从库默认只读(replica-read-only yes);从库也可以再挂从库(级联,减轻主库压力)
  • 传播方式:主库写命令同时写 repl backlog 和 AOF(如开启)

2. 哨兵(Sentinel)机制?故障转移流程?

哨兵:独立的监控进程集群(通常 3 个),监控主从、自动故障转移、通知客户端新主地址。解决"主挂了怎么办"。

关键概念:

🎯 面试要点

  • 哨兵数量取奇数(3/5/7),> 半数在线才能判定客观下线——2 个哨兵就有单点风险
  • 脑裂风险:主库与哨兵断连但仍在运行 → 哨兵提升新主 → 旧主恢复后数据冲突。缓解:min-replicas-to-write 配置(写前至少 N 个从库确认),旧主写不进去
  • 客户端通过 sentinel get-master-addr-by-name 动态获取主地址(Redisson 原生支持)

3. Cluster 集群原理?哈希槽?

Cluster(Redis 3.0+):无中心化集群,解决单机容量和吞吐瓶颈。

多 key 操作的约束
# 不同 key 的槽不同 → 多 key 命令(MGET/MSET/LUA)会报错
MGET user:1 user:2
# (error) CROSSSLOT Keys in request don't hash to the same slot

# 解决:使用 hash tag,让 key 落同一槽
MGET {user}:1 {user}:2      # {} 内部分参与 CRC16,两个 key 同槽
# 代价:同 tag 的 key 集中在同一节点,热点倾斜

🎯 面试要点

  • 16384 槽的原因:心跳包中槽位 bitmap 2KB,gossip 传输划算;超过 1000 节点网络消息量大(官方建议 ≤ 1000 节点)
  • Cluster 不支持:多 key 操作(除非 hash tag)、Lua 跨槽、事务跨槽
  • 对比哨兵:哨兵解决"高可用",Cluster 解决"高可用 + 水平扩展";小数据量用哨兵即可
  • 客户端缓存槽映射(JedisCluster/Redisson 都有 ClusterConnection),MOVED 触发刷新

🎤 常见面试追问

  1. 全量同步和增量同步什么时候发生?——从库首次连接/断线太久(offset 超出 backlog)→ 全量(RDB);断线重连且 offset 还在 backlog 内 → 增量补发。
  2. 哨兵是怎么防止误判的?——主观下线是单个哨兵判断,客观下线要"多数哨兵都判定"(投票)——避免网络抖动导致单点误判切换。
  3. Redis 脑裂是什么?怎么缓解?——主库与哨兵断连但仍在运行,哨兵提升新主,旧主恢复后两边都写 → 数据冲突。缓解:min-replicas-to-write 配置(写前至少 N 个从库确认)。
  4. Cluster 的哈希槽为什么是 16384?——心跳包里槽位用 bitmap 表示(16384 bit = 2KB),gossip 传输划算;官方建议节点 ≤ 1000,16384 足够且均衡。
  5. Cluster 下多 key 操作怎么办?——不同 key 的槽不同会报 CROSSSLOT 错误。解决:hash tag({user}:1)让 key 落同一槽,代价是可能热点倾斜。

📖 名词解释(本页术语)

术语 大白话解释
主从复制主库写、从库同步(全量 RDB + 增量 backlog),读写分离、数据备份。
repl_backlog主库的环形命令缓冲:从库断线后靠它增量补发;溢出则全量重来。
哨兵(Sentinel)监控主从、自动故障转移的进程(3 个起):主挂后自动选新主并通知客户端。
主观下线 / 客观下线单个哨兵判定主库超时(sdown);多数哨兵都判定(odown)才真正切换。
Cluster 集群无中心集群:16384 个哈希槽分散到节点,支持水平扩展,自动故障转移。
哈希槽 / MOVED / ASKkey 按 CRC16 % 16384 定位槽,槽归属节点;请求发错节点返回 MOVED(客户端重定向到正确节点)或 ASK(迁移中)。
hash tag{} 内的内容参与哈希计算,让多个 key 落同一槽(支持多 key 操作),可能热点倾斜。
脑裂网络分区导致"双主"同时写数据。用 min-replicas-to-write 限制旧主写入缓解。
⚠️ 本页面由 AI 生成,内容仅供参考,请以官方文档和实际源码为准。