中间件
面试权重:★★★ | 适用级别:P7/P8+ | 预计复习时间:2-3周
概览
面试权重:★★★ | 适用级别:P7/P8+ | 预计复习时间:2-3周
这篇的核心不是背组件大全,而是搞清楚 Redis、MQ、ES、Zookeeper 分别解决什么问题,出现高并发、丢消息、缓存不一致、集群故障时应该怎么判断和兜底。
建议用法
建议按四条主线复习:缓存为什么快、消息为什么可靠、搜索为什么适合倒排索引、注册与协调为什么常用 Zookeeper。每一条线都尽量落到"原理 + 场景 + 故障处理"三件事上。
一、知识体系
1. Redis ★★★
1.1 数据结构与编码 ★★★
Redis 为什么能快
- 核心结论
- Redis 快不只是因为"基于内存",而是内存 + 单线程命令执行模型 + 高效数据结构 + IO 多路复用一起作用的结果。
- 原理展开
- Redis 的核心数据类型不是简单映射到一种底层结构,而是会根据数据规模和内容动态选择更节省内存的编码。
- String 底层是 SDS,支持预分配和二进制安全。
- Hash、List、ZSet、Set 在不同数据量级下会切换不同编码,目的都是在时间和空间之间做平衡。
- 面试怎么答
- "Redis 快的关键是尽量把 CPU 花在真正的命令逻辑上,而不是线程切换和复杂锁竞争上。再配合紧凑编码和网络模型,整体吞吐就很高。"
五种基础类型与常见场景
String- 最常用,适合缓存对象、计数器、分布式锁、限流令牌等。
List- 适合消息队列、时间线,但生产里很多队列场景会被 Stream 或 MQ 替代。
Hash- 适合存对象字段,能减少整体序列化与反序列化成本。
Set- 适合去重、共同好友、标签集合。
ZSet- 适合排行榜、延迟任务、按分数排序场景。
扩展类型与加分点
Bitmap- 适合签到、布尔状态统计、布隆过滤器底层位图思路。
HyperLogLog- 用较小空间估算基数,适合 UV 统计。
Geo- 适合地理位置搜索。
Stream- Redis 5 引入的消息流结构,适合轻量消息处理,但复杂业务通常仍会交给专业 MQ。
1.2 持久化 ★★★
RDB、AOF、混合持久化怎么选
- 核心结论
- RDB 偏恢复速度和文件紧凑,AOF 偏数据安全和操作可追溯,混合持久化是更常见的折中方案。
- 原理展开
- RDB 通过 fork 子进程生成快照,主进程继续处理请求,借助 COW 降低停顿。
- AOF 通过追加写命令记录变更,常见刷盘策略有
always、everysec、no。 - AOF 文件会膨胀,所以需要
bgrewriteaof做重写。 - 混合持久化通常先写 RDB 头,再追加增量 AOF,兼顾恢复速度和数据安全。
- 面试怎么答
- "如果业务更怕数据丢失,就偏 AOF 或混合持久化;如果更关心恢复速度,RDB 的价值更高。生产通常不是二选一,而是组合。"
- 易错点
- fork 本身会消耗内存页复制成本,内存大时不能把 RDB 当成零成本操作。
1.3 内存管理
- 核心结论
- Redis 内存问题主要看三件事:过期删除、淘汰策略、热点和大 Key。
- 原理展开
- 过期键删除采用惰性删除 + 定期删除组合,不会每次都做全量扫描。
- 淘汰策略要会区分
allkeys-lru、allkeys-lfu、volatile-ttl等高频选项。 - 真正线上问题往往不是策略不会背,而是对象太大、冷热分布极不均、key 生命周期设计差。
- 面试怎么答
- "Redis 内存治理不只是配一个淘汰策略,更要控制 value 大小、key 生命周期和热点分布。"
1.4 高可用架构 ★★★
主从复制、Sentinel、Cluster 的定位
- 核心结论
- 主从复制解决读扩展和容灾基础,Sentinel 解决自动故障转移,Cluster 解决真正的分片扩容。
- 原理展开
- 主从复制包含全量同步和增量同步,复制积压缓冲区决定了断连后能否只做增量。
- Sentinel 通过监控、投票、选主实现故障切换,但它不做分片。
- Cluster 通过 16384 个 hash slot 做数据分布,节点扩缩容本质上是在迁移 slot。
- 面试怎么答
- "Sentinel 是高可用方案,不是分片方案;Cluster 才同时解决高可用和横向扩展。很多人会把这两个层级混掉。"
- 常见追问
- MOVED 和 ASK 区别?
- 脑裂怎么理解?
- 为什么 Redis 主从切换时分布式锁会有风险?
1.5 常见问题 ★★★
缓存穿透、击穿、雪崩
- 核心结论
- 三者都可能把请求打回数据库,但根因不同,治理手段也不同。
- 原理展开
- 穿透是请求不存在的数据,常用空值缓存或布隆过滤器。
- 击穿是热点 key 突然失效,大量请求同时回源,常用互斥构建或逻辑过期。
- 雪崩是大量 key 同时失效或缓存整体不可用,常配合随机过期、多级缓存、限流降级。
- 面试怎么答
- "三者最容易考的是区分根因,再说明为什么互斥锁适合击穿、布隆过滤器适合穿透,而随机过期更针对雪崩。"
缓存和数据库一致性
- 核心结论
- 对大多数业务来说,缓存一致性追求的是可控最终一致,而不是绝对强一致。
- 原理展开
- Cache Aside 最常见:读先查缓存,miss 再查 DB 回写;写先更 DB,再删缓存。
- 延迟双删、binlog 订阅、消息通知、本地缓存失效广播,都是为了缩小不一致窗口。
- 如果业务强一致要求极高,通常不应该过度依赖缓存承接核心状态。
- 面试怎么答
- "先更库再删缓存是主流,不是因为它完美,而是它在复杂度和一致性之间最平衡。真正重要的是你如何控制异常路径和重试。"
热点 Key 与大 Key
- 核心结论
- 热点 Key 会打爆单点,大 Key 会拖慢网络、阻塞线程和复制。
- 处理思路
- 热点 Key:本地缓存、读写分离、key 打散、预热、多副本承接。
- 大 Key:拆分、压缩、异步删除、避免把整页大对象当一个 value 存。
1.6 Redis高级特性 ★★
Lua、Pipeline、事务与分布式锁
- 核心结论
- Lua 的价值是把多步命令合成一段原子脚本;Pipeline 的价值是减少往返;Redis 事务不等于关系型事务。
- 原理展开
MULTI/EXEC只是批量顺序执行,失败后也没有关系型事务那种完整回滚语义。- 分布式锁常见实现是
SET NX EX+ 唯一值 + Lua 校验删除。 - Redisson 的看门狗机制可以在业务执行时间超出预期时自动续期。
- 面试怎么答
- "Redis 分布式锁能解决大多数高并发协作问题,但一旦业务要强一致和严格 fencing token,就要谨慎评估是否该转向 ZK/etcd。"
2. 消息队列 ★★★
2.1 消息队列选型对比 ★★
- 核心结论
- MQ 选型先看业务目标,不要先看组件站队。
- 快速对比
| 维度 | Kafka | RocketMQ | RabbitMQ |
|---|---|---|---|
| 核心优势 | 吞吐极高、生态强 | 业务特性丰富 | 协议丰富、路由灵活 |
| 强项场景 | 日志、流处理、数据管道 | 交易、业务消息 | 中小系统、复杂路由 |
| 典型短板 | 业务特性相对少 | 社区生态不如 Kafka 宽 | 大吞吐场景压力更大 |
- 面试怎么答
- "Kafka 更像高吞吐消息日志平台,RocketMQ 更偏业务消息平台,RabbitMQ 更偏协议灵活和中小场景。真正选择要看吞吐、可靠性、延迟消息、事务消息等诉求。"
2.2 Kafka深度 ★★★
分区、副本与高吞吐来源
- 核心结论
- Kafka 的吞吐能力主要来自顺序写、Page Cache、批量和分区并行。
- 原理展开
- Topic 会拆成多个 Partition,分区是并行度和顺序性的基本单位。
- 副本通过 ISR 机制维护,Leader 对外提供读写,Follower 负责追赶。
acks=all、幂等生产者、手动提交 offset 是常见可靠性基础配置。
- 面试怎么答
- "Kafka 不靠单条消息超快,而是靠顺序写磁盘和批量 IO 把吞吐做高。分区带来并行度,但也把顺序性约束到了分区级。"
- 常见追问
- 为什么说 Kafka 用磁盘也很快?
- HW、LEO 是什么?
Rebalance、顺序性与消息可靠性
- 核心结论
- Kafka 高并发下最常见痛点不是"发不出去",而是 Rebalance 抖动、重复消费和顺序失控。
- 原理展开
- 消费者组内一个分区同一时刻只会被一个消费者消费。
- Rebalance 触发于成员增减、超时、分区变化等,会带来消费暂停和重新分配。
- 顺序消息只能保证同一个分区内顺序。
- 面试怎么答
- "Kafka 的可靠性要分三端看:生产端确认、Broker 副本同步、消费端幂等和 offset 提交。只讲一端都不完整。"
2.3 RocketMQ深度 ★★★
业务消息为什么常提 RocketMQ
- 核心结论
- RocketMQ 在事务消息、延迟消息、死信处理等业务特性上更顺手,适合交易链路和复杂业务场景。
- 原理展开
- NameServer 负责路由发现,Broker 负责实际存储和投递。
- CommitLog、ConsumeQueue、IndexFile 的分层设计兼顾了顺序写和查询效率。
- 事务消息采用 Half Message + 本地事务 + 回查机制,关键是把业务事务和消息发送做成最终一致。
- 面试怎么答
- "如果业务特别看重事务消息、延迟消息、消费治理,RocketMQ 往往比 Kafka 更省心。"
2.4 消息队列通用问题 ★★★
丢失、重复、堆积、顺序
- 核心结论
- MQ 面试高频本质上就是四类问题:会不会丢、会不会重、积压怎么办、顺序怎么保。
- 标准回答
- 消息丢失:生产确认、Broker 持久化、副本同步、消费确认。
- 重复消费:业务幂等、去重表、状态机、唯一消息 ID。
- 消息堆积:扩容消费者、提升并发、降级非核心链路、临时旁路消费。
- 顺序消费:把同一业务 key 路由到同一队列或分区,并控制消费并发。
- 面试怎么答
- "严格 exactly-once 很难,业务里更多是 at-least-once 加幂等消费,达到效果上的 exactly-once。"
3. Elasticsearch ★★
3.1 核心概念
- 核心结论
- ES 不是"能查 JSON 的数据库",它的核心能力在倒排索引和搜索相关性。
- 原理展开
- 文档会经过分词,形成 term,再通过倒排索引把 term 映射到文档集合。
- 分片决定数据分布和并行查询能力,副本决定可用性和读扩展。
- 面试怎么答
- "ES 适合文本搜索、过滤聚合和复杂检索,不适合承担强事务主存储。"
3.2 查询与分析
- 高频要点
match适合全文检索,term适合精确匹配。bool查询、过滤与打分要能区分。- 深分页要避免简单
from + size无限放大,可考虑search_after、scroll 等方案。
- 易错点
- 分词字段和 keyword 字段混用,是 ES 面试和生产的双高频坑。
3.3 集群与运维
- 核心结论
- ES 集群管理重点看节点角色、分片数量、写入刷新节奏和 merge 压力。
- 面试怎么答
- "ES 运维的核心不是会建索引,而是能控制分片数量、理解 refresh/flush/merge 对性能的影响。"
3.4 性能优化
- 优化方向
- 索引层:分片不要过多,mapping 合理收敛。
- 查询层:尽量走 filter、减少脚本查询、控制深分页。
- 写入层:批量写、延长刷新间隔、避免高基数无意义字段。
4. Zookeeper ★★
4.1 核心特性
- 核心结论
- Zookeeper 更像协调服务,不是高性能 KV 数据库。
- 原理展开
- 数据模型是树状 ZNode,支持持久、临时、顺序等节点类型。
- Watcher 是一次性通知机制,不能当消息队列用。
- Session 是判断客户端存活和触发临时节点回收的关键。
- 面试怎么答
- "Zookeeper 擅长做协调、选主、分布式锁和配置管理,不擅长做大吞吐数据存储。"
4.2 ZAB协议 ★★
- 核心结论
- ZAB 的目标是保证 Zab 集群在 Leader 崩溃和恢复场景下仍能保持顺序一致的广播语义。
- 一句话抓手
- 崩溃恢复保证选出合适的新 Leader。
- 消息广播保证事务按顺序被多数节点确认。
4.3 典型应用
- 分布式锁
- 临时顺序节点 + Watcher,强调公平性和可靠性。
- 配置中心
- 配置变更通知和集中管理。
- 注册中心
- 依赖临时节点感知服务上下线。
- 选主
- 节点断开会自动释放临时节点,天然适合 leader 选举。
4.4 Zookeeper vs Eureka vs Nacos
- 核心结论
- 三者的核心差别在于一致性取舍、功能定位和使用生态。
- 面试怎么答
- "ZK 偏 CP,Eureka 偏 AP,Nacos 可在不同场景下提供 AP/CP 形态,还把注册和配置整合在一起。选型时要先看业务更怕不可用还是短暂不一致。"
二、高频面试题
基础级(P7必答)
- Redis 为什么这么快?
- 30秒答法:Redis 快不是单点优势,而是内存访问、单线程命令执行、IO 多路复用和高效底层编码一起叠加出来的。它把大部分开销都从线程切换和锁竞争里拿掉了。
- 关键词:内存、单线程、IO 多路复用、编码优化、低开销
- 追问提醒:Redis 6 多线程做了什么;单线程为什么还能扛高并发
- Redis 的 RDB 和 AOF 有什么区别?
- 30秒答法:RDB 是定期快照,恢复快、文件紧凑,但可能丢最后一次快照后的数据;AOF 是追加写命令,数据更安全但文件更大、恢复更慢。生产里常用混合持久化做折中。
- 关键词:RDB、AOF、fork、COW、everysec、重写
- 追问提醒:AOF 重写;混合持久化;fork 对大内存实例的影响
- 缓存穿透、击穿、雪崩分别是什么?怎么处理?
- 30秒答法:穿透是查不存在数据,击穿是热点 key 失效瞬间并发回源,雪崩是大批 key 同时失效或缓存整体不可用。对应策略通常是布隆过滤器或空值缓存、互斥重建或逻辑过期、随机过期和限流降级。
- 关键词:穿透、击穿、雪崩、布隆过滤器、逻辑过期
- 追问提醒:热点 key 怎么治理;多级缓存如何配合
- 怎么保证缓存和数据库的一致性?
- 30秒答法:主流方案是 Cache Aside,读 miss 再回源,写时先更新数据库再删缓存。异常路径下可配合重试、延迟双删、binlog 订阅或消息通知缩小不一致窗口。
- 关键词:Cache Aside、删缓存、延迟双删、binlog、最终一致
- 追问提醒:为什么不是先删缓存后更新数据库;强一致场景怎么办
- Kafka 为什么吞吐量高?
- 30秒答法:核心原因是顺序写磁盘、充分利用 Page Cache、批量发送和分区并行。Kafka 不是靠单条消息超快,而是靠把整体 IO 模型做得非常适合日志追加。
- 关键词:顺序写、Page Cache、批量、分区、零拷贝
- 追问提醒:Kafka 为什么还需要磁盘;ISR 和副本同步
- Kafka 怎么保证消息不丢?
- 30秒答法:三端都要管。生产端要有确认和重试,Broker 端要有副本同步和 ISR,消费端要在真正处理成功后再提交 offset,并保证幂等消费。
- 关键词:acks、ISR、offset、幂等消费、重试
- 追问提醒:重复消费怎么办;事务消息和 exactly-once 怎么理解
- RocketMQ 事务消息原理是什么?
- 30秒答法:先发 Half Message,对消费者暂不可见;业务本地事务执行后再决定 commit 或 rollback。Broker 若迟迟收不到确认,会主动回查生产者本地事务状态。
- 关键词:Half Message、本地事务、回查、最终一致
- 追问提醒:为什么适合交易链路;回查失败怎么处理
- Redis Cluster 的 hash slot 机制是什么?
- 30秒答法:Redis Cluster 把数据划成 16384 个 slot,key 通过哈希映射到 slot,再由 slot 路由到具体节点。扩容缩容本质是 slot 迁移,不是简单整个节点替换。
- 关键词:16384、slot、MOVED、ASK、迁移
- 追问提醒:为什么不是一致性 Hash;热点 slot 怎么办
- Zookeeper 适合做什么?为什么常用于分布式锁和选主?
- 30秒答法:Zookeeper 适合做协调、注册、配置和选主,因为它有有序节点、临时节点和较强一致性保证。客户端断开后临时节点自动清理,这让锁释放和 leader 失效检测都比较自然。
- 关键词:临时节点、顺序节点、Watcher、强一致
- 追问提醒:ZK 锁和 Redis 锁怎么选;Watcher 为什么是一性触发
- Elasticsearch 为什么适合搜索,不适合主交易库?
- 30秒答法:因为 ES 核心是倒排索引和搜索相关性,不是强事务和复杂更新一致性。它擅长文本检索、过滤聚合和近实时查询,但不适合承担强一致交易写入主库。
- 关键词:倒排索引、近实时、相关性、强事务
- 追问提醒:refresh 机制;深分页为什么慢
进阶级(P8+深挖)
- Redis 分布式锁有哪些风险?什么时候该考虑 ZK/etcd?
- 30秒答法:Redis 锁的高性能优势很明显,但在主从切换、网络抖动、业务执行超时等场景下会有一致性风险。如果业务必须要 fencing token 或更强的协调语义,就应该评估 ZK/etcd。
- 关键词:锁丢失、续期、主从切换、fencing token
- 追问提醒:RedLock 争议;Redisson 看门狗
- Kafka Rebalance 为什么会影响业务?怎么缓解?
- 30秒答法:Rebalance 会让消费者组暂停消费并重分配分区,延迟高时业务感知很明显。缓解通常靠合理超时配置、避免长时间阻塞
poll、使用更平滑的分配策略和降低频繁扩缩容。 - 关键词:Rebalance、消费者组、分区重分配、暂停消费
- 追问提醒:CooperativeStickyAssignor;长耗时消费怎么处理
- RocketMQ 和 Kafka 你会怎么选?
- 30秒答法:日志、流处理、超高吞吐场景优先 Kafka;事务消息、延迟消息、业务治理诉求强的场景更偏 RocketMQ。真正选择标准是业务目标,不是组件偏好。
- 关键词:吞吐、事务消息、延迟消息、日志流处理
- 追问提醒:顺序消费;消息堆积;死信处理
- ES 集群为什么容易因为分片设计不当出问题?
- 30秒答法:分片过多会带来管理和内存开销,分片过大又会让恢复和查询并行度变差。ES 性能问题很多时候不是单条 DSL 写错,而是索引设计从一开始就不合理。
- 关键词:分片数量、恢复、并行度、内存开销
- 追问提醒:冷热节点;索引生命周期管理
- Nacos、Eureka、Zookeeper 作为注册中心怎么权衡?
- 30秒答法:Eureka 偏 AP,注册发现简单稳妥;Zookeeper 偏 CP,适合更强调一致性的协调场景;Nacos 在注册和配置整合上更方便,也能在不同实例类型下走 AP/CP 策略。
- 关键词:AP、CP、注册中心、配置中心、治理能力
- 追问提醒:服务摘除策略;健康检查;配置发布
三、实战场景题(P8+重点)
- 缓存层突然失效,大量请求回源 DB,怎么止血?
- 回答框架
- 先限流和降级,保护核心链路。
- 再快速恢复热点 key 或拉起缓存实例。
- 关键接口可临时启用本地缓存、静态兜底或读主备数据。
- 事后再追根因:过期策略、集群故障、发布误删、连接池问题。
- 核心关注点:先止血,再找根因。
- MQ 大量堆积,消费者明显落后,怎么处理?
- 回答框架
- 先看堆积量、积压速率和是否影响核心业务。
- 再判断瓶颈在消费者处理慢、下游依赖慢,还是分区数不足。
- 动作上可扩容消费者、提升并发、临时旁路非核心消息、拆热点 topic。
- 最后回补治理:压测、消费监控、死信与重试策略。
- 核心关注点:不要只会说"加机器"。
- 搜索接口 RT 抖动,ES 集群写入也在升高,怎么排查?
- 回答框架
- 先看查询 DSL、慢查询、热点索引和分片负载。
- 再看 refresh、merge、bulk 写入和节点资源。
- 判断是索引设计问题、查询不走 keyword/filter、还是写读互相抢资源。
- 核心关注点:ES 的问题通常是写入、查询、分片设计一起看。
- 注册中心挂了,服务会不会全挂?
- 回答框架
- 先区分是注册中心不可用还是实例数据丢失。
- 大多数客户端会缓存本地实例列表,短期内服务调用未必立刻中断。
- 真正风险是新实例无法注册、下线感知变慢、治理能力下降。
- 核心关注点:要回答"短期还能跑、长期会恶化"这种层次感。
四、学习资源推荐
书籍
- 《Redis设计与实现》:理解 Redis 数据结构和实现细节
- 《Kafka权威指南》:适合系统梳理 Kafka 主线
- 《Elasticsearch实战》:适合搜索体系入门和进阶
博客/文章
- Redis 官方文档:持久化、集群、淘汰策略最权威
- Kafka 官方文档:分区、副本、消费者组、事务特性
- RocketMQ 官方文档与阿里技术文章:业务消息场景很有价值
视频
- Redis 高并发实战与缓存治理专题
- Kafka / RocketMQ 对比与可靠性设计分享
- Elasticsearch 索引设计与查询优化课程