如果说上篇解决的是 Redis 高频基础题怎么答稳那么下篇解决的就是面试官继续往深处追时你怎么不慌。这篇重点放在更容易拉开差距的题Redis 6.0 多线程、布隆过滤器、Hash 冲突、事务、分布式锁、Redisson、渐进式 rehash、Cluster 节点故障和重新分片。这些题看起来还是八股但真正面试时问法往往会变成“为什么这么设计”“线上有什么坑”“你会怎么处理”。读完下篇你能拿到 4 类能力能把 Redis 底层机制讲得更深入比如多线程边界、Hash 冲突、渐进式 rehash。能把分布式锁讲完整不只会说 setnx还能讲原子性、误删、Lua、续期和 Redisson。能把 Redis Cluster 的节点故障、扩容、槽位迁移、重新分片说成生产问题而不是只背 16384 个槽。能形成一套“先答结论再讲原理再补坑点再接追问”的中高级面试表达方式。和普通八股文的区别是普通八股文帮你记住“知识点”这篇帮你补上“追问链路”。面试官真正想听的不是你背过多少名词而是你能不能把 Redis 的设计、风险和工程取舍讲清楚。十三、为什么 Redis 6.0 之后引入多线程Redis 6.0 之前处理客户端请求时读 socket、协议解析、命令执行、写 socket 等流程基本由主线程顺序处理。随着网络带宽和机器性能提升Redis 的瓶颈很多时候不在 CPU 执行命令而在网络 I/O 和协议读写上。Redis 6.0 引入多线程主要是用多线程处理网络数据读写和协议解析提高网络 I/O 效率。但 Redis 执行命令、操作内存数据仍然是单线程串行执行这样可以避免多线程并发修改数据带来的锁竞争和复杂性。面试可以这样说Redis 6.0 引入多线程不是把命令执行改成多线程而是用多线程优化网络 I/O。因为 Redis 很多场景的瓶颈在网络读写不在 CPU 计算所以多线程 I/O 能提升整体吞吐同时命令执行保持单线程保证实现简单和数据操作安全。可能被追问的1.Redis 6.0 之后还算单线程吗答从命令执行和数据操作角度看仍然是单线程从网络 I/O 处理角度看引入了多线程。2.为什么不把命令执行也改成多线程答命令执行多线程会引入锁竞争、并发控制和数据一致性问题复杂度明显增加而 Redis 的命令执行通常不是主要瓶颈。十四、什么是布隆过滤器布隆过滤器是一种判断元素是否可能存在于集合中的数据结构由一个位图数组和多个哈希函数组成。插入元素时会用多个哈希函数算出多个位置并把这些位置的 bit 设置为 1。查询元素时也计算这些位置如果有任何一个位置是 0就说明元素一定不存在如果全是 1只能说明元素可能存在。布隆过滤器的优点是空间效率高、查询和插入速度快不需要存储元素本身适合用于大规模数据快速判断。缺点是有误判率也就是可能把不存在的数据判断为存在并且普通布隆过滤器不适合删除元素因为多个元素可能共享同一个 bit。在 Redis 缓存场景中布隆过滤器常用于防缓存穿透。请求进来先判断 key 是否可能存在如果布隆过滤器判断不存在直接返回避免打到数据库。面试可以这样说布隆过滤器可以判断一个元素一定不存在或者可能存在。它用位图和多个哈希函数换取很高的空间效率适合防缓存穿透但要接受一定误判率。可能被追问的1.布隆过滤器会误判成什么答可能把不存在的数据误判为存在但不会把存在的数据误判为不存在。2.为什么普通布隆过滤器不方便删除答因为多个元素可能映射到同一个 bit如果删除时把某个 bit 改成 0可能影响其他元素的判断。3.误判率和什么有关答和位图大小、哈希函数个数、插入元素数量有关。元素越多bit 被置 1 的比例越高误判率越大。十五、Redis 的 Hash 冲突怎么办哈希冲突是指不同 key 经过哈希计算后落到同一个哈希桶里。Redis 为了解决哈希冲突采用链式哈希。同一个桶里的多个元素会通过链表连接起来查询时先定位桶再遍历桶中的链表找具体 key。如果哈希冲突变多链表变长查询效率会下降。为了保持高效Redis 会对哈希表进行 rehash也就是扩容哈希表增加桶数量减少冲突。Redis 的字典结构内部通常有两个哈希表ht[0] 用于当前数据ht[1] 用于 rehash 迁移。rehash 期间数据会逐步从 ht[0] 迁移到 ht[1]。面试可以这样说Redis 解决 Hash 冲突主要靠链式哈希同一个桶里的元素用链表保存。为了避免链表过长影响性能Redis 会在合适时机扩容并做渐进式 rehash。可能被追问的1.链式哈希有什么缺点答如果冲突太多链表会变长查询从 O(1) 退化性能下降。2.Redis 为什么要 rehash答为了增加哈希桶数量降低冲突概率让查询、插入、删除尽量保持高效。十六、聊聊 Redis 事务机制Redis 提供简单事务核心命令是 MULTI、EXEC、DISCARD、WATCH。MULTI 表示事务开始之后的命令不会立即执行而是进入事务队列EXEC 表示执行队列中的所有命令并一次性返回结果。因为 Redis 执行命令是单线程的所以事务队列中的命令会按顺序执行中间不会被其他客户端命令插入。但 Redis 事务不等同于 MySQL 事务它不支持完整 ACID也不支持运行时错误后的自动回滚。如果命令入队前存在语法错误事务可能无法正常执行如果命令执行时发生类型错误Redis 会继续执行后续命令不会回滚前面已经执行的命令。面试可以这样说Redis 事务本质上是把一组命令排队然后通过 EXEC 顺序执行。它能保证这组命令执行期间不被其他命令打断但不支持像 MySQL 那样的回滚机制所以更像轻量级事务。可能被追问的1.Redis 事务为什么不支持回滚答Redis 设计目标是简单和快速。回滚需要记录大量状态并增加复杂度而 Redis 认为命令错误通常可以在开发阶段发现所以不提供传统数据库那种回滚。2.Redis 事务能保证原子性吗答如果从“事务队列不会被其他客户端打断”看它有顺序执行的原子效果但如果某条命令执行失败后续命令仍会继续执行所以不能简单等同于数据库事务的原子性。3.WATCH有什么用答WATCH可以监控 key如果事务执行前 key 被其他客户端修改EXEC会失败常用于乐观锁场景。十七、锁超时怎么解决锁超时通常指业务还没执行完Redis 分布式锁已经过期导致其他线程或服务重新获取锁产生并发问题。第一种思路是减少锁内代码执行时间把耗时操作尽量移出锁范围只在真正需要互斥的临界区加锁。第二种思路是合理设置锁过期时间。过期时间要覆盖正常业务耗时并预留一定缓冲但不能设置得过长否则异常情况下锁释放太慢。第三种思路是锁续期。比如 Redisson 的看门狗机制会在客户端仍持有锁时自动延长锁过期时间避免业务未完成锁就过期。面试可以这样说锁超时要从业务耗时、锁粒度和续期机制三个方向处理。能缩短临界区就缩短临界区能预估耗时就设置合理过期时间耗时不可控时可以用 Redisson 看门狗自动续期。可能被追问的1.锁过期时间是不是越长越好答不是。太短会导致业务未完成锁就过期太长会导致服务宕机后锁长时间不释放影响可用性。2.Redisson 指定leaseTime后还有看门狗吗答通常指定固定 leaseTime 后看门狗不会自动续期不指定 leaseTime 时Redisson 才会使用默认看门狗续期机制。十八、什么是渐进式 rehashRedis 字典底层有两个哈希表通常是 ht[0] 和 ht[1]。平时只使用 ht[0]rehash 时才会同时使用两个表。当哈希表负载因子过高需要扩容或者数据变少需要收缩时Redis 会触发 rehash把 ht[0] 中的数据迁移到 ht[1]。如果一次性迁移所有 key数据量大时会导致 Redis 长时间阻塞。所以 Redis 使用渐进式 rehash每次只迁移一小部分桶。rehash 过程中新增数据一般写入 ht[1]查询、删除、更新会同时检查 ht[0] 和 ht[1]保证迁移期间仍然能正常访问。Redis 会维护 rehashidx记录当前迁移到哪个桶。随着后续增删改查操作持续发生逐步完成迁移。全部迁移完成后释放旧表并把 ht[1] 设置为新的 ht[0]。面试可以这样说渐进式 rehash 是 Redis 为了避免一次性扩容迁移造成长时间阻塞把哈希表迁移拆成多次小步骤完成。迁移期间两个哈希表同时工作新增写入新表查询删除两个表都查。可能被追问的1.渐进式 rehash 期间查询会不会查不到数据答不会。Redis 会先查旧表再根据是否处于 rehash 状态查新表保证迁移期间数据可访问。2.为什么新增数据写入新表答这样可以避免新数据又写回旧表减少后续迁移量让 rehash 能逐步完成。十九、分片主从挂了后集群是否还可以使用如果只是从节点故障主节点仍然正常集群通常还能继续提供服务。客户端或集群会屏蔽故障从节点业务可以继续访问其他主从节点。如果某个主节点故障但它有可用从节点Cluster 可以把从节点提升为新的主节点接管原主节点负责的槽位集群可以继续使用。如果某个主节点故障并且没有从节点可以接管那么它负责的槽位不可用集群可能进入 fail 状态。也可以理解为 0 到 16383 的槽位映射不完整。如果超过半数主节点挂掉无论是否有从节点集群通常都会进入 fail 状态因为集群无法完成正常的故障判断和投票。面试可以这样说从节点挂了通常不影响集群整体可用主节点挂了要看有没有从节点接管。如果没有从节点负责的槽位不可用集群会 fail如果半数以上主节点不可用集群也会 fail。可能被追问的1.为什么主节点没有从节点时会导致集群 fail答因为该主节点负责的一部分槽位没人接管槽位映射不完整相关 key 无法访问。2.为什么超过半数主节点故障会有问题答Redis Cluster 的故障判断和主从切换依赖多数主节点参与。如果多数主节点不可用集群无法可靠判断和完成故障转移。二十、Redis Cluster 重新分片过程是怎样的重新分片通常发生在扩容、缩容或槽位分布不均时本质是把一部分 Hash Slot 从源节点迁移到目标节点。添加新节点可以使用 redis-cli --cluster add-node 新节点地址 集群任一节点地址。开始重新分片可以使用 redis-cli --cluster reshard 集群任一节点地址。操作过程中需要指定迁移多少个槽比如 5461 个槽再指定接收槽位的目标节点 ID然后指定从哪些源节点迁移槽位。确认后Redis 会逐步迁移槽位和对应数据。迁移期间客户端可能收到 ASK 或 MOVED 重定向。面试可以这样说Redis Cluster 重新分片就是迁移 slot。先添加节点再执行 reshard指定迁移槽位数量、目标节点和源节点确认后开始迁移。迁移完成后槽位映射更新客户端按新的槽位分布访问。可能被追问的1.重新分片会影响线上访问吗答会有一定影响但 Redis Cluster 支持在线迁移。迁移期间客户端需要正确处理 ASK/MOVED 重定向业务侧也要关注延迟和流量。2.扩容后为什么要迁移槽位答新节点刚加入时通常不负责槽位不迁移槽位就没有数据和流量。迁移槽位后新节点才真正分担存储和访问压力。二十一、使用过 Redisson 吗说说它的原理Redisson 是基于 Redis 的 Java 客户端提供了很多分布式对象和工具常用的就是分布式锁 RLock。Redisson 加锁时会通过 Lua 脚本保证加锁逻辑的原子性。锁的 key 存在 Redis 中value 里会包含客户端和线程标识避免误删别人的锁。Redisson 锁支持可重入。同一个线程再次加锁时不会阻塞自己而是增加重入次数释放锁时减少次数直到次数为 0 才真正删除锁。Redisson 默认有看门狗机制。如果加锁时没有指定固定过期时间客户端持有锁期间看门狗会定期给锁续期避免业务未执行完锁就过期。解锁时Redisson 也会通过 Lua 脚本判断当前线程是否持有锁只有持有者才能释放锁避免误删。面试可以这样说Redisson 分布式锁底层还是 Redis但它把加锁、可重入、释放锁、锁续期这些细节封装好了。核心点是 Lua 保证原子性value 标识锁归属hash 结构支持可重入看门狗负责自动续期。可能被追问的1.Redisson 为什么支持可重入答它会记录线程标识和重入次数。同一个线程重复加锁时增加计数释放时减少计数计数归零才真正删除锁。2.看门狗什么时候生效答通常在没有显式指定 leaseTime 时生效。Redisson 默认锁过期时间是 30 秒看门狗会定期续期。3.Redisson 能完全解决分布式锁问题吗答能解决大多数工程问题但仍要关注 Redis 可用性、锁粒度、业务幂等、超时时间、主从切换时的数据一致性风险。二十二、Redis 集群中节点挂了或者添加如何重新分配数据Redis Cluster 的数据分布由 Hash Slot 决定所以节点挂了或新增节点本质上都是重新分配槽位。新增节点时先把节点加入集群然后通过 reshard 把一部分槽从旧节点迁移到新节点。迁移完成后新节点开始负责这些槽位和对应数据。节点故障时如果它是从节点通常只影响副本如果它是主节点并且有从节点集群会把从节点提升为主节点接管原来的槽位。如果要下线节点需要先把该节点负责的槽迁移到其他节点再执行 remove-node。不能直接移除仍然负责槽位的主节点。面试可以这样说Redis Cluster 不是按节点直接分数据而是按 slot 分数据。新增、删除、故障恢复本质都是让 16384 个槽重新分配到可用节点上。扩容时迁移一部分槽给新节点缩容时先迁走槽再移除节点主节点故障时由从节点接管槽位。可能被追问的1.新增节点后为什么不会自动分担数据答因为新节点刚加入时没有负责槽位只有迁移 slot 后才会承载数据和流量。2.删除主节点前为什么要迁移槽答因为主节点负责的槽里有数据。如果直接删除槽位映射不完整相关 key 无法访问。二十三、Redis 集群模式的原理是什么Redis Cluster 是 Redis 的分布式集群方案核心目标是数据分片、横向扩容和高可用。数据分片通过 16384 个 Hash Slot 实现。每个 key 根据 CRC16 计算槽位每个主节点负责一部分槽位。集群内部节点通过 Gossip 协议通信交换节点状态、故障信息、槽位分配信息、主从关系等。常见消息包括 ping、pong、meet、fail。每个主节点可以配置一个或多个从节点。从节点复制主节点数据当主节点故障时从节点可以被选举为新的主节点。客户端可以连接集群中的任意节点。如果访问的 key 不属于当前节点负责的槽位节点会返回重定向信息让客户端访问正确节点。面试可以这样说Redis Cluster 通过 Hash Slot 做数据分片通过 Gossip 协议维护集群状态通过主从复制和故障转移保证高可用。客户端访问任意节点都可以但最终会根据槽位路由到真正负责该 key 的节点。可能被追问的1.Redis Cluster 为什么不支持跨 slot 的普通多 key 操作答因为不同 key 可能分布在不同节点上跨节点操作会带来分布式事务和一致性问题。可以用 hash tag 让相关 key 落到同一个 slot。2.Gossip 协议有什么作用答让节点之间不断交换集群状态感知新节点加入、节点故障、槽位迁移和主从变化。3.什么是 hash tag答key 中{}内的部分会作为计算 slot 的依据比如user:{100}:name和order:{100}:list会落到同一个槽位。二十四、为什么要做 Redis 分区Redis 分区就是把数据拆分到多个 Redis 节点上不同节点负责不同的数据。第一个原因是突破单机内存限制。单台 Redis 的内存有限数据量越来越大时需要把数据分散到多台机器上。第二个原因是提升整体吞吐。单个节点的 CPU、网络、连接数都有上限分区后不同节点可以并行处理请求。第三个原因是支持横向扩容。业务增长时可以通过增加节点和迁移槽位来扩容而不是只能升级单机配置。但分区也会带来复杂性比如多 key 操作受限、事务和 Lua 脚本跨节点困难、客户端路由复杂、数据迁移和故障处理更复杂。面试可以这样说Redis 分区主要是为了解决单机容量和性能瓶颈把数据分散到多台机器上提升容量和吞吐。但分区后也会带来跨节点操作限制、路由和迁移复杂度所以要结合业务规模选择是否使用集群。可能被追问的1.Redis 分区有哪些方式答常见有客户端分片、代理层分片和 Redis Cluster。现在生产中更常见的是 Redis Cluster由 Redis 自身维护槽位和节点关系。2.分区后有什么限制答跨 slot 的多 key 操作、事务、Lua 脚本会受限数据迁移、热点 key、故障恢复也更复杂。3.小业务一定要上 Redis Cluster 吗答不一定。如果数据量和访问量不大单机加主从哨兵可能就够了。Cluster 更适合容量和吞吐有明显扩展需求的场景。收尾上下两篇合在一起覆盖了 Redis 面试从基础到进阶的大部分高频问题。上篇解决“能不能把核心概念讲清楚”下篇解决“能不能扛住面试官继续追问”。复习时建议按这条线走先掌握 Redis 为什么快和缓存问题再看持久化、高可用和 Cluster最后攻克分布式锁、Redisson、事务、rehash 这类容易深挖的题。真正面试时不要只背一句定义要主动补上场景、风险、解决方案和取舍这也是这份资料和普通八股文最大的区别。