Skip to content

综合真题解析与案例

定位: 真实面试题综合解析 + 生产案例 —— 检验知识串联能力 使用: 每道题能独立回答 + 联系相关知识点


一、综合真题

1.1 在你的项目中 Redis 怎么用的?遇到过什么问题?

回答框架(STAR 原则):

Situation:
  电商平台大促时,首页 Banner 和商品详情页使用 Redis 缓存

Task:
  需要保证 Redis 高可用,且缓存与数据库数据最终一致

Action:
  1. 缓存策略:Cache Aside(先写库后删缓存)
  2. 高可用:Cluster 3主3从
  3. 缓存穿透:布隆过滤器拦截恶意请求
  4. 热点 key:本地缓存 + 逻辑过期

Result:
  大促期间 Redis QPS 峰值 20 万,缓存命中率 99.2%,DB 负载正常

问题 trace:
  Big key:发现某个 Hash 存了用户收藏列表,达 2 万条
  影响:HGETALL 阻塞 200ms
  解决:拆分为多个 Hash + LRANGE 分批读取

1.2 Redis 宕机后如何恢复?

恢复步骤:

1. 检查故障原因
   redis-cli INFO persistence  # 检查持久化状态
   tail -100 /var/log/redis/redis.log  # 检查日志

2. 数据恢复
   a) 使用混合持久化:AOF 文件直接启动
   b) 只有 RDB:将最近 RDB 文件复制到数据目录
   c) 从节点升级:Sentinel/Cluster 自动切换

3. 缓存预热(重点!)
   不要立即启用所有业务 → 防止缓存穿透打挂 DB
   策略:
   - 分级加载(先重要数据)
   - 限流保护(DB 侧限流)
   - 本地缓存兜底

4. 验证
   redis-cli DEBUG SEGFAULT  # 不!不要在生产这样做
   # 实际上验证所有 key 恢复、业务正确

1.3 设计一个秒杀系统的 Redis 方案

需求:
  100 万用户抢 1 万件商品
  不能超卖、不能重复抢

方案设计:

```mermaid
sequenceDiagram
    participant Client as 客户端
    participant Redis
    participant DB as DB

    Client->>Redis: Lua 脚本 pre-seckill
    Note right of Redis: ① 验证用户资格<br/>② 扣减库存<br/>③ 记录抢购
    Redis-->>Client: 结果
    Client->>Redis: 异步写入
    Redis->>DB: ④ 持久化

Lua 脚本(原子扣减 + 判断): local key = KEYS[1] -- 库存 key local user_key = KEYS[2] -- 用户已抢记录 local user_id = ARGV[1]

-- 已抢过? if redis.call('SISMEMBER', user_key, user_id) == 1 then return {err='already_joined'} end

-- 还有库存? local stock = redis.call('GET', key) or 0 if tonumber(stock) <= 0 then return {err='sold_out'} end

-- 扣减库存(原子操作) redis.call('DECR', key) redis.call('SADD', user_key, user_id) return


### 1.4 大促时缓存雪崩了,怎么排查和恢复?

排查流程:

  1. 确认问题症状

    • Redis QPS 急剧下降?→ 可能是服务器问题
    • DB QPS 暴增?→ 缓存穿透/雪崩
    • Redis 内存满开始淘汰?→ 检查 evicted_keys
  2. 检查 Redis 状态 redis-cli INFO stats | grep evicted_keys redis-cli SLOWLOG GET 20 redis-cli INFO memory | grep used_memory

  3. 临时恢复

    • 开启服务降级(返回默认值/空数据)
    • 限制 DB 访问 QPS
    • 紧急扩容 Redis 集群
  4. 事后复盘

    • 检查过期时间配置
    • 是否需要本地缓存兜底
    • 评估是否需要多级缓存架构

---

## 二、生产运维案例

### 案例 1:Redis 内存增长异常排查

现象: used_memory_rss 超过 maxmemory,触发 OOM

排查:

  1. MEMORY STATS 查看内存分布
  2. redis-cli --bigkeys 发现大 key
  3. 定位:某个用户相关的 Hash 异常增长

原因: 业务 bug:用户行为记录没有被清理,持续增长

解决:

  1. 紧急:手动删除该 Hash 的旧数据
  2. 长期:加过期时间 + 设置 maxmemory-policy allkeys-lru

### 案例 2:主从延迟导致数据不一致

现象: 用户支付成功后,查订单状态还是"未支付"(读到从节点)

原因: 主节点写入支付成功 → 从节点尚未同步 → 用户读到从节点旧数据

解决:

  1. 立即:关键操作强制读主节点(jedis.setReadFromMaster())
  2. 长期:确认业务是否接受最终一致性
  3. 监控:主从延迟告警(slave_repl_offset 差值)

### 案例 3:热 Key 导致 Redis 响应变慢

现象: 某个商品详情页的 Redis 查询延迟从 1ms 暴涨到 200ms

排查:

  1. redis-cli --hotkeys 发现该商品的 key 被密集访问
  2. 进一步确认是该商品被某个大 V 推荐

解决:

  1. 临时:本地缓存(Caffeine,5 秒过期)
  2. 长期:热点 key 自动发现 + 自动本地缓存
  3. 架构:写入多个副本 key,读随机选择一个

---

## 📚 相关链接

- [[面试高频100题]] — 按板块分类的面试题
- [[00-Redis文库设计文档|总纲设计文档]]

Knowledge4J — Java 知识库