IT策士 10余年一线大厂经验专注 IT 思维、架构、职场进阶。我会在各个平台持续发布最新文章助你少走弯路。准备 Redis 面试最怕碎片化背诵。我为你整理了50 道大厂高频 Redis 面试题覆盖数据结构、缓存、持久化、高可用、分布式锁和性能调优六大模块每题都附带答案要点部分直接给出现场可用的 Python 代码示例。读完这 50 问Redis 面试再无死角。一、基础概念与数据结构10 问1. Redis 为什么这么快纯内存操作数据存在内存中读写微秒级。单线程模型避免上下文切换和锁竞争命令执行天然原子。I/O 多路复用基于 epoll/kqueue 模型高效处理大量并发连接。高效数据结构String、Hash 等底层实现精巧如 ZipList、跳表数据紧凑。2. Redis 的五种基本数据类型是什么各自应用场景String缓存对象、计数器、分布式锁、Session 共享。Hash存储对象用户信息、商品详情方便部分字段更新。List消息队列LPUSHBRPOP、最新列表、栈/队列。Set标签系统、共同好友交集、抽奖去重。Sorted Set排行榜、带权重的消息队列、延时队列。3. Redis 底层数据结构如何优化内存内部编码Stringint整型直接存、embstr短字符串连续分配、raw长字符串。Hash字段少且值短用ziplist压缩列表超出阈值转hashtable。List3.2 后统一用quicklistziplist节点组成的双向链表。Set全为整数时用intset否则hashtable。ZSet元素少且值短用ziplist否则skiplistdict。4. 键的过期策略是怎样的惰性删除访问 key 时检查是否过期过期则删除。定期删除每隔 100ms 随机抽一批设了 TTL 的 key 检查并删除过期 key。两者结合兼顾 CPU 和内存。5. 淘汰策略有哪些LFU 和 LRU 的区别8 种淘汰策略noeviction默认、volatile-lru、allkeys-lru、volatile-random、allkeys-random、volatile-ttl以及 Redis 4.0 的volatile-lfu和allkeys-lfu。LRU最近最少使用看“多久没被访问”。LFU最不经常使用看“被访问次数多少”。LFU 更适合保留热数据。6.DEL和UNLINK有什么不同DEL同步阻塞删除删除大 key 时可能阻塞 Redis。UNLINK异步删除将 key 从键空间移除真正的内存回收由后台线程做不阻塞主线程。Redis 4.0 支持。7. 什么是 Redis 的 Pipeline为什么能提升性能将多个命令打包成一次网络请求发送服务端批量处理后一次性返回结果大幅减少 RTT网络往返时间。注意Pipeline 不是原子操作中间可能插入其他客户端的命令。Python 示例piper.pipeline()pipe.set(k1,v1)pipe.incr(counter)pipe.get(k1)resultspipe.execute()# [True, 1, v1]8.KEYS命令为什么禁用该用什么代替KEYS *会遍历所有键导致 Redis 长时间阻塞生产禁用。替代SCAN游标迭代每次返回少量 key不会阻塞。SCAN 0 MATCH user:* COUNT 100。9. Redis 是单线程的为什么还能处理高并发Redis 6.0 之前纯单线程模型执行命令但 I/O 读写使用了多路复用epoll使得一个线程可以同时处理成千上万个客户端连接。Redis 6.0 后引入多线程 I/O网络数据的读写由多个 I/O 线程并行处理命令执行仍是单线程兼顾安全与性能。10. Redis 事务的 ACID 特性如何原子性事务中的命令要么都执行要么编译时错误都不执行。但不支持回滚运行时错误不会撤销已执行的命令。没有隔离性单线程串行执行天然无脏读、不可重复读。持久性取决于持久化配置默认不保证。二、缓存设计难点10 问11. 缓存穿透、缓存击穿、缓存雪崩的区别及解决方案穿透查不存在的数据请求直达 DB。解决缓存空对象短 TTL、布隆过滤器。击穿热点 key 过期大量请求打到 DB。解决互斥锁SETNX查库重建、逻辑过期异步刷新。雪崩大量 key 同时过期或 Redis 宕机。解决随机 TTL、多级缓存、限流降级、Redis 高可用。12. 如何用布隆过滤器防止缓存穿透Python 怎么实现布隆过滤器预先存所有合法 key请求先查布隆过滤器不在则直接拒绝避免查库。Python 示例基于 Redis 位图class BloomFilter: def __init__(self, redis_client, key, expected_items, false_positive_rate):# 计算 bit 数组大小和哈希函数个数... def add(self, item):foroffsetinself._hash_offsets(item): self.redis.setbit(self.key, offset,1)def exists(self, item):returnall(self.redis.getbit(self.key, offset)foroffsetinself._hash_offsets(item))13. Cache Aside 模式是什么为什么是“删除缓存”而非“更新缓存”读先读缓存miss 则读 DB 并写缓存。写先写 DB再删缓存。删缓存的原因更新缓存可能产生并发写脏数据删除后下次读会从 DB 加载最新数据简单可靠。14. 什么是延迟双删解决了什么问题在写 DB 后先删一次缓存等 DB 主从同步完成后如 500ms再删一次缓存防止因主从延迟导致读请求把旧数据加载到缓存。实现delete cache - update DB - sleep(延迟) - delete cache again。15. 如何保证缓存与数据库的最终一致性采用Cache Aside 过期时间兜底。结合 MQ 或 binlog 异步通知刷新缓存Canal MQ。对于强一致性场景直接读主库并设置较短过期。16. 热点 key 怎么发现和处理发现客户端统计、redis-cli --hotkeys、MONITOR临时。解决本地缓存cachetools、读写分离、key 拆分hotkey:1:0,hotkey:1:1随机分布。17. Redis 缓存与本地缓存的区别各自的适用场景Redis 缓存全局共享独立于应用适合分布式系统更新后所有节点生效。本地缓存如 Pythoncachetools进程内速度快无网络开销但容量小各节点独立适合极热数据或对一致性要求低的配置。18. 如何设计一个缓存更新的定时任务扫描 DB 中变更的数据更新或删除对应 Redis 键。可以利用 Redis 的SET带EX过期让缓存自动失效或通过PUB/SUB通知订阅者刷新。19. 缓存为什么会出现竞态条件怎么解决多个请求同时发现缓存失效同时去查 DB 并写缓存造成 DB 压力。解决加互斥锁SETNX保证只有一个请求去查 DB 并重建缓存。20.SETNX实现分布式锁有什么问题死锁风险未设过期时间。锁过期后业务还在执行导致其他客户端获取锁。无法保证锁在集群环境下的强一致性。三、持久化机制5 问21. RDB 和 AOF 的原理与区别RDB指定时间间隔生成内存快照BGSAVE二进制压缩恢复快可能丢一段时间数据。AOF记录每条写命令实时性高可配置everysec文件可读但文件大、恢复慢。22. 混合持久化是什么有什么优点Redis 4.0 支持aof-use-rdb-preamble yesAOF 重写时将当前数据生成 RDB 格式写入 AOF 文件开头后半部分为 AOF 增量命令。优点恢复速度快RDB 部分数据完整AOF 部分。生产首选。23. AOF 重写机制如何工作后台子进程BGREWRITEAOF遍历当前数据生成最小命令集写入新 AOF 文件。重写期间的新写入命令同时追加到旧 AOF 缓冲区和重写缓冲区。子进程完成后将重写缓冲区的增量追加到新文件然后原子替换旧 AOF。24. 如何选择持久化策略纯缓存数据可重建→ 关闭持久化。一般业务允许丢几分钟数据→ 只开 RDB。重要业务最多丢 1 秒→ 开 AOFeverysec。核心业务 → RDB AOF 混合持久化 异地备份。25. AOF 文件损坏了怎么办Redis 自带redis-check-aof --fix appendonly.aof截断到最后一个有效命令。然后重启 Redis。四、主从复制与高可用8 问26. 主从复制全量同步和部分同步的流程全量同步从节点发送PSYNC ? -1主节点BGSAVE生成 RDB 发给从节点同时记录写命令到复制缓冲区从节点加载 RDB 后执行缓冲命令。部分同步从节点重连时带上runid和offset如果offset在主节点复制积压缓冲区范围内就只传输缺失的命令。27. 复制积压缓冲区是什么设置多大合适一个固定大小的 FIFO 队列记录最近写命令用于部分重同步。默认 1MB可根据写入量和网络稳定性调大如repl-backlog-size 64mb。28. Sentinel 哨兵是如何工作的哨兵集群监控主从节点健康状态。主观下线SDOWN单哨兵认为节点失联。客观下线ODOWN多数哨兵认为主节点下线选举 leader 执行故障转移。故障转移选出最优从节点提升为主让其他从节点同步新主通知客户端新主地址。29. Sentinel 和 Cluster 的区别Sentinel解决高可用监控主节点故障自动转移但数据全量存储写入单点。Cluster解决数据分片和写入扩展通过哈希槽将数据分散在多个主节点每个主节点可配从节点提供故障转移。30. Redis Cluster 的哈希槽是如何工作的共 16384 个哈希槽CRC16(key) % 16384决定键落在哪个槽。每个主节点管理一部分槽客户端根据槽映射将请求发到对应节点。Hash Tag{...}可让多个 key 落到同一槽以支持事务和批量操作。31. MOVED 和 ASK 重定向的区别MOVED键所属槽已永久迁移到另一节点客户端应更新本地槽表后重试。ASK槽正在迁移中本次临时重定向到指定节点客户端不更新槽表需先发送ASKING再执行命令。32. Python 如何连接 Redis Cluster 并实现高可用from redis.clusterimportRedisCluster rcRedisCluster(hostlocalhost,port6371,decode_responsesTrue)rc.set(key,value)Smart Client 自动处理 MOVED/ASK 重定向和故障转移。33. 集群模式下 Lua 脚本有限制吗脚本中访问的所有 key 必须在同一个哈希槽否则报错CROSSSLOT。使用 Hash Tag 将相关 key 映射到同一槽可解决。五、分布式锁7 问34. 用 Redis 实现分布式锁的演进过程SETNX无过期死锁→SET key value EX NX防死锁→ Lua 脚本释放防误删→ 看门狗自动续期防锁过期业务未完成→ Redlock 算法解决单点故障。35. 看门狗Watchdog机制是什么加锁后启动后台定时任务在锁过期时间进行到 1/3 时自动续期直到业务完成显式释放。避免因业务执行超时导致锁提前释放。Python 核心实现def _watchdog_loop(self):whilenot self._stop: sleep(self.expire /3)ifrenew_script(keys[lock_key],args[holder, expire]): print(续期成功)36. Redlock 算法原理和流程在 N 个独立 Redis 节点通常 5 个上顺序尝试加锁使用相同 key、随机值和 TTL。若在多数节点≥ N/21加锁成功且总耗时 TTL则获锁成功。失败则向所有节点发送释放锁请求。锁的有效时间 TTL - 耗时。37. Redlock 安全吗有什么争议网络安全专家认为依赖系统时钟或遇到 GC 长停顿可能导致锁失效。对于强一致性要求场景推荐基于 ZooKeeper 或 etcd 的锁。实际中 Redlock 仍被广泛使用可配合 fencing token 提高安全性。38. Python 有哪些 Redis 分布式锁库redlock-py实现 Redlock 算法。redis-py内置lock方法r.lock(mylock, timeout10)提供上下文管理器自带续期。示例with r.lock(resource,timeout10):# do something39. 分布式锁在秒杀场景中怎么用扣减库存前通过 Lua 脚本判断库存无需额外锁Lua 本身原子。但若涉及跨系统资源如同时扣库存和生成订单可用锁包裹整个流程。40. 锁的可重入性需要吗怎么实现Redis 官方分布式锁不支持可重入但可用redissonJava或自定义使用 ThreadLocal 计数相同线程再次获取时递增计数释放时递减到 0 才真正解锁。六、消息队列与 Stream5 问41. Redis 做消息队列有哪几种方式优缺点ListBRPOP简单队列无 ACK消息弹出即丢失不能重复消费。Pub/Sub广播消息不持久化消费者离线丢失。Stream5.0消费者组、ACK、消息持久化、消息回溯是真正的可靠队列。42. Stream 的消费者组如何工作同组消费者共享消费进度竞争消费消息。使用XREADGROUP读取新消息消息处理后XACK确认。若消费者崩溃消息仍在 pending 中可通过XCLAIM转移给其他消费者。43. 消息积压怎么办如何监控XINFO STREAM查看长度、pending 数。临时扩容消费者数量设置MAXLEN限制 Stream 长度防止无限膨胀。为无法处理的消息设计死信队列。44. 如何保证消息不丢生产者XADD后即持久化取决于 AOF/RDB 配置。消费者处理完再XACK加上定时任务扫描 pending 重试或转移。45. Redis Stream 与 Kafka 的对比Kafka 吞吐量更高支持海量堆积磁盘适合大数据管道。Stream 轻量、零运维适合中小型可靠消息场景且复用现有 Redis。七、性能优化与运维5 问46. 如何发现慢查询怎么优化SLOWLOG GET 10查看慢日志设置slowlog-log-slower-than 10001ms。优化避免KEYS、大 Key使用SCAN替换复杂查询用 Lua 合并命令使用 Pipeline。47. 大 Key 有什么危害如何排查和优化危害内存不均、迁移阻塞、删除时主线程卡顿。排查redis-cli --bigkeys、MEMORY USAGE key、Python 扫描脚本。优化拆分大 Hash/List采用UNLINK异步删除分批删除。48. 线上 Redis 变慢了从哪些方面排查慢日志分析看是否有慢命令。检查 CPU/内存/网络使用率。查看持久化是否影响BGSAVE对磁盘的压力。连接数是否打满是否存在热 key。是否触发了内存淘汰evicted_keys增加。49. 如何做 Redis 性能基准测试redis-benchmark -n 100000 -c 50 -q -t set,get自定义 Python 脚本测试带业务逻辑的 Pipeline 和序列化开销。50. Python 客户端连接池的注意事项避免每次请求新建连接使用全局连接池单例。max_connections设置合适并发数 缓冲。开启health_check_interval和retry_on_timeout。在异步项目中使用redis.asyncio客户端以利用事件循环。想了解更多还可以去各个平台搜索「IT策士」一起升级 IT 思维