跳到主要内容

Redis 高频面试题

本节汇总了中高级职位的 Redis 高频面试题,涵盖从基础架构到生产问题的深度解析。

基础与核心原理

Q1: Redis 为什么这么快?

  • 纯内存操作:所有读写均在内存完成。
  • 单线程模型:避免了多线程上下文切换和锁争用开销。
  • 高效数据结构:Skiplist、Listpack(旧版本 Ziplist)、IntSet 等均为内存极致优化。
  • I/O 多路复用:基于 epoll 的非阻塞 I/O。
  • Redis 6+ 多线程 I/O:主线程执行逻辑,多线程处理网络读写。

Q2: 单线程 Redis 能利用多核吗?

  • 核心逻辑由主线程单核跑完。
  • Redis 6.0 后支持 io-threads 解决网络 I/O 瓶颈。
  • 其他工作如 AOF 后台刷盘、UNLINK 删除、BGSAVE 均由子线程或子进程执行。

持久化与一致性

Q3: RDB 与 AOF 的抉择?

  • RDB (快照):文件积压、恢复快。缺点:易丢数据(看快照频率)。
  • AOF (日志):数据更安全、记录命令。缺点:文件大、恢复慢。
  • 混合持久化 (Redis 4.0+):开启 aof-use-rdb-preamble。结合 RDB 的快与 AOF 的稳,是目前生产环境的标配。

Q4: AOF 重写 (Rewrite) 的原理?

  • Fork 出子进程。
  • 遍历内存数据,生成新的 AOF 文件(只记录当前最新状态,合并冗余命令)。
  • Redis 7.0 (Multi-part AOF):不再需要临时文件切换,减少了内存管理压力。

高可用与集群

Q5: 哨兵 (Sentinel) 与 集群 (Cluster) 如何选择?

  • Sentinel:适用于读多写少、单机能扛住写压力的场景,主打自动故障切换。
  • Cluster:适用于海量数据且写并发极高的场景,实现真正的分布式水平扩展。

Q6: 为什么 Cluster 槽数是 16384 (16k)?

  • 节点心跳包(Cluster Bus)会包含槽位位图(Bitmap)。
  • 如果槽位太多(如 65536),位图将占据 8KB 左右,导致心跳包网络负担过重。
  • 16k 已经足够分片需求,通常节点数在 1000 以内是最佳规模。

缓存生产故障

Q7: 缓存崩了该怎么办? (雪崩、击穿、穿透)

参考 Redis 最佳实践 中关于这三者的详细应对。

Q8: 如何保持数据库与缓存的双写一致性?

  • 方案:先更新数据库,再删除缓存。
  • 延时双删:写完数据库后,过几百毫秒再删一次缓存,缓解极短时间内请求读旧数据并重填缓存的问题。
  • Binlog 订阅:通过 Canal/MySQL Binlog 异步删除缓存,将逻辑解耦,保证最终一致性。

开发与运维进阶

Q9: 什么是 Big Key?如何处理?

  • 定义:String > 10KB, List/Hash 成员数 > 5000。
  • 风险:阻塞网卡、删除耗时高导致主线程卡顿。
  • 方法
    • 发现redis-cli --bigkeysMEMORY USAGE
    • 处理UNLINK 异步删除(非 DEL 阻塞销毁),或将大 Key 拆分为多个小 Key。

Q10: Redis 7.4 的 Hash 字段过期解决了什么问题?

  • 以前只能整个 Hash 过期。要实现字段过期通常采用:
    1. 字段名带时间戳:hset user:1 age:20241010 25
    2. 设置额外过期 Key 集。
  • Redis 7.4 的 HEXPIRE 命令直接由内核支持,减少了业务逻辑维护复杂性。

持续更新中,建议结合实践不断提升。