缓存和消息队列面试题
测试开发工程师中间件核心考察范围 | Redis + Kafka + 消息队列
Redis 和消息队列是后端系统的核心组件,测开面试中常结合项目场景问。本文覆盖 Redis 基础/进阶/集群、消息队列原理/可靠性/高可用,共 40 道高频题。
一、Redis 基础
1. Redis 是什么?有什么特点和应用场景?
Redis 是高性能的键值对内存数据库。三大特点:① 基于内存操作,QPS 可达 10万+;② 支持持久化(RDB/AOF);③ 支持多种数据结构(String/List/Set/Hash/ZSet)。
应用场景:缓存(减轻数据库压力)、分布式锁(解决并发问题)、计数器(点赞/浏览量)、排行榜(ZSet)、Session 共享。
2. Redis 的五种基本数据类型及使用场景?
| 类型 | 特点 | 场景 |
|---|---|---|
| String | 最常用,可存数字/字符串/JSON | 缓存、计数器、分布式锁 |
| Hash | 存储对象的多个字段 | 用户信息、商品信息 |
| List | 有序可重复 | 消息队列、最新列表 |
| Set | 无序不重复 | 去重、共同好友、点赞列表 |
| ZSet | 带分数排序 | 排行榜、延迟队列 |
3. Redis 单线程为什么这么快?
四个原因:① 基于内存操作(内存读写远超磁盘);② 单线程避免线程切换和锁竞争;③ IO 多路复用(一个线程处理多个网络连接);④ 数据结构经过优化。
注意:Redis 6.0+ 引入多线程,但只用于网络 IO,核心数据操作仍是单线程。
4. Redis 的持久化机制有哪些?
| 方式 | 原理 | 优点 | 缺点 |
|---|---|---|---|
| RDB | 定期生成内存快照 | 恢复速度快 | 可能丢失最后一次快照后的数据 |
| AOF | 记录每条写命令 | 数据完整性好(最多丢1秒) | 文件大、恢复慢 |
推荐两种都开启:RDB 做定期备份,AOF 保证数据完整性。AOF 配置 everysec 策略平衡性能和安全。
5. Redis 的过期策略有哪些?
三种策略配合使用:
- 定期删除:每 100ms 随机抽取 key 检查是否过期
- 惰性删除:查询 key 时才检查是否过期
- 内存淘汰:内存不足时按策略删除 key(常用
allkeys-lru,淘汰最近最少使用的)
6. Redis 的内存淘汰策略有哪些?
常用四种:
noeviction:默认,内存不足时直接报错allkeys-lru:从所有 key 中淘汰最近最少使用的(推荐)volatile-lru:从有过期时间的 key 中淘汰最近最少使用的allkeys-random:随机淘汰
推荐 allkeys-lru,符合二八定律,热点数据会被保留。
7. Redis 的事务如何使用?
MULTI 开启事务 → 输入命令(进入队列)→ EXEC 执行。WATCH 实现乐观锁,监控 key 是否被修改。
注意:Redis 事务不支持回滚,某条命令失败不影响其他命令。实际项目中更常用 Lua 脚本保证原子性。
二、Redis 进阶
8. 什么是缓存穿透?如何解决?
缓存穿透:查询数据库不存在的数据,缓存也没有,每次都穿透到数据库。比如恶意查询 id=-1 的商品。
解决方案:
- 缓存空值:查询数据库返回空也缓存,设置较短过期时间(如 5 分钟)
- 布隆过滤器:在缓存前加一层,快速判断数据是否存在,不存在直接返回
9. 什么是缓存击穿?如何解决?
缓存击穿:热点 key 突然过期,瞬间大量请求穿透到数据库。比如爆款商品缓存过期,几千个请求同时查数据库。
解决方案:
- 热点数据永不过期,配合定时任务定期刷新
- 互斥锁:第一个请求查数据库时加锁,其他请求等待
- 提前异步刷新:key 快过期时后台自动刷新
10. 什么是缓存雪崩?如何解决?
缓存雪崩:大量 key 同时过期,请求瞬间打到数据库。
解决方案:
- 随机过期时间:基础时间 + 随机值(如 1小时 ± 10分钟)
- Redis 集群:分散压力
- 限流降级:请求过多时直接返回友好提示
三者区别:穿透是查不存在的数据,击穿是单个热点 key 过期,雪崩是大量 key 同时过期。
11. 如何保证缓存和数据库的一致性?
推荐策略:先更新数据库,再删除缓存。更新成功后删除缓存,下次查询重新加载最新数据。
其他方案:
- 先删缓存再更新数据库(有并发问题)
- 延迟双删:先删缓存 → 更新数据库 → 延迟 1 秒再删缓存
- 订阅 binlog 异步更新缓存(强一致性场景)
12. Redis 如何实现分布式锁?
核心命令:SET key value NX EX seconds
- NX:key 不存在才设置(抢锁)
- EX:设置过期时间(防死锁)
流程:加锁(SET)→ 执行业务 → 释放锁(删除前校验是不是自己的锁,用 Lua 脚本保证原子性)。
13. 什么是大 key 问题?如何解决?
大 key:value 占用内存很大的 key(如几万元素的 Set、几 MB 的 String)。
危害:占用大量内存、操作慢(删除会阻塞)、内存分布不均。
解决:拆分大 key、压缩数据、定期清理。比如用户浏览历史只保留最近 100 条。
14. Redis 如何实现限流?
- 计数器算法:String 记录次数 + EXPIRE 过期。简单但有边界突发问题
- 滑动窗口算法:ZSet 实现,score 是时间戳,统计最近 N 秒的请求数。更精确
场景:短信验证码接口限制每分钟 1 次。
15. Redis 如何实现消息队列?
| 方式 | 特点 | 适用场景 |
|---|---|---|
| List(LPUSH + BRPOP) | 简单,不支持消息确认 | 简单异步任务 |
| Pub/Sub | 消息不持久化,离线丢消息 | 实时通知 |
| Stream(5.0+) | 持久化、消费组、消息确认 | 替代轻量 MQ |
重要业务还是用专业 MQ(Kafka/RabbitMQ)。
16. Redis 的慢查询如何排查?
配置 slowlog-log-slower-than 10000(超过 10ms 记录),用 slowlog get 查看。
常见原因:操作大 key、使用 keys * 等 O(n) 命令、集合操作数据量太大。 优化:拆分大 key、用 SCAN 替代 KEYS、分批处理。
17. Redis 性能优化有哪些方法?
六个方向:① 避免大 key;② 设置合理过期时间;③ 使用 pipeline 批量操作;④ 避免高复杂度命令(keys *、HGETALL 大 hash);⑤ 使用连接池;⑥ 合理设置 maxmemory 和淘汰策略。
三、Redis 集群与高可用
18. Redis 如何保证高可用?
三种架构:
- 主从复制:一主多从,主写从读,读写分离
- 哨兵模式:监控主从节点,主节点宕机自动故障转移
- Redis Cluster:多个主节点,数据分片存储,支持水平扩展
19. Redis 集群的数据分片原理?
Redis Cluster 使用哈希槽分片:总共 16384 个槽,key 通过 CRC16 对 16384 取模确定槽位。不同槽分配给不同主节点。
例如 3 个主节点:A(0-5460)、B(5461-10922)、C(10923-16383)。客户端直接访问对应节点,访问错误返回 MOVED 重定向。
20. Redis 在测开项目中怎么用的?
常见场景:
- 商品缓存:缓存命中率 95%+,减轻数据库压力,过期时间 1 小时 + 随机 10 分钟
- Session 共享:用户登录信息存 Redis,支持分布式部署
- 库存预扣减:秒杀库存存 Redis,Lua 脚本原子扣减,异步更新数据库
- 分布式锁:关键环节保证并发安全,避免超卖
四、消息队列基础
21. 什么是消息队列?有什么作用?
消息队列是异步通信机制,生产者发消息到队列,消费者从队列获取处理。三大作用:
- 异步处理:下单后不用等发短信就返回,提升响应速度
- 削峰填谷:秒杀请求进队列慢慢处理,避免系统崩溃
- 解耦:订单系统和库存系统通过 MQ 通信,互不依赖
22. 常见消息队列有什么区别?
| MQ | 吞吐量 | 特点 | 适用场景 |
|---|---|---|---|
| Kafka | 百万级 TPS | 高吞吐、功能简单 | 大数据、日志采集 |
| RabbitMQ | 万级 TPS | 功能丰富、可靠性高 | 金融、对可靠性要求高 |
| RocketMQ | 十万级 TPS | 支持事务消息、延迟消息 | 电商 |
23. 消息队列如何保证消息不丢失?
三个环节保障:
- 生产者端:发送确认机制(Kafka 的
acks=all),失败重试 - MQ 服务端:消息持久化到磁盘 + 副本机制(至少 2 副本)
- 消费者端:消费成功才提交 offset,失败重试。不能先提交再处理
24. 如何保证消息不重复消费?
核心思路:幂等性设计。
- 业务唯一 ID(如订单号),消费前查 Redis 是否已处理
- 数据库唯一索引,重复插入自动失败
- 版本号机制,重复更新会失败
25. 什么是消息积压?如何解决?
消息积压:生产速度 > 消费速度,队列越堆越多。
解决方案:① 增加消费者数量;② 优化消费逻辑(去掉同步等待);③ 扩容分区(Kafka 增加 partition);④ 批量消费。
26. 如何保证消息的顺序性?
两个关键点:
- 发送端:同一业务消息发到同一分区(Kafka 按 key hash 路由)
- 消费端:同一分区单线程消费,保证顺序处理
注意:严格顺序会牺牲性能。场景:订单状态变更(创建→支付→发货)需要保证顺序。
27. 什么是死信队列?
死信队列存放无法正常消费的消息。消息变死信的三种情况:消费失败达最大重试次数、消息过期(TTL)、队列满。
作用:隔离异常消息,避免阻塞正常消费,方便人工介入。配合定时任务扫描处理。
28. 什么是延迟消息?如何实现?
延迟消息:发送后不立即消费,延迟一段时间后才能被消费。
实现方式:
- RocketMQ 原生支持:固定延迟级别(5 秒、1 分钟、5 分钟等)
- Redis ZSet:score 存时间戳,定时任务扫描到期消息
场景:订单超时未支付自动取消(下单发 30 分钟延迟消息,到期检查状态)。
29. 消息队列的推模式和拉模式?
| 模式 | 特点 | 代表 |
|---|---|---|
| Push(推) | MQ 主动推送,实时性好,但可能压垮消费者 | RabbitMQ |
| Pull(拉) | 消费者主动拉取,控制消费速度,可能有延迟 | Kafka |
Kafka 采用拉模式,消费者 poll 拉取,可批量拉取提高效率。
五、消息队列进阶
30. Kafka 的分区和副本是什么?
- 分区(Partition):存储单元,一个 topic 分多个分区分布在不同 broker,提高并行度
- 副本(Replica):分区的冗余备份,Leader 负责读写,Follower 同步数据。Leader 宕机自动选举新 Leader
示例:订单 topic 6 分区 3 副本,6 个消费者并行消费,3 副本保证数据可靠性。
31. Kafka 如何保证高吞吐量?
五个技术手段:① 顺序写磁盘(速度接近内存);② 零拷贝技术(数据不经过用户空间);③ 批量发送(减少网络开销);④ 消息压缩(GZIP/Snappy);⑤ 分区并行。
32. 消费者组是什么?
消费者组(Consumer Group)的两个特点:
- 组内负载均衡:同一分区只能被组内一个消费者消费
- 组间隔离:不同组独立消费同一个 topic 的全部数据
场景:订单消息有 3 个消费者组(订单处理组、库存扣减组、积分增加组),一条消息多个业务独立消费。
33. offset 是什么?如何管理?
offset 是消费者在分区中的消费位置,记录消费到了第几条。
- 自动提交:定期自动提交,简单但可能丢消息或重复
- 手动提交:消费成功后才提交,更可靠
推荐手动提交 + 幂等性设计。
34. 什么是事务消息?
事务消息保证本地事务和消息发送的一致性。RocketMQ 流程:发送半消息(不投递)→ 执行本地事务 → 成功提交/失败回滚。
实际项目中常用最终一致性方案:消息重试 + 补偿机制。
35. 如何处理消费失败的消息?
四种策略:① 立即重试(偶发错误);② 延迟重试(间隔递增:1 秒→5 秒→30 秒);③ 进入死信队列(重试 3 次仍失败);④ 记录日志告警。
36. 消息队列如何实现高可用?
- 集群部署:至少 3 个 broker,避免单点
- 副本机制:每分区至少 2 副本
- 生产消费保障:生产者重试 + 持久化 + 消费者手动提交
- 监控告警:Lag 超 10 万条告警、消费延迟超 1 分钟告警、消费者离线告警
37. 如何监控消息队列的健康状态?
四个核心指标:
- 消息堆积量(Lag):消费者 offset 和最新 offset 的差值
- 消费延迟:生产到消费的时间间隔(正常秒级)
- 消费者状态:是否有宕机或异常
- 集群资源:CPU/内存/磁盘/网络
工具:Kafka Manager + Prometheus + Grafana。
38. 消息队列的性能优化?
六个方向:① 批量发送;② 批量消费;③ 异步发送;④ 消息压缩;⑤ 增加分区数;⑥ 优化消费逻辑(去同步等待)。
39. 如何设计高可用消息队列架构?
四个方面:① 集群部署(≥3 broker);② 副本机制(每分区 ≥2 副本);③ 生产消费保障(重试+持久化+手动提交);④ 监控告警(Lag/延迟/资源)。
40. MQ 在测开项目中怎么用的?
四个典型场景:
- 异步处理:下单后异步发短信/扣积分/发优惠券,响应时间从 2s 降到 200ms
- 削峰填谷:秒杀请求进 MQ 排队,支撑万人同时抢购
- 系统解耦:订单和库存通过 MQ 通信,独立部署互不影响
- 数据同步:订单变更后发消息同步到数据仓库/搜索引擎
相关页面
- [[测开指导/测开指导-md/基础知识/01-计算机基础]]
- [[测开指导/测开指导-md/基础知识/02-Java核心技术]]
- [[测开指导/测开指导-md/基础知识/08-Python核心技术]]
- [[测开指导/概念/MVCC]]
- [[测开指导/概念/CI-CD]]
- [[测开指导/测开指导-md/基础知识/03-测试理论与策略]]
