FXJ Wiki

Back

收录内容#

  • Redis 总结 里的高频问题清单
  • Redis常见面试题 里的缓存定位、数据结构、线程模型、持久化笔记

Redis 知识点总览#

知识点#

使用思维导图进行总结

牛客小月:高频问题:

  • Redis 的数据类型有哪些?应用场景?
  • Redis 的数据类型的底层数据结构你了解吗?
  • ZSet 为什么使用 SkipList 跳表实现?SkipList 跳表是什么?
  • Redis 如何实现分布锁?
  • SetNx 实现的分布锁有什么问题?
  • Redisson 分布式锁底层使用什么数据结构?
  • Redisson 分布式锁的好处有哪些?
  • 解释一下如何实现可重入?
  • 超市续约的看门狗机制了解吗?
  • Redisson 分布式锁的问题是什么?如何解决?
  • 介绍 Redis 的持久化方式(RDB、AOF、混合持久化)?优缺点?
  • Redis 的内存淘汰策略有哪些?
  • 什么是缓存击穿/穿透/雪崩?分别怎么解决?
  • 什么是热 Key 问题?影响?解决方案?
  • 什么是大 Key 问题?影响?解决方案?
  • Redis 的高可用了解吗?主从?哨兵?Redis cluster?
  • 除了官方的还了解过其他的 Redis 高可用方案吗?
  • 主从数据同步的原理了解吗?
  • Redis 是 AP 还是 CP 的?
  • Redis 支持事务吗?
  • Redis 支持事务回滚吗?

为什么大家总爱把 Redis 放到 MySQL 前面#

Apple Notes 里这块写得很直接:Redis 之所以常被拿来做 MySQL 缓存,就是因为它同时占住了高性能高并发

  • MySQL 的主存储在磁盘,哪怕有 Buffer Pool,随机读写的平均代价也明显高于内存。
  • Redis 直接把热点数据放在内存里,读路径短,QPS 可以远高于 MySQL。
  • 所以很多读请求根本不该一路打到数据库,而是先被 Redis 挡掉。

这题面试里别答成“Redis 快,所以用 Redis”。更稳的说法是:

  • Redis 适合承接热点读临时状态计数器排行榜短期会话信息
  • MySQL 负责真正的持久化主存储;
  • 两者搭配以后,数据库承担的是回源和最终一致性,不再直接扛所有高频读取。

Redis 和 Memcached 的区别#

这块也是 Apple Notes 里的高频点:

共同点:

  • 都是基于内存的数据库;
  • 都能拿来做缓存;
  • 都支持过期;
  • 性能都很高。

不同点:

  • Memcached 基本就是纯 key-value;Redis 数据结构丰富很多。
  • Memcached 没有 Redis 这一套比较完整的持久化机制。
  • Memcached 没有 Redis 原生的集群、发布订阅、Lua、事务等能力。
  • Redis 更像“内存数据结构服务器”,而不只是一个缓存盒子。

Redis 数据类型和使用场景#

先把最常见的数据类型和场景放一起看

类型常见场景
String缓存对象、计数器、分布式锁、共享 session
Hash缓存对象、购物车、按字段读取的用户信息
List简单消息队列、时间线、双端队列
Set去重、点赞、共同关注、抽奖
ZSet排行榜、带权重排序、延迟队列
Bitmap签到、登录状态、二值状态统计
HyperLogLogUV、海量去重计数
GEO地理位置检索
Stream更完整的消息队列语义

这些类型底层大概是什么#

String#

原笔记和 Apple Notes 都提到了 SDS

  • 二进制安全,不只存文本;
  • 取长度是 O(1)O(1),因为有 len 字段;
  • 拼接前会检查空间,不会像 C 字符串那样容易缓冲区溢出。

List#

  • 老资料里常写双向链表 / 压缩列表;
  • 现在更应该记成 quicklist + listpack 这条线。

你面试里不用把版本细节背得很死,但要知道:Redis 会针对“小而紧凑”和“大而频繁变更”的场景切不同实现,不是所有结构都一把梭哈希表。

Hash#

  • 小对象时会尽量紧凑存;
  • 大一点再切到真正的哈希表结构。

所以它很适合缓存对象,尤其是“对象里只会更新少数字段”的场景。

Set#

  • 元素全是整数且规模不大时,会走整数集合;
  • 否则走哈希表。

ZSet#

这一块经常被追问:为什么底层爱说“跳表”?

因为 ZSet 的核心需求是两件事同时成立:

  • 能按成员快速查;
  • 还能按 score 有序遍历、做范围查询。

所以通常会把:

  • 哈希表用来做成员到分值的定位;
  • 跳表用来做按分值排序和区间操作。

哪些结构最容易出现在业务里#

  • String:缓存详情页、验证码、计数器。
  • Hash:用户资料、购物车。
  • Set:去重关系。
  • ZSet:排行榜、延迟任务。
  • Bitmap:签到统计。
  • HyperLogLog:UV。

为什么 Redis 单线程还这么快#

这题很容易答偏。Apple Notes 里专门强调了一句:

Redis 的“单线程”主要是指从接收请求到执行命令、返回结果这一条主命令路径是单线程。

它并不是整个进程里只有一个线程。

Redis 真正的线程模型#

  • 主线程:事件循环、网络读写、命令执行。
  • 后台线程(BIO):处理关闭文件、AOF 刷盘、惰性释放内存等耗时任务。
  • Redis 6 之后:还可以开 I/O 线程分担网络收发压力,但命令执行仍然是单线程

为什么快#

这块按笔记里的顺序记就很顺:

  • 大部分操作都在内存里完成;
  • 数据结构专门为高频读写设计;
  • 命令执行单线程,省掉了大量锁竞争和线程切换;
  • epoll 这种 I/O 多路复用,一条线程就能同时盯很多连接。

所以 Redis 的瓶颈很多时候不在 CPU,而在:

  • 内存;
  • 网络带宽;
  • 大 Key / 热 Key;
  • 慢命令和不合理数据结构。

Redis 6 为什么又引入了 I/O 线程#

并不是因为“单线程不行了”,而是网络 I/O 有时会先成为瓶颈。

所以 Redis 6 做的是:

  • 让多个 I/O 线程分担网络读写;
  • 命令真正执行仍然交给主线程。

也就是说,它优化的是“收发包”,不是把命令执行模型改成多线程并发执行。

持久化:Redis 不只是一个一断电就没数据的缓存#

RDB#

RDB 是快照:

  • 在某个时间点把内存里的数据整体落成一个快照文件;
  • 恢复快;
  • 文件通常也更紧凑;
  • 但两次快照之间如果宕机,会丢这一段窗口内的数据。

AOF#

AOF 是把写命令追加到日志里。

Apple Notes 里这块强调的是:Redis 的 AOF 是执行完命令之后再记日志

优点:

  • 少了一步额外的命令合法性检查;
  • 当前命令执行路径更直接。

代价:

  • 如果命令执行完但 AOF 还没来得及落盘就宕机,还是会丢数据;
  • AOF 记录本身如果都在主线程路径上,也可能影响后续命令。

三种常见刷盘策略#

  • appendfsync always:每次写都刷盘,最稳但最慢;
  • appendfsync everysec:每秒刷一次,实践里常用;
  • appendfsync no:交给操作系统决定何时刷。

混合持久化#

Redis 4.0 开始支持混合持久化,可以理解成:

  • 先用 RDB 装一大段基础状态;
  • 后面再接增量 AOF。

这样既避免纯 AOF 重放太慢,也能比纯 RDB 少丢一些数据。

这一篇最适合怎么答#

如果面试官一句话问“Redis 为什么适合做缓存”,我会按这条线说:

  1. 内存存储,热点读写非常快;
  2. 数据结构丰富,不只是查字符串;
  3. 命令执行模型简单,单线程避免锁竞争;
  4. 能做持久化,不只是临时缓存;
  5. 能继续往外接高可用、分布式锁、消息队列这些能力。

下一篇再把这些更偏工程的问题接上:

  • 分布式锁;
  • 消息队列;
  • HyperLogLog;
  • 主从 / 哨兵 / Cluster;
  • 缓存一致性。
Redis 为什么适合做缓存:数据结构、线程模型与持久化
https://astro-pure.js.org/blog/interview-redis-1
Author 五香牛肉面
Published at 2026年3月6日
Comment seems to stuck. Try to refresh?✨