Skip to content

03-Redis 篇面试题

对应原始资料:12-BAT/02-Redis篇

一、基础

Q1:Redis 为什么快

  1. 基于内存。
  2. 单线程(命令执行),避免上下文切换和锁竞争。
  3. IO 多路复用(epoll)。
  4. 高效数据结构。

Q2:为什么用单线程

  • 命令执行在内存,本身就极快。
  • 避免多线程的锁和上下文切换。
  • 6.0 起网络读写引入多线程,命令仍单线程。

Q3:Redis 五大数据类型及使用

String(计数、缓存)、Hash(对象)、List(队列)、Set(去重、交并差)、ZSet(排行榜)。 更多:BitMap(签到)、HyperLogLog(UV 去重估算)、Geo(附近)、Stream(MQ)。

Q4:Redis 是单线程还是多线程

  • 命令执行:单线程。
  • 持久化、AOF 重写、删除大 key:异步线程(BIO)。
  • 6.0 网络 IO:多线程。

二、持久化

Q5:RDB vs AOF

RDBAOF
形式二进制快照命令追加
恢复
数据安全可能丢失最多丢 1 秒(everysec)
文件

Q6:AOF 三种刷盘策略

always(每次,慢但安全)、everysec(默认)、no(交给 OS)。

Q7:混合持久化(4.0+)

AOF 文件前半是 RDB 快照 + 后半是增量命令,兼顾速度和安全。

三、过期与淘汰

Q8:过期策略

  • 定期删除:每隔一段时间随机抽查删除过期 key。
  • 惰性删除:访问时检查。
  • 两者结合。

Q9:内存淘汰策略(8 种)

  • noeviction(默认):不淘汰,写入报错。
  • allkeys-lru / volatile-lru:LRU 最近最少使用。
  • allkeys-lfu / volatile-lfu:LFU 最少使用次数(4.0+)。
  • allkeys-random / volatile-random:随机。
  • volatile-ttl:将要过期的优先。

缓存场景推荐 allkeys-lruallkeys-lfu

四、缓存问题

Q10:缓存穿透

查询不存在的数据。 解决:缓存空值(短 TTL)、布隆过滤器、参数校验。

Q11:缓存击穿

热点 key 失效瞬间大量请求。 解决:互斥锁重建、逻辑过期(不真过期,后台异步更新)、热点永不过期。

Q12:缓存雪崩

大量 key 同时失效或 Redis 宕机。 解决:过期时间加随机、Redis 集群、限流降级、多级缓存。

Q13:DB 与缓存一致性

  • Cache Aside:先更 DB,再删缓存。
  • 延迟双删。
  • 强一致:Canal 订阅 binlog + MQ。

五、分布式锁

Q14:Redis 实现分布式锁

redis
SET lock uuid NX PX 30000

释放用 Lua 保证原子:

lua
if redis.call("get", KEYS[1]) == ARGV[1] then
  return redis.call("del", KEYS[1])
else return 0 end

Q15:Redisson 的改进

  • WatchDog 自动续期(默认每 10s 续到 30s)。
  • 可重入(Hash 计数)。
  • 公平锁、读写锁、信号量。

Q16:RedLock

多个独立 Redis 节点同时获取锁,多数成功才算成功,防止单点故障。

六、集群

Q17:主从复制

  • 全量:master 生成 RDB 发给 slave。
  • 增量:master 写命令传播给 slave。

Q18:哨兵 Sentinel

  • 监控 master/slave。
  • master 故障自动选举新 master。
  • 客户端从哨兵获取 master 地址。

Q19:Cluster

  • 16384 个槽,按 CRC16 分配到节点。
  • 客户端直连任意节点,MOVED 重定向。
  • 去中心化、可水平扩展。

Q20:为什么是 16384

作者回答:心跳包更小,节点数通常 < 16384,节省带宽。

七、其他高频

Q21:BigKey

  • 一个 String > 10KB / Hash/List 元素 > 5000。
  • 危害:阻塞(删除、网络)、迁移困难、集群倾斜。
  • 排查:redis-cli --bigkeys
  • 拆分:把大 Hash 拆成多个小 Hash。

Q22:HotKey

  • 排查:监控统计。
  • 解决:本地缓存、多副本(key_1/key_2 分散到不同节点)、限流。

Q23:Pipeline

一次发送多条命令,减少 RTT,非原子

Q24:Lua 脚本

原子执行多条命令(单线程保证不被打断)。

Q25:Redis 6 多线程 IO

io-threads 4,网络读写多线程,命令仍单线程。

高频考点速记

  • 快:内存 + 单线程 + 多路复用。
  • 持久化:RDB 快、AOF 全,混合最好。
  • 三大缓存问题:穿透(不存在)、击穿(热点失效)、雪崩(批量失效)。
  • 分布式锁:NX + EX + Lua 释放 + Redisson 续期。
  • 集群:主从(读写分离)→ 哨兵(高可用)→ Cluster(分片)。