【个人学习||Redis】Redis

学习地图

这门学科是干什么的

Redis 是一个基于内存的键值数据库,但如果只把它理解成"缓存工具"就太窄了。更准确地说,它是一个数据结构服务器 :你提交命令,它直接帮你在内存里维护 StringHashListSetZSet 等结构,并提供过期、持久化、复制、高可用、分布式能力。

你学习 Redis 的本质,不是背命令,而是建立这条主线:

业务问题 -> 选合适的数据结构 -> 设计 Key -> 设置过期/持久化/一致性策略 -> 处理高并发与故障

这是后面所有实战和面试题的总框架,必须吃透

它解决什么问题

Redis 最常解决的是下面几类问题:

  1. 加速读取
    把热点数据放在内存里,减少对 MySQL 等磁盘数据库的访问。
  2. 承接高并发
    比如秒杀、热点商品、排行榜、验证码、会话状态。
  3. 临时状态存储
    比如登录状态、短信验证码、接口幂等标记、分布式锁。
  4. 数据结构型需求
    比如计数器、队列、去重集合、排行榜。
  5. 高可用与扩展
    通过主从复制、哨兵、集群支撑线上系统。

它和哪些相关技术有关系

相关技术 和 Redis 的关系 你要建立的联系
MySQL / PostgreSQL Redis 常作为前置缓存或辅助存储 Redis 解决"快"和"并发",关系型数据库解决"持久"和"复杂查询"
Memcached 都能做缓存 Redis 不只是缓存,还支持数据结构、持久化、复制
Kafka / RabbitMQ 都可能出现在异步系统里 Redis 可做轻量队列,但不是强消息中间件的完全替代
Nginx / API 网关 网关扛流量,Redis 扛状态 常结合限流、验证码、登录态
Java / Go / Node.js 业务代码通过客户端操作 Redis 学会"命令模型"和"客户端封装"同样重要
Linux Redis 常部署在 Linux 基础运维、日志、端口、进程、内存排查都离不开
分布式系统 Redis 常被用来做共享状态 要理解一致性、可用性、故障恢复、脑裂风险

学它之前需要哪些前置知识

必须具备

  1. 基本编程能力,知道变量、对象、数组、函数。
  2. 会使用命令行,至少能执行程序、看端口、看日志。
  3. 知道什么是客户端/服务端、TCP 连接、请求/响应。
  4. 知道数据库最基本概念:读、写、索引、事务、持久化。

有了会更顺

  1. Linux 基础。
  2. 一门后端语言的 Redis 客户端用法。
  3. 基本的数据结构知识:哈希表、链表、跳表、集合。

真正重要的 20% 核心内容是什么

下面这些内容,决定你是否真正掌握 Redis 的 80% 实战价值:

  1. Redis 的定位和边界
    它适合什么,不适合什么。
  2. 五大核心数据类型
    StringHashListSetZSet 的使用场景。
  3. 缓存设计
    缓存命中、穿透、击穿、雪崩、一致性。
  4. 过期机制与淘汰策略
    Key 为什么会过期、什么时候真正删除、内存满了怎么办。
  5. 持久化
    RDBAOF 的区别、取舍、恢复过程。
  6. 高可用
    主从复制、哨兵、集群的作用边界。
  7. 性能与排错
    大 Key、热 Key、阻塞命令、慢查询、内存膨胀。

哪些内容是初学者容易陷入、但不值得一开始深挖的

先知道,后深入

  1. Redis 源码级对象系统细节。
  2. 每一种内部编码转换阈值。
  3. 集群槽位迁移细节和故障注入。
  4. LuaFunctionModule 的深层实现。
  5. HyperLogLogBitmapGEOStream 的边缘用法。
  6. 内存分配器 jemalloc 的源码细节。

初学者最容易学偏的地方

  1. 只背命令,不理解"为什么选这个数据结构"。
  2. 只会把 Redis 当缓存,不知道它还能承接状态和结构化场景。
  3. 只会 SET/GET,不会设计 Key、TTL、一致性策略。
  4. 只会用,不会解释为什么快、为什么会丢数据、为什么会出现缓存雪崩。
  5. 一上来就学集群搭建,却连单机行为都说不清。

学习顺序

推荐学习顺序

  1. 第一阶段:入门认知
    先搞清 Redis 到底是什么、为什么快、为什么大家爱用它。
  2. 第二阶段:核心概念
    String/Hash/List/Set/ZSet 的场景和命令吃透。
  3. 第三阶段:核心机制
    过期、淘汰、事务、发布订阅、流水线。
  4. 第四阶段:底层原理
    事件循环、I/O 多路复用、对象编码、持久化与复制主线。
  5. 第五阶段:工程实践
    缓存设计、分布式锁、限流、排行榜、会话共享、高可用选型。
  6. 第六阶段:常见问题与排错
    大 Key、热 Key、阻塞、慢日志、内存打满、复制延迟、连接异常。
  7. 第七阶段:面试与评估
    用定义题、原理题、场景题、排错题建立稳定输出能力。
  8. 第八阶段:学习总结与知识闭环
    把知识串成体系,形成"理解、上手、排错、面试"的闭环。

正确的学习方法论

  1. 先场景,后命令
    先想"我要解决什么问题",再学 Redis 的命令。
  2. 先直觉,后定义,最后原理
    否则会在术语里迷路。
  3. 先单机,后分布式
    单机行为搞不懂,集群一定会学乱。
  4. 先主干,后枝叶
    五大数据类型、缓存设计、持久化、高可用,这些必须先掌握。

企业里通常怎么用 Redis

  1. 热点数据缓存。
  2. 登录态、会话状态共享。
  3. 验证码、限流、幂等控制。
  4. 排行榜、计数器、点赞、关注关系。
  5. 分布式锁和轻量级队列。

面试官通常怎么问 Redis

  1. Redis 为什么快。
  2. Redis 和 MySQL / Memcached 的区别。
  3. 五种数据类型分别适合什么场景。
  4. 过期删除和内存淘汰策略。
  5. 缓存穿透、击穿、雪崩怎么处理。
  6. RDB 和 AOF 如何取舍。
  7. Redis 是单线程吗。
  8. 如何保证高可用。

必须掌握 vs 知道即可

层次 必须掌握 知道即可
入门 Redis 定位、为什么快、基本命令 配置项全量细节
核心 5 大数据类型、TTL、持久化、高可用基本概念 冷门命令、边缘数据类型
实战 缓存设计、热点问题、锁、限流、排错 源码级内存结构
面试 原理解释能力、场景选型能力 特别深的源码优化细节

第一阶段:入门认知

1. 学什么

这一阶段我们先不追求"会很多命令",而是先建立 Redis 的正确直觉。

你要学会的内容有:

  1. Redis 到底是什么。
  2. 它为什么常被拿来做缓存。
  3. 它和 MySQL、Memcached 的本质区别。
  4. Redis 的基本工作方式:客户端发命令,服务端在内存中操作数据并返回结果。
  5. 最小命令集:PINGSETGETDELEXPIRETTL
  6. Redis 学习的设计哲学。

学习本质

Redis 入门最重要的不是记住多少命令,而是建立一句话认知:

Redis 是一个用内存换速度、用数据结构直接服务业务场景的系统。

这句话是 必须吃透 的,因为后面所有话题都会回到这里。

2. 为什么重要

如果你第一阶段就把定位搞错,后面会出现两类典型问题:

  1. 把 Redis 当成万能数据库
    结果把本该放在 MySQL 的核心业务数据也塞进去,最后一致性和恢复都很痛苦。
  2. 把 Redis 当成只会缓存字符串的小工具
    结果看不到它在排行榜、计数器、集合去重、会话共享中的价值。

这一阶段的重要性在于,它解决三个现实问题:

  1. 你能判断什么时候该用 Redis。
  2. 你能向别人解释 Redis 为什么快。
  3. 你能搭起一个最小可用环境并做基础操作。

3. 核心概念

3.1 用类比先理解

可以把 Redis 想成一个"超快的、住在内存里的、按命令办事的值班员":

  1. 你把钥匙牌 key 交给它。
  2. 它帮你保管对应的内容 value
  3. 你也可以告诉它"这份东西 60 秒后自动作废"。
  4. 它支持的不是单一盒子,而是很多数据结构盒子。

3.2 技术定义

Redis 是一个开源的、基于内存的、支持多种数据结构的键值数据库,提供高性能读写能力,并支持持久化、复制、过期、高可用等能力。

3.3 核心术语

术语 直觉理解 技术定义 先掌握到什么程度
Key 数据的名字 Redis 中数据访问的唯一标识 必须掌握
Value 数据内容 Key 对应的值,可是不同数据结构 必须掌握
TTL 剩余寿命 Key 距离过期还有多少秒 必须掌握
EXPIRE 设置保质期 给 Key 设置过期时间 必须掌握
In-memory 数据放内存里 主要读写发生在内存,不靠磁盘直接查询 必须掌握
Persistence 落盘保存 把内存数据保存到磁盘,以便重启恢复 先知道,后深入
RESP 通信语言 Redis 客户端与服务端交互协议 先知道,后深入
Logical DB 逻辑分库 Redis 的编号数据库,如 01 知道即可

3.4 Redis、MySQL、Memcached 的区别

对比项 Redis MySQL Memcached
数据位置 内存为主 磁盘为主 内存
数据模型 键值 + 多种数据结构 关系型表 纯键值
查询方式 按 Key / 命令操作 SQL 按 Key
持久化 支持 强项 通常不强调
常见角色 缓存、状态、计数、排行 核心业务数据 简单缓存
复杂查询 不擅长 擅长 不擅长

3.5 它解决什么实际问题

第一阶段你要能把 Redis 的价值压缩成 3 句话:

  1. 它让热点数据访问更快。
  2. 它让临时状态共享更容易。
  3. 它让一些常见业务结构不必自己在代码里重造轮子。

4. 原理解释

4.1 Redis 为什么快

先用直觉解释:

  1. 数据主要在内存
    访问内存比访问磁盘快得多。
  2. 命令模型简单
    大多数操作都是直接按 Key 找到值并处理。
  3. 核心执行路径短
    请求进来,解析命令,操作内存,返回结果。
  4. 避免了很多关系型数据库的复杂开销
    不需要 SQL 解析、复杂执行计划、磁盘页管理那一套重流程。

4.2 工作流程

一个最基础的 Redis 请求,通常会经历这些步骤:

  1. 客户端与 Redis 建立 TCP 连接。
  2. 客户端把命令按 RESP 协议发给 Redis。
  3. Redis 事件循环读取请求。
  4. Redis 解析命令并找到对应处理逻辑。
  5. Redis 在内存数据结构中执行操作。
  6. Redis 把结果返回给客户端。
  7. 如果配置了持久化或复制,后台还会继续做落盘或同步。

4.3 设计思想

必须吃透
  1. 用内存换时间
    Redis 牺牲部分成本,换来极高吞吐和极低延迟。
  2. 用数据结构直接贴业务
    排行榜就用有序集合,计数器就用字符串自增,而不是都塞成一坨文本。
  3. 核心简单,命令原子
    单条命令的执行语义清晰,这让并发场景更容易控制。

4.4 关于"Redis 是单线程吗"

这是高频混淆点,第一阶段先建立正确说法:

  1. Redis 执行命令的主路径长期以单线程模型著称。
  2. 这不等于 Redis 整个进程完全只有一个线程。
  3. 现代 Redis 在网络 I/O、后台持久化等方面会使用额外线程。

你在面试里不要只背"Redis 是单线程",更准确的表达是:

Redis 的命令执行核心路径以单线程模型为主,但现代版本并不是整个系统只有一个线程。

5. 示例

5.1 最小可运行示例

如果你本机有 Docker,可以直接启动一个 Redis:

bash 复制代码
docker run -d --name redis-demo -p 6379:6379 redis:7

进入客户端:

bash 复制代码
redis-cli -h 127.0.0.1 -p 6379

然后执行最小命令集:

redis 复制代码
PING
SET user:1 "Alice"
GET user:1
EXPIRE user:1 60
TTL user:1
DEL user:1
GET user:1

你应该看到类似结果:

text 复制代码
PONG
OK
"Alice"
(integer) 1
(integer) 59
(integer) 1
(nil)

5.2 这个示例到底说明了什么

  1. Redis 不是"只能缓存页面",它本质上是在管理 Key 和 Value。
  2. EXPIRE 说明 Redis 天生支持"临时数据"。
  3. TTL 让你观察 Key 的剩余生命周期。
  4. 这已经足够模拟验证码、登录态、短期缓存等大量真实场景。

5.3 如果你更习惯代码

下面是一个 Node.js 示例,展示最基础的缓存读取流程:

ts 复制代码
import Redis from "ioredis";

const redis = new Redis("redis://127.0.0.1:6379");

async function main() {
  await redis.set("article:1", JSON.stringify({ id: 1, title: "Redis 入门" }), "EX", 60);
  const value = await redis.get("article:1");
  console.log(value);
  console.log(await redis.ttl("article:1"));
  await redis.quit();
}

main().catch(console.error);

6. 工程实践

6.1 真实工程场景

场景:电商商品详情页访问量很高,数据库压力过大。

目标:把商品详情缓存到 Redis,降低 MySQL 压力。

6.2 操作步骤

  1. 用户请求 /product/1001
  2. 服务先查 Redis:GET product:1001
  3. 如果命中,直接返回。
  4. 如果没命中,查 MySQL。
  5. 查到后写回 Redis:SET product:1001 <json> EX 300
  6. 后续 5 分钟内的重复请求都直接走 Redis。

6.3 运行流程图

text 复制代码
用户请求
  -> 应用服务
    -> 先查 Redis
      -> 命中:直接返回
      -> 未命中:查 MySQL -> 回写 Redis -> 返回结果

6.4 一个最小工程代码片段

ts 复制代码
async function getProduct(id: number) {
  const key = `product:${id}`;

  const cached = await redis.get(key);
  if (cached) {
    return JSON.parse(cached);
  }

  const product = await db.product.findById(id);
  if (!product) {
    return null;
  }

  await redis.set(key, JSON.stringify(product), "EX", 300);
  return product;
}

6.5 这一步解决了什么问题

  1. 数据库不必每次都抗同样的读请求。
  2. 热点数据能在更短时间内返回。
  3. 应用可以把"快读"与"准存"职责拆开。

6.6 企业里的真实用法提醒

企业里不会只写一个 GET/SET 就结束,通常还会考虑:

  1. Key 命名规范。
  2. TTL 多久合适。
  3. 数据更新后怎么删缓存或更新缓存。
  4. 热点数据失效时会不会把数据库打穿。

这些问题我们会在后续阶段系统展开。当前阶段先知道它们存在,不要一上来就钻太深。

7. 常见误区

误区 为什么错 正确认知
Redis 就是缓存 过于狭隘 Redis 还是状态存储和数据结构工具
Redis 能替代 MySQL 边界混乱 Redis 更擅长快读和临时状态,不擅长复杂关系查询
设置了 EXPIRE 就会在那一秒立刻删掉 过于机械 Redis 结合惰性删除和定期删除,不保证"秒级准点销毁"
Redis 是单线程,所以性能一般 因果倒置 Redis 因为内存访问和简洁执行路径,反而非常快
有 Redis 就不会丢数据 忽略持久化配置 是否丢数据取决于持久化、复制和故障场景
Key 随便命名就行 忽视工程规范 Key 设计直接影响可维护性和排错效率

初学者最常踩的坑

  1. 不设置过期时间,临时数据越堆越多。
  2. 把大对象整块塞进去,后面很难更新和排查。
  3. 缓存命中后不理解数据来源,排错时找不到源头。
  4. 看到 Redis 很快,就想把什么都放进去。

8. 面试题

高频面试题 1

Redis 是什么?

回答骨架:

  1. Redis 是基于内存的键值数据库。
  2. 它支持多种数据结构,不只是简单字符串缓存。
  3. 常用于缓存、计数器、排行榜、会话共享、分布式锁等场景。

高频面试题 2

Redis 为什么快?

回答骨架:

  1. 数据主要存内存。
  2. 命令模型简单,执行路径短。
  3. 很多操作是 O(1) 或接近常数级。
  4. 避免了关系型数据库的复杂查询和磁盘 I/O 开销。

高频面试题 3

Redis 和 MySQL 的区别是什么?

回答骨架:

  1. Redis 更偏向高速访问和临时/热点数据。
  2. MySQL 更偏向持久化、事务、一致性和复杂查询。
  3. 两者通常不是替代关系,而是配合关系。

高频面试题 4

Redis 是单线程吗?

回答骨架:

  1. 核心命令执行路径以单线程模型为主。
  2. 但现代 Redis 的 I/O 和后台任务会使用多线程。
  3. 所以不能简单地说"Redis 整个系统只有一个线程"。

高频面试题 5

为什么 Redis 适合做缓存?

回答骨架:

  1. 访问快,延迟低。
  2. 支持 TTL,适合存放临时热点数据。
  3. 可以显著减轻后端数据库压力。

9. 自测题

概念自测

  1. 用你自己的话解释:Redis 为什么不是"只是缓存"。
  2. 为什么说 Redis 和 MySQL 不是替代关系,而是分工关系?
  3. TTLEXPIRE 各自是干什么的?
  4. 为什么"Redis 是单线程"这句话并不完整?

操作自测

  1. 启动一个 Redis 实例。
  2. 写入 name=redis
  3. 给它设置 30 秒过期时间。
  4. 查看剩余生存时间。
  5. 删除这个 Key。

场景自测

判断下面场景是否适合 Redis,并说出原因:

  1. 首页热点商品缓存。
  2. 用户 5 分钟短信验证码。
  3. 核心订单明细长期唯一存储。
  4. 实时排行榜。

第一阶段练习题

练习 1:一分钟解释 Redis

请你尝试用 1 分钟回答下面这个问题:

"Redis 是什么,它解决什么问题,为什么快?"

要求:

  1. 不超过 150 字。
  2. 要同时提到"内存""数据结构""缓存/高并发"。

练习 2:命令实操

请你自己实际执行下面命令,并写出每一步的返回结果:

redis 复制代码
SET login:code "842731"
EXPIRE login:code 120
TTL login:code
GET login:code
DEL login:code
GET login:code

练习 3:场景判断

下面 4 个场景,哪些优先考虑 Redis,哪些不要直接拿 Redis 当主存储?请说明理由。

  1. 热门文章阅读数。
  2. 用户登录会话。
  3. 财务流水主账本。
  4. 秒杀库存的高并发扣减辅助控制。

练习 4:对比题

请你自己填完这个表:

对比项 Redis MySQL
存储位置
擅长场景
是否适合复杂查询
是否适合热点高并发读

练习 5:工程表达题

请你回答:

"如果商品详情页访问量很高,为什么要先查 Redis,再查 MySQL?"

要求:

  1. 从性能角度回答一次。
  2. 从系统分层角度再回答一次。

10. 学完标志

学完这一阶段后,你应该能做到:

  1. 用自己的话准确解释 Redis 是什么。
  2. 说清 Redis 解决的核心问题。
  3. 说出 Redis 为什么快,而不是只会背"单线程"。
  4. 搭建一个最小 Redis 环境并完成 SET/GET/EXPIRE/TTL/DEL 操作。
  5. 判断一个场景是更适合 Redis,还是更适合 MySQL。
  6. 用"缓存商品详情"这个案例解释 Redis 在企业中的基本价值。

进入下一阶段前的达标标准

如果你已经能独立完成下面 3 件事,就可以进入下一阶段:

  1. 不看资料说清 Redis 的定位与边界。
  2. 实际执行基础命令并理解返回值。
  3. 说出至少 3 个 Redis 适合的业务场景。

下面直接进入第二阶段,并把整套 Redis 学习内容一次性闭环讲完。

第二阶段:核心概念

1. 学什么

这一阶段的核心任务只有一句话:

学会把业务需求翻译成 Redis 数据结构和命令。

你需要掌握的重点包括:

  1. 五大核心数据类型:StringHashListSetZSet
  2. 每种类型最常见的命令。
  3. 每种类型最典型的业务场景。
  4. Key 设计方法。
  5. "业务问题 -> 数据结构选型 -> 命令设计"的思维方式。

2. 为什么重要

大部分 Redis 的使用成败,不取决于你会不会冷门命令,而取决于你会不会选类型。

它解决的现实问题是:

  1. 避免把所有数据都粗暴塞成字符串,导致更新困难、性能差、排错难。
  2. 让业务代码直接借力 Redis 的数据结构能力,而不是自己造轮子。
  3. 建立"数据建模"能力,这正是从初学者走向工程实践的关键一步。

如果这一阶段吃透了,你后面学缓存、锁、排行榜、限流时都会明显轻松。

3. 核心概念

3.1 五大数据类型总览

类型 直觉理解 常见命令 典型场景 选型关键词
String 一个值 SET GET INCR 缓存对象、计数器、验证码 单值、简单、通用
Hash 一个对象的多个字段 HSET HGET HGETALL 用户信息、商品字段 对象字段、局部更新
List 有顺序的列表 LPUSH RPUSH LPOP RPOP 简单队列、消息暂存 顺序、头尾操作
Set 无序且去重的集合 SADD SREM SISMEMBER 标签、去重、共同关注 去重、成员判断
ZSet 带分数的有序集合 ZADD ZRANGE ZREVRANK 排行榜、优先队列 排序、TopN、范围查询

3.2 一句话选型法

  1. 只需要存一个值,优先看 String
  2. 需要存一个对象的多个字段,优先看 Hash
  3. 需要按进入顺序处理,优先看 List
  4. 需要去重、判断是否存在,优先看 Set
  5. 需要排序、排名、按分值区间查,优先看 ZSet

3.3 典型术语

术语 定义 为什么要懂
Member 集合或有序集合中的成员 Set/ZSet 的核心元素
Score 有序集合成员的分值 决定排序
Field Hash 中的字段名 用于对象拆分
Value 字段值或 Key 对应值 实际数据内容
Key Pattern Key 命名模式 影响维护性和排错效率

3.4 Key 设计规范

Redis 不是只要能用就行,Key 设计本身就是工程能力。

推荐规则:

  1. 使用业务前缀:user:product:order:
  2. 使用层级分隔:user:1001:profile
  3. 保持语义一致:同类业务同类命名。
  4. 对临时数据尽量配 TTL。
  5. 不要把版本、环境、租户信息混乱塞在一起。

一个实用示例:

场景 推荐 Key
用户基础信息 user:1001:profile
商品详情缓存 product:2001:detail
短信验证码 sms:login:13800138000
榜单 rank:game:s1

4. 原理解释

4.1 为什么 Redis 要提供多种数据结构

如果 Redis 只提供字符串,会发生三件麻烦事:

  1. 你要自己在应用层序列化和反序列化复杂结构。
  2. 一个字段变更也要重写整个对象。
  3. 排行、去重、队列这些场景都要自己实现,复杂度高。

Redis 的设计思路是:

把业务里高频出现的数据组织方式直接做成原生命令。

这就是它叫"数据结构服务器"的原因。

4.2 选型流程

面对一个需求时,建议按这 5 步判断:

  1. 数据是单值还是多字段对象。
  2. 是否需要顺序。
  3. 是否需要去重。
  4. 是否需要排序。
  5. 是否需要频繁局部更新。

4.3 内部设计的直觉

虽然你现在还没学到底层编码,但先建立这个概念:

  1. Redis 对外暴露的是统一命令。
  2. Redis 对内会根据数据规模和数据类型选择更省空间或更快的内部编码。
  3. 所以同样是 Hash,小对象和大对象在内部实现上可能不一样。

这也是为什么"理解类型语义"比背内部细节更重要。

4.4 类型之间的易混淆点

容易混淆 区别核心 正确选型
String vs Hash 一个整体值 vs 多字段对象 对象字段多且可能局部更新时用 Hash
List vs Set 有顺序不去重 vs 无顺序去重 队列看顺序,用 List;标签看去重,用 Set
Set vs ZSet 去重集合 vs 带分值排序集合 需要排名或区间排序时用 ZSet

5. 示例

5.1 最小可运行示例

redis 复制代码
SET page:view:1001 1
INCR page:view:1001

HSET user:1001 name "Alice" age 20 city "Shanghai"
HGET user:1001 name

LPUSH queue:order 1001 1002 1003
RPOP queue:order

SADD tag:redis user:1 user:2 user:2
SISMEMBER tag:redis user:1

ZADD rank:game 98 "u1" 100 "u2" 95 "u3"
ZREVRANGE rank:game 0 2 WITHSCORES

5.2 这个示例说明了什么

  1. 同样是"存数据",不同类型提供的是不同操作语义。
  2. INCR 说明字符串不仅能存文本,也能做数值原子自增。
  3. Hash 适合对象字段。
  4. Set 天然去重。
  5. ZSet 天然适合榜单。

5.3 一个业务到类型的映射例子

业务需求 推荐类型 原因
文章浏览数 String 只需要自增计数
用户资料 Hash 多字段、可局部更新
待处理任务队列 List 头尾出入队
文章标签集合 Set 去重、成员判断
游戏积分排行榜 ZSet 按分数排序

6. 工程实践

6.1 真实工程场景

场景:做一个社区系统,需要同时支持用户资料、文章点赞、在线排行榜。

6.2 推荐建模

  1. 用户资料:Hash
    user:1001:profile
  2. 某文章点赞用户集合:Set
    post:5001:likes
  3. 周榜积分:ZSet
    rank:weekly

6.3 操作步骤

  1. 注册用户时写入 Hash
  2. 点赞时 SADD post:5001:likes user:1001
  3. 判断是否已点赞时 SISMEMBER
  4. 用户得分变化时 ZINCRBY rank:weekly 10 user:1001
  5. 查询前十名时 ZREVRANGE rank:weekly 0 9 WITHSCORES

6.4 Node.js 最小工程示例

ts 复制代码
import Redis from "ioredis";

const redis = new Redis("redis://127.0.0.1:6379");

async function main() {
  await redis.hset("user:1001:profile", {
    name: "Alice",
    city: "Shanghai",
    level: "3",
  });

  await redis.sadd("post:5001:likes", "user:1001");
  await redis.zincrby("rank:weekly", 10, "user:1001");

  console.log(await redis.hgetall("user:1001:profile"));
  console.log(await redis.sismember("post:5001:likes", "user:1001"));
  console.log(await redis.zrevrange("rank:weekly", 0, 9, "WITHSCORES"));

  await redis.quit();
}

main().catch(console.error);

6.5 企业里的经验法则

  1. 能用语义明确的类型,就不要全部塞 String JSON。
  2. 频繁局部更新的对象优先考虑 Hash
  3. 榜单、排序需求优先考虑 ZSet
  4. 需要去重关系时优先考虑 Set
  5. 先关注业务建模,再关注命令技巧。

7. 常见误区

误区 问题所在 正确认知
一个对象统一序列化成字符串最简单 更新单字段要读全量、改全量、写全量 对象字段多时优先考虑 Hash
List 就是消息队列终极方案 缺少专业消息中间件很多能力 简单队列可用,复杂可靠消息别强行替代
Set 可以做排行榜 它没有分值排序能力 排名用 ZSet
ZSet 只是会排序的 Set 忽略了 score 的业务含义 排序、区间、TopN 都依赖 score
Key 名无所谓 后期很难排查和统计 Key 设计是工程规范的一部分

8. 面试题

  1. Redis 五大数据类型分别适合什么场景?
    回答重点:类型语义 + 业务映射。
  2. 为什么对象存储常推荐 Hash,而不是直接 JSON String?
    回答重点:局部更新、字段读取、内存/维护权衡。
  3. Set 和 ZSet 的区别是什么?
    回答重点:去重 vs 去重+有序。
  4. ZSet 为什么适合排行榜?
    回答重点:score 排序、排名查询、TopN。
  5. 如何设计 Redis Key?
    回答重点:前缀、层级、语义、TTL、可维护性。

9. 自测题

  1. 用户资料、关注列表、文章点赞、实时排行榜分别适合哪种类型?
  2. 如果你要实现"浏览数 +1",为什么优先用 String 而不是 Hash
  3. 为什么"共同关注"场景适合 Set
  4. 为什么排行榜不用 List
  5. 请你自己设计 5 个规范的 Redis Key。

10. 学完标志

学完这一阶段后,你应该能做到:

  1. 看见业务需求时,快速选出合适的数据类型。
  2. 熟练使用五大类型最常见命令。
  3. 理解不同类型背后的业务语义。
  4. 独立设计一套可维护的 Key 规范。
  5. 解释"为什么这个场景用 Hash / Set / ZSet"。

第三阶段:核心机制

1. 学什么

这一阶段不再停留在"存什么",而是学习 Redis "怎么管这些数据"。

重点包括:

  1. 过期机制:EXPIRETTL、惰性删除、定期删除。
  2. 内存淘汰:maxmemory、淘汰策略。
  3. 事务机制:MULTIEXECWATCH
  4. Pipeline:减少网络往返。
  5. 发布订阅:PUBLISH / SUBSCRIBE
  6. 持久化机制的入口认知:RDBAOF

2. 为什么重要

初学者最容易只看到"写进去、读出来",却忽略了两个工程真相:

  1. 数据不是永远留在 Redis 里。
  2. Redis 不是把命令执行完就万事大吉,背后还有内存、持久化和一致性代价。

这一阶段解决的实际问题是:

  1. 为什么设置了 TTL 却不一定准点删除。
  2. 为什么 Redis 内存会打满。
  3. 为什么 Redis 事务和数据库事务不是一回事。
  4. 为什么批量请求会慢,Pipeline 为什么能提速。

3. 核心概念

3.1 过期相关术语

术语 定义 你要理解什么
TTL Key 剩余过期时间 观察 Key 生命状态
EXPIRE 设置秒级过期 临时数据最常用
PEXPIRE 设置毫秒级过期 更细粒度 TTL
惰性删除 访问到过期 Key 时再删 降低无效扫描成本
定期删除 后台周期抽样扫描过期 Key 防止过期数据长期堆积

3.2 内存淘汰策略

策略 含义 适用直觉
noeviction 不淘汰,直接报错 不希望无感丢数据
allkeys-lru 所有 Key 中淘汰最近最少使用 通用缓存常用
volatile-lru 只在设置了 TTL 的 Key 中淘汰 缓存和永久数据混存时
allkeys-lfu 所有 Key 中淘汰最不常使用 热点明显时很实用
volatile-ttl 优先淘汰快过期的 Key 较少作为首选

3.3 事务相关术语

术语 定义 易错点
MULTI 开启事务队列 只是开始排队,不是立刻执行
EXEC 一次性执行事务队列 不提供传统数据库那种回滚
WATCH 乐观锁监听 Key 变化 适合 CAS 风格控制
原子性 单条命令执行不可被打断 不等于多命令天然全局事务

3.4 Pipeline 与 Pub/Sub

机制 解决什么问题 适用边界
Pipeline 减少多次命令的网络往返开销 批量读写提速
Pub/Sub 简单实时消息分发 适合轻量通知,不适合强可靠消息

4. 原理解释

4.1 过期删除为什么不是"准点秒杀"

Redis 之所以不对每个 Key 都单独开一个定时器,是因为代价太高。

它采用两种配合机制:

  1. 惰性删除
    当客户端访问某个 Key 时,Redis 发现它已过期,就顺手删掉。
  2. 定期删除
    Redis 后台会定期随机抽样带过期时间的 Key,清理其中已过期的部分。

设计思想:

用近似高效的方式管理过期,而不是为了绝对准点付出巨大成本。

4.2 内存淘汰为什么必要

Redis 以内存为主,内存不可能无限大。

当达到 maxmemory 后,Redis 必须做选择:

  1. 直接拒绝新写入。
  2. 或按策略淘汰一部分旧数据。

这就是为什么缓存系统必须关注淘汰策略,而关系型数据库更多关注磁盘空间。

4.3 Redis 事务为什么和 MySQL 不一样

Redis 事务的重点是:

  1. 命令会先进入队列。
  2. EXEC 时按顺序一次执行。
  3. 执行期间不会被其他命令插队。

但它和传统 ACID 事务不同,关键差异有两点:

  1. Redis 不提供复杂回滚语义。
  2. 如果事务中某条命令运行时报错,其他命令通常不会像关系型数据库那样整体回滚。

所以它更像"批量顺序执行 + 可选乐观锁",而不是完整数据库事务。

4.4 Pipeline 为什么快

不使用 Pipeline 时:

  1. 客户端发 1 条命令。
  2. 等 Redis 回 1 次。
  3. 再发下一条。

如果有 1000 条命令,光网络往返就很浪费。

Pipeline 的本质是:

一次发多条,减少 RTT,不是减少 Redis 的命令执行次数。

4.5 持久化机制的入口认知

这一阶段先建立两句话:

  1. RDB 像"拍快照"。
  2. AOF 像"记操作日志"。

后面第四阶段再深入讲它们底层是怎么工作的。

5. 示例

5.1 最小可运行示例

redis 复制代码
SET sms:login:13800138000 "843201" EX 300 NX
TTL sms:login:13800138000

MULTI
INCR counter:daily:login
EXPIRE counter:daily:login 86400
EXEC

SUBSCRIBE order:event
PUBLISH order:event "order:1001:paid"

5.2 Pipeline 代码示例

ts 复制代码
const pipeline = redis.pipeline();

for (let i = 1; i <= 3; i++) {
  pipeline.incr(`article:${i}:view`);
}

const result = await pipeline.exec();
console.log(result);

5.3 这个示例说明了什么

  1. 验证码场景很适合 TTL。
  2. MULTI/EXEC 可以把多命令作为一个顺序执行单元。
  3. Pipeline 优化的是网络开销。
  4. Pub/Sub 更偏"即时通知",而不是可靠消息存储。

6. 工程实践

6.1 真实工程场景:短信验证码

目标:

  1. 验证码只允许短期有效。
  2. 防止重复覆盖或无限发送。

步骤:

  1. 生成验证码。
  2. SET sms:login:{phone} code EX 300 NX
  3. 如果返回失败,说明短期内已存在验证码,不再重复发送。
  4. 用户提交验证码时读取并校验。
  5. 校验成功后删除 Key。

6.2 真实工程场景:批量统计

比如要一次更新 1000 个文章阅读数,不适合逐条请求,可以用 Pipeline 批量发命令。

6.3 持久化配置最小示例

conf 复制代码
appendonly yes
appendfsync everysec
save 900 1
save 300 10
save 60 10000

这个配置说明:

  1. 开启 AOF。
  2. AOF 每秒刷盘一次,性能和安全性相对平衡。
  3. 也保留 RDB 快照规则。

7. 常见误区

误区 问题所在 正确认知
设置了 TTL 就会在那一秒立刻删除 把实现想得过于理想化 Redis 采用惰性 + 定期删除
Redis 事务和 MySQL 事务一样 忽略回滚和隔离语义差异 Redis 事务更像队列化原子执行
Pipeline 能让命令本身更快 混淆 CPU 执行和网络往返 Pipeline 主要优化 RTT
Pub/Sub 可以替代 Kafka 忽略持久化、重试、消费确认 Pub/Sub 适合轻通知,不是强消息系统
只要设了 maxmemory 就够了 忽略淘汰策略 还必须选对淘汰策略

8. 面试题

  1. Redis 过期 Key 是怎么删除的?
  2. 惰性删除和定期删除分别解决什么问题?
  3. allkeys-lruvolatile-lru 的区别是什么?
  4. Redis 事务和 MySQL 事务的区别是什么?
  5. Pipeline 为什么能提高性能?
  6. Pub/Sub 适合什么,不适合什么?
  7. RDB 和 AOF 分别是什么思路?

9. 自测题

  1. 为什么 Redis 不给每个 Key 单独挂一个定时器?
  2. 如果缓存和永久数据混在一个实例里,你会更倾向什么淘汰策略?为什么?
  3. MULTI/EXEC 为什么不能简单等同于数据库事务?
  4. 批量执行 1000 次 INCR 时,为什么建议用 Pipeline?
  5. Pub/Sub 和专业消息队列相比缺了哪些能力?

10. 学完标志

学完这一阶段后,你应该能做到:

  1. 说清 Redis 过期机制是如何工作的。
  2. 理解内存淘汰策略并能做基础选型。
  3. 解释 Redis 事务和关系型事务的本质差异。
  4. 在批量命令场景下正确使用 Pipeline。
  5. 对持久化、消息通知这些能力建立初步边界感。

第四阶段:底层原理

1. 学什么

这一阶段要回答"Redis 为什么这样设计",重点包括:

  1. 请求执行生命周期。
  2. 事件循环与 I/O 多路复用。
  3. RESP 协议。
  4. 内部数据结构与编码。
  5. RDBAOF 的底层思路。
  6. 主从复制的基本同步过程。

2. 为什么重要

如果你只会用 Redis 而不理解底层,你会在两个场景里卡住:

  1. 面试被问"为什么快""为什么会阻塞""为什么会丢数据"时说不深。
  2. 线上出问题时不知道从哪个机制下手排查。

底层原理不是为了炫技,而是为了解释现象、做对权衡。

3. 核心概念

3.1 请求生命周期

Client
Socket / RESP 请求
事件循环
命令解析
命令执行
内存数据结构
回复结果
AOF / RDB / 复制等后台路径

3.2 关键术语

术语 定义 为什么重要
事件循环 单线程主循环处理网络事件与命令执行 是 Redis 高性能核心之一
I/O 多路复用 一个线程监听多个连接事件 降低大量连接的调度成本
RESP Redis 序列化协议 客户端与服务端的通信规范
SDS Simple Dynamic String Redis 自己的字符串实现
dict 哈希字典结构 支撑大量 Key 查找
quicklist List 的底层结构之一 兼顾链表与紧凑存储
listpack 紧凑编码结构 小数据更省内存
skiplist 跳表 支撑 ZSet 排序与范围查询
fork + CoW 子进程 + 写时复制 支撑 RDB/AOF 重写的关键机制

3.3 数据类型与底层结构的对应直觉

对外类型 常见内部实现直觉
String SDS / 整数编码
Hash listpack / hashtable
List quicklist
Set intset / hashtable
ZSet listpack / skiplist + dict

3.4 协议示意

一个简单的 PING 在 RESP 中大致会长这样:

text 复制代码
*1
$4
PING

SET name redis 大致会是:

text 复制代码
*3
$3
SET
$4
name
$5
redis

协议设计追求的是:

  1. 易解析。
  2. 可扩展。
  3. 适合高性能网络处理。

4. 原理解释

4.1 为什么 Redis 快,不只是"因为内存"

更完整的解释应该是四层原因叠加:

  1. 内存访问快
    避免磁盘随机 I/O。
  2. 事件循环简单
    主线程串行执行命令,避免大量锁竞争。
  3. I/O 多路复用
    单线程也能高效处理很多连接的可读可写事件。
  4. 数据结构贴业务
    例如 ZSet 的排序查询直接交给底层结构,不需要业务层手搓。

4.2 单线程执行模型的设计思想

Redis 的核心命令执行长期采用单线程模型,背后并不是"不会多线程",而是:

  1. 内存操作本身很快。
  2. 单线程可避免共享状态带来的锁竞争。
  3. 简化实现和一致性保证。

它的代价也很清楚:

  1. 长时间命令会阻塞其他命令。
  2. 大 Key、大批量遍历会拖垮延迟。

所以你会看到工程实践里一直强调:

避免阻塞命令、避免大 Key、避免长事务。

4.3 RDB 的底层思路

RDB 可以理解为"某一时刻内存数据的快照"。

典型过程:

  1. 主进程收到 BGSAVE
  2. fork 出子进程。
  3. 子进程把当前内存视图写成 RDB 文件。
  4. 主进程继续服务请求。
  5. 由于写时复制,主进程后续修改的数据页才会额外复制。

设计权衡:

  1. 恢复速度通常较快。
  2. 文件紧凑。
  3. 但两次快照之间仍可能丢数据。

4.4 AOF 的底层思路

AOF 可以理解为"把写命令按顺序追加到日志"。

典型过程:

  1. 写命令执行成功。
  2. 追加到 AOF 缓冲。
  3. 按配置策略刷盘。
  4. 重启时重新执行日志恢复数据。

设计权衡:

  1. 数据更完整。
  2. 文件可能变大,因此需要 AOF 重写。
  3. 恢复速度通常不如直接加载快照。

4.5 主从复制的基本过程

你先建立一个正确主线:

  1. 从节点连接主节点。
  2. 首次全量同步时,主节点生成 RDB 发给从节点。
  3. 从节点加载 RDB。
  4. 同步过程中及之后,主节点继续把增量命令传播给从节点。
  5. 断线重连后,若条件允许,使用 PSYNC 做部分重同步。

这就是为什么复制会和 RDB、复制偏移量、复制积压缓冲区关联起来。

5. 示例

5.1 最小可运行示例

redis 复制代码
SET age 18
OBJECT ENCODING age

HSET user:1001 name "Alice" age 20
OBJECT ENCODING user:1001

BGSAVE
INFO persistence

5.2 这个示例说明了什么

  1. Redis 对同一种逻辑类型可能采用不同编码。
  2. OBJECT ENCODING 能帮助你观察内部编码。
  3. BGSAVEINFO persistence 能帮助你理解快照状态。

5.3 一个主从配置最小示例

主节点:

conf 复制代码
port 6379
appendonly yes

从节点:

conf 复制代码
port 6380
replicaof 127.0.0.1 6379

6. 工程实践

6.1 真实工程场景:为什么线上会突然卡顿

如果线上 Redis 突然延迟抖动,底层角度常见原因是:

  1. 有大 Key 被遍历或删除。
  2. fork 触发 RDB/AOF 重写时内存压力大。
  3. 某个命令阻塞了主线程。
  4. 网络层或连接数异常。

6.2 真实工程场景:为什么会丢几秒数据

如果你只开了 RDB,且快照间隔较长,那么 Redis 异常退出时,最后一次快照之后的数据可能丢失。

6.3 企业里的常见取舍

目标 常见选择
更快恢复 偏向保留 RDB
更少数据丢失 开启 AOF,常见 everysec
高可用 主从 + 哨兵或集群
大规模扩容 集群分片

7. 常见误区

误区 为什么错 正确认知
Redis 快完全因为单线程 解释过窄 是内存、事件循环、协议、数据结构共同作用
单线程一定比多线程慢 忽略任务性质 内存短操作 + 无锁模型下单线程很高效
RDB 就是实时持久化 误把快照当日志 RDB 是时间点快照
AOF 一定完全不丢数据 忽略刷盘策略 是否丢数据与 appendfsync 策略有关
主从复制就是实时强一致 误判一致性 Redis 复制是异步为主

8. 面试题

  1. Redis 为什么快?请不要只回答"因为内存"。
  2. Redis 为什么采用单线程执行模型?
  3. I/O 多路复用在 Redis 里解决什么问题?
  4. RDBAOF 的底层思路分别是什么?
  5. fork + CoW 在 Redis 持久化里起什么作用?
  6. 主从复制首次同步流程是什么?
  7. 为什么大 Key 会影响 Redis 延迟?

9. 自测题

  1. 请你完整讲一遍一次 Redis 请求从客户端到返回结果的生命周期。
  2. 为什么 Redis 不希望你在主线程执行很慢的大命令?
  3. RDB 为什么既高效又可能丢失一段时间的数据?
  4. AOF everysec 在性能和安全性之间做了什么权衡?
  5. 复制中的全量同步和部分重同步有什么区别?

10. 学完标志

学完这一阶段后,你应该能做到:

  1. 从架构层解释 Redis 为什么快。
  2. 理解 Redis 请求执行生命周期。
  3. 说清 RDB、AOF、复制的基本底层思路。
  4. 解释单线程模型的优点与代价。
  5. 把很多线上现象和底层机制对应起来。

第五阶段:工程实践

1. 学什么

这一阶段把前面学的概念真正落到业务里,重点覆盖:

  1. 缓存设计模式。
  2. 缓存一致性。
  3. 缓存穿透、击穿、雪崩。
  4. 分布式锁。
  5. 限流、幂等、会话共享。
  6. 排行榜、计数器、轻量队列。
  7. 持久化与高可用的工程选型。

2. 为什么重要

企业里很少有人因为不会 SET 而用不好 Redis,真正的问题通常是:

  1. 缓存设计不对,把数据库打挂。
  2. 锁设计不对,导致重复执行或死锁。
  3. 高可用方案理解不清,故障时切换混乱。
  4. 知道命令,但不会搭业务方案。

这一阶段的目标,就是让你从"会用命令"升级到"会做方案"。

3. 核心概念

3.1 缓存三种最常见模式

模式 流程 最常见程度 说明
Cache Aside 先查缓存,未命中查数据库,再回填缓存 最常用 应用控制缓存逻辑
Read Through 应用只管查缓存层,缓存层负责回源 较少直接手写 常见于平台组件化方案
Write Through / Write Back 写缓存时联动写库或延后写库 需谨慎 一致性设计更复杂

3.2 三大缓存问题

问题 现象 典型方案
穿透 查不存在的数据,缓存和数据库都被打 空值缓存、布隆过滤器
击穿 热点 Key 失效瞬间大量请求打数据库 互斥锁、逻辑过期、热点永不过期
雪崩 大量 Key 同时失效,流量打爆后端 TTL 打散、多级缓存、限流降级

3.3 分布式锁关键点

要点 为什么重要
获取锁要原子 防止并发抢锁异常
锁要有 TTL 防止业务异常后永不释放
解锁要校验 owner 防止误删别人的锁
锁不是银弹 长事务、外部调用多时要谨慎

最常见安全写法:

SET lock:order:1001 requestId NX PX 5000

解锁时用 Lua 脚本校验 requestId 后再删除。

3.4 高可用拓扑

方案 适合场景 你至少要会解释什么
单机 Redis 开发、测试、小规模低风险 简单,但单点风险大
主从复制 读扩展、基础备份 主写从读,复制异步
哨兵 Sentinel 高可用主从切换 监控、选主、自动故障转移
Redis Cluster 大规模分片 + 高可用 16384 槽位、分片路由

3.5 常见配置

conf 复制代码
maxmemory 2gb
maxmemory-policy allkeys-lru
appendonly yes
appendfsync everysec

这 4 行已经覆盖了大量线上 Redis 基础配置思路。

4. 原理解释

4.1 Cache Aside 为什么最常见

因为它把缓存控制权交给应用:

  1. 读时先查 Redis。
  2. 未命中查数据库。
  3. 查到后回填 Redis。
  4. 写时更新数据库,再删除缓存或延迟双删。

优点:

  1. 简单。
  2. 易理解。
  3. 适合绝大多数业务。

代价:

  1. 一致性要自己处理。
  2. 热点失效时容易击穿。

4.2 为什么很多更新是"先更新数据库,再删缓存"

这是一个高频面试点。

原因是:

  1. 如果先删缓存,再写数据库,期间并发读请求可能把旧数据重新写回缓存。
  2. 先写数据库,再删缓存,至少保证数据库先变成新值。

它仍不是绝对完美,但在大多数业务里是性价比很高的方案。

4.3 分布式锁为什么不能直接 SETNXDEL

如果你只做:

  1. SETNX lock
  2. 业务执行
  3. DEL lock

可能出现问题:

  1. 业务执行太久,锁过期。
  2. 其他线程拿到新锁。
  3. 原线程执行完再 DEL,把别人的锁删掉。

所以解锁时必须校验"锁是不是我加的",这就是 Lua 解锁脚本的原因。

4.4 Cluster 为什么要用槽位

Redis Cluster 不按"Key 哈希后直接映射机器"做,而是引入 16384 个槽位。

设计好处:

  1. Key 先映射到槽位。
  2. 槽位再分配给节点。
  3. 节点迁移时只需要迁槽,不需要全量重算所有 Key。

这就是集群可扩展性的核心设计。

5. 示例

5.1 最小可运行示例:缓存旁路

ts 复制代码
async function getArticle(id: number) {
  const key = `article:${id}:detail`;
  const cached = await redis.get(key);

  if (cached) {
    return JSON.parse(cached);
  }

  const article = await db.article.findById(id);
  if (!article) {
    await redis.set(key, "null", "EX", 60);
    return null;
  }

  await redis.set(key, JSON.stringify(article), "EX", 300);
  return article;
}

5.2 最小可运行示例:安全释放分布式锁

ts 复制代码
const requestId = crypto.randomUUID();
const lockKey = "lock:order:create";

const ok = await redis.set(lockKey, requestId, "NX", "PX", 5000);
if (!ok) {
  throw new Error("获取锁失败");
}

const unlockScript = `
if redis.call("GET", KEYS[1]) == ARGV[1] then
  return redis.call("DEL", KEYS[1])
else
  return 0
end
`;

try {
  // 执行业务
} finally {
  await redis.eval(unlockScript, 1, lockKey, requestId);
}

5.3 最小可运行示例:限流

redis 复制代码
INCR rate:login:127.0.0.1
EXPIRE rate:login:127.0.0.1 60

这个示例表示 60 秒窗口内统计某来源请求次数,真实工程里通常会封装成 Lua 保证更严谨的原子流程。

6. 工程实践

6.1 场景一:商品详情缓存

步骤:

  1. 读取先查缓存。
  2. 未命中查数据库。
  3. 查不到也缓存空值,防止穿透。
  4. 设置随机 TTL,防止雪崩。
  5. 更新商品时,先更新数据库,再删除缓存。

6.2 场景二:登录会话共享

步骤:

  1. 登录成功后生成 token。
  2. 把会话信息写入 Redis:session:{token}
  3. 设置过期时间,例如 30 分钟。
  4. 网关或服务根据 token 去 Redis 校验身份。
  5. 用户活跃时刷新 TTL。

6.3 场景三:排行榜

步骤:

  1. 用户得分变化时 ZINCRBY
  2. 查询前 N 名用 ZREVRANGE
  3. 查单个用户排名用 ZREVRANK

6.4 场景四:高并发扣减辅助控制

思路:

  1. Redis 用于高并发预扣减和快速判定。
  2. 核心订单结果仍要落到数据库。
  3. Redis 常作为"削峰 + 快速过滤 + 状态协同"层,而不是唯一真相源。

6.5 企业里的高可用建议

规模 常见方案
本地开发 单机
中小型生产 主从 + 哨兵
大流量、多分片 Redis Cluster

7. 常见误区

误区 为什么危险 正确认知
Redis 缓存了,数据库就轻松了 忽略失效瞬间冲击 必须设计击穿、雪崩保护
分布式锁拿到了就绝对安全 忽略锁超时、GC、网络抖动 锁是降低并发冲突,不是万能事务
Redis 能存,就能当主数据库 忽略持久化与一致性边界 核心账务、复杂关系数据不要轻率替代
哨兵就是分片 概念混淆 哨兵做高可用切换,不做数据分片
集群就天然强一致 误判分布式特性 Redis 追求高可用和性能,不是强一致数据库

8. 面试题

  1. 说一下你们项目里的 Redis 缓存是怎么设计的。
  2. 缓存穿透、击穿、雪崩分别是什么,怎么处理?
  3. 为什么更新数据常用"先更新数据库,再删缓存"?
  4. Redis 分布式锁怎么实现?为什么解锁不能直接 DEL
  5. 哨兵和集群有什么区别?
  6. Redis 在秒杀系统里通常承担什么角色?
  7. Redis 能不能做消息队列?边界在哪里?

9. 自测题

  1. 设计一个商品详情缓存方案,并考虑穿透、击穿、雪崩。
  2. 设计一个短信验证码方案,并防止重复发送。
  3. 设计一个 1 分钟 10 次的登录限流方案。
  4. 设计一个排行榜方案,并给出核心命令。
  5. 说出单机、哨兵、集群分别适合什么场景。

10. 学完标志

学完这一阶段后,你应该能做到:

  1. 独立设计常见 Redis 业务方案。
  2. 说清缓存一致性与高并发问题处理方式。
  3. 正确实现基础分布式锁。
  4. 根据规模选择单机、哨兵或集群。
  5. 把 Redis 放到真实系统架构里思考,而不是把它当命令集合。

第六阶段:常见问题与排错

1. 学什么

这一阶段学习"线上 Redis 出问题时怎么办",重点包括:

  1. 大 Key、热 Key。
  2. 慢查询、阻塞命令。
  3. 内存飙升、OOM。
  4. 连接数过多、超时、网络抖动。
  5. 持久化失败、复制延迟。
  6. 缓存问题导致数据库被打爆时的排查路径。

2. 为什么重要

Redis 真正拉开工程水平差距的地方,不是在你会不会写 SET,而是在于:

出问题时你能不能迅速定位是 Key 问题、命令问题、网络问题、内存问题,还是架构问题。

这一阶段解决的是生产事故能力。

3. 核心概念

3.1 常见故障类型

问题 典型现象 常见根因
大 Key 延迟抖动、删除卡顿、网络包大 一个 Key 里塞了过多元素或大对象
热 Key 单 Key QPS 极高 热点流量集中
慢查询 RT 上升 大量遍历、阻塞命令、CPU 紧张
OOM 写入失败 内存打满、淘汰策略不合适
复制延迟 从库数据落后 主从网络抖动、主库压力大
持久化异常 重启后数据恢复异常 AOF/RDB 失败、磁盘问题

3.2 常用排查命令

命令 用途
INFO memory 看内存使用情况
INFO stats 看总体统计
INFO replication 看主从复制状态
SLOWLOG GET 10 看慢命令
LATENCY DOCTOR 看延迟诊断
MEMORY USAGE key 看某个 Key 占用内存
SCAN 安全分批扫描 Key
OBJECT ENCODING key 看内部编码
CLIENT LIST 看客户端连接
MONITOR 实时观察命令,慎用于生产

3.3 排错方法论

建议你固定按这 6 步走:

  1. 先确认现象:慢、错、丢、满、连不上。
  2. 再确认范围:单实例、单业务、单 Key,还是全局。
  3. 看核心指标:CPU、内存、QPS、连接数、复制延迟。
  4. 查关键命令:慢日志、热点命令、大 Key。
  5. 先止血,再追根因。
  6. 复盘并修规则。

4. 原理解释

4.1 为什么大 Key 危险

大 Key 的问题不只是"占空间大",而是会带来链式问题:

  1. 读取时网络包大。
  2. 删除或遍历时阻塞主线程。
  3. 复制和持久化成本更高。
  4. 一旦成为热 Key,问题会被放大。

4.2 为什么热 Key 危险

Redis 很快,但单 Key 热点无限集中也会出问题:

  1. 单个 Key 成为瓶颈。
  2. 某个实例负载异常倾斜。
  3. 热点失效时会造成击穿。

常见缓解方式:

  1. 本地缓存。
  2. 二级缓存。
  3. 热 Key 永不过期 + 异步刷新。
  4. 热点拆分。

4.3 为什么 KEYS * 危险而 SCAN 更安全

KEYS * 会一次性遍历所有 Key,可能长时间阻塞 Redis。

SCAN 则采用游标式渐进遍历:

  1. 一次返回一部分。
  2. 可以分批处理。
  3. 对线上更友好。

4.4 为什么慢日志重要

Redis 的问题很多时候不是"Redis 不行",而是某几个命令不合理。

慢日志能帮助你回答:

  1. 哪条命令慢。
  2. 参数大概是什么。
  3. 最近是否重复出现。

5. 示例

5.1 最小可运行示例:排查大 Key

bash 复制代码
redis-cli --bigkeys

或者针对某个 Key:

redis 复制代码
MEMORY USAGE user:1001:profile
OBJECT ENCODING user:1001:profile

5.2 最小可运行示例:排查慢命令

redis 复制代码
SLOWLOG GET 10
LATENCY DOCTOR
INFO commandstats

5.3 最小可运行示例:排查复制

redis 复制代码
INFO replication

5.4 一个常见故障定位示例

现象:商品详情接口 RT 飙升。

排查路径:

  1. 看应用日志,确认是否 Redis RT 高。
  2. SLOWLOG GET
  3. 查是否有热点 Key 失效。
  4. 查数据库是否因缓存失效被打爆。
  5. INFO memoryINFO stats

6. 工程实践

6.1 真实工程场景:缓存击穿导致数据库暴涨

处理步骤:

  1. 先对热点 Key 加互斥重建。
  2. 临时延长热点 TTL。
  3. 对数据库限流。
  4. 增加本地缓存或热点保护。
  5. 复盘为什么热点 Key 会同时失效。

6.2 真实工程场景:大 Hash 导致延迟波动

处理思路:

  1. 定位大 Key。
  2. 判断是否可拆分。
  3. 避免一次性 HGETALL 拉全量。
  4. 对删除操作使用更温和的方式,避免高峰期粗暴处理。

6.3 真实工程场景:从库延迟严重

排查思路:

  1. 看主从网络。
  2. 看主库是否有大写入或 fork 压力。
  3. 看是否存在大 Key 同步。
  4. 看从库机器资源是否不足。

7. 常见误区

误区 为什么错 正确认知
Redis 慢了就一定是 Redis 本身问题 忽略业务命令设计 很多慢是大 Key、热 Key、错误命令导致
线上直接 KEYS * 最快 可能把实例打停顿 SCAN 渐进扫描
MONITOR 可以常开 命令很多时开销很大 只在短时间诊断时慎用
大对象问题只是内存多一点 忽略删除、复制、网络、阻塞成本 大 Key 是综合性风险
从库延迟只和网络有关 根因更复杂 还可能是主库压力、fork、大同步

8. 面试题

  1. 什么是大 Key?有什么危害?怎么排查?
  2. 什么是热 Key?怎么处理?
  3. 为什么不建议在线上用 KEYS *
  4. Redis 慢时你一般怎么排查?
  5. 如果 Redis 内存满了会发生什么?
  6. 从库延迟严重你会怎么分析?
  7. 为什么缓存击穿会把数据库打爆?

9. 自测题

  1. 请设计一个 Redis 故障排查 checklist。
  2. 大 Key 和热 Key 的危害分别是什么?
  3. SLOWLOG GETLATENCY DOCTORINFO memory 分别解决什么问题?
  4. 如果线上请求变慢,你会先看哪 3 个维度?
  5. 为什么删除大 Key 也可能成为问题?

10. 学完标志

学完这一阶段后,你应该能做到:

  1. 遇到 Redis 线上问题时有清晰排查路径。
  2. 会用最常见的诊断命令。
  3. 理解大 Key、热 Key、慢日志、复制延迟这些高频问题。
  4. 能把"现象"快速映射到"机制"。
  5. 初步具备生产级 Redis 排障思维。

第七阶段:面试与评估

1. 学什么

这一阶段不是新增知识点,而是训练你把前面内容变成:

  1. 能解释。
  2. 能比较。
  3. 能设计。
  4. 能排错。
  5. 能在面试里稳定输出。

2. 为什么重要

很多人会 Redis,但一到面试就容易暴露三个问题:

  1. 只会背名词,不会讲因果。
  2. 只会讲命令,不会讲场景。
  3. 只会讲方案,不会讲权衡。

面试官想看的不是你会不会敲命令,而是你是否具备:

  1. 基础认知是否扎实。
  2. 原理理解是否成体系。
  3. 工程判断是否成熟。

3. 核心概念

3.1 Redis 面试的 5 类题型

题型 典型问题 考察点
定义题 Redis 是什么、为什么快 基础认知
对比题 Redis vs MySQL / Memcached 边界感
原理题 过期、淘汰、持久化、复制 机制理解
场景题 缓存设计、分布式锁、秒杀 工程能力
排错题 慢、满、丢、延迟 实战思维

3.2 回答框架

建议你固定用这个框架回答:

  1. 先下定义
    先说它是什么。
  2. 再讲原理
    它为什么这样工作。
  3. 再讲场景
    它解决什么问题。
  4. 最后讲权衡
    它的边界和代价是什么。

这比单纯堆术语稳定得多。

3.3 中级面试官最爱追问的点

  1. 为什么 Redis 快。
  2. 为什么缓存一致性难做到绝对完美。
  3. 分布式锁为什么不能直接删 Key。
  4. 事务为什么不像 MySQL 那样回滚。
  5. RDB 和 AOF 如何取舍。
  6. 哨兵和集群到底差在哪。
  7. 你项目里 Redis 出过什么问题,怎么排查。

4. 原理解释

4.1 面试官为什么总问"为什么"

因为"为什么"能迅速区分:

  1. 背答案的人。
  2. 真理解机制的人。

例如"Redis 为什么快",如果你只答"内存 + 单线程",通常只能到初级水平。

更好的回答要覆盖:

  1. 内存。
  2. 事件循环。
  3. I/O 多路复用。
  4. 数据结构贴业务。
  5. 单线程无锁化带来的简化收益。

4.2 场景题为什么总是开放题

因为真实工程没有标准答案。

面试官看的是:

  1. 你是否先识别问题本质。
  2. 你是否知道几个可选方案。
  3. 你是否能说明 trade-off。

例如缓存一致性,没有完美方案,关键是:

  1. 你是否知道为什么会不一致。
  2. 你是否知道常见工程折中。

4.3 如何把项目经验讲得有层次

建议顺序:

  1. 业务背景是什么。
  2. 为什么要用 Redis。
  3. 用了哪些类型和机制。
  4. 遇到过什么问题。
  5. 最后结果和优化效果。

5. 示例

5.1 一个合格的面试回答示例

问题:Redis 为什么快?

回答示例:

Redis 快主要有四个原因。第一,它的数据主要在内存里,避免了磁盘随机 I/O。第二,它的命令执行路径比较短,很多操作直接基于高效数据结构完成。第三,Redis 通过事件循环和 I/O 多路复用高效处理大量连接。第四,它核心命令执行长期采用单线程模型,减少了锁竞争和线程切换成本。当然,单线程也有代价,比如大 Key 和阻塞命令会影响整体延迟。

5.2 一个中级面试回答示例

问题:缓存击穿怎么处理?

回答示例:

缓存击穿是指某个热点 Key 失效时,大量并发请求同时打到数据库。常见处理方案有三类:第一,对热点 Key 做互斥重建,只允许一个线程回源;第二,对极热点数据采用逻辑过期或后台异步刷新,避免真正失效;第三,配合本地缓存、限流和降级保护后端。选择哪种方案要看热点稳定性、数据实时性要求和实现复杂度。

5.3 一个"项目表达"模板

text 复制代码
我们在商品详情场景使用 Redis 做缓存旁路。读取先查 Redis,未命中再查 MySQL 并回填。为防止穿透,我们对空结果做短 TTL 缓存;为防止雪崩,我们对 TTL 做随机打散;为防止热点击穿,我们对热点商品加互斥重建。更新时采用先更新数据库再删除缓存的策略。线上曾遇到过热点 Key 失效导致数据库 QPS 暴涨,后续通过热点保护和本地缓存做了优化。

6. 工程实践

6.1 面试前怎么复习最有效

  1. 先把 20 个高频问题写出自己的答案。
  2. 每个问题都补"为什么"和"代价"。
  3. 每个工程题都补一段真实场景说明。
  4. 用 3 分钟、1 分钟、30 秒三种长度各讲一遍。

6.2 模拟面试顺序

  1. 先答定义题。
  2. 再答原理题。
  3. 再答场景题。
  4. 最后答排错题。

6.3 企业评估官最看重什么

  1. 你是否会把 Redis 放在系统里讲,而不是孤立讲。
  2. 你是否知道边界和风险。
  3. 你是否有过排错思路。
  4. 你是否会做取舍,而不是只给"标准答案"。

7. 常见误区

误区 为什么不好 正确做法
面试只背八股 一追问就露馅 用"定义-原理-场景-权衡"结构输出
一上来就讲冷门特性 偏离重点 先把高频核心讲扎实
项目经验只说"我们用了 Redis" 信息量太低 讲业务目标、方案、问题、结果
把所有问题都回答成"用 Redis 集群" 缺少边界感 先识别问题,再谈方案

8. 面试题

  1. Redis 为什么快?
  2. Redis 和 MySQL 的分工是什么?
  3. 五大数据类型怎么选?
  4. 过期删除和内存淘汰的区别是什么?
  5. 缓存穿透、击穿、雪崩分别怎么处理?
  6. 为什么更新数据库后通常删除缓存而不是直接更新缓存?
  7. RDB 和 AOF 如何选?
  8. Redis 分布式锁要注意什么?
  9. 哨兵和集群的区别是什么?
  10. 如果 Redis 线上变慢,你会怎么排查?

9. 自测题

  1. 请你用 1 分钟解释 Redis 是什么。
  2. 请你用 3 分钟解释 Redis 为什么快。
  3. 请你自己模拟回答"缓存一致性怎么做"。
  4. 请你讲一个 Redis 项目案例,包含问题、方案、风险、结果。
  5. 请你回答"你们为什么不用 MySQL 直接扛这个场景?"。

10. 学完标志

学完这一阶段后,你应该能做到:

  1. 比较稳定地回答 Redis 常见面试题。
  2. 不只会讲定义,还能讲机制、场景、权衡。
  3. 用项目表达方式讲清 Redis 价值。
  4. 初步具备基础到中级面试应答能力。
  5. 知道自己哪些部分还薄弱,需要回补。

第八阶段:学习总结与知识闭环

1. 学什么

这一阶段要做的是把前面所有内容连成一张网,而不是散成很多点。

你要完成:

  1. Redis 知识主干复盘。
  2. 学习顺序复盘。
  3. 工程方法论沉淀。
  4. 下一步深入方向规划。

2. 为什么重要

很多人学完一堆知识点却仍不会用,本质原因是没有形成闭环。

真正的闭环应该是:

能理解 -> 能解释 -> 能上手 -> 能排错 -> 能设计 -> 能面试输出

如果缺一环,知识就会很快散掉。

3. 核心概念

3.1 Redis 知识主干

Redis 定位
数据类型与命令模型
过期 / 淘汰 / 事务 / Pipeline
事件循环 / 协议 / 内部结构 / 持久化
缓存 / 锁 / 限流 / 排行榜 / 会话
高可用 / 集群 / 复制
排错 / 面试 / 项目复盘

3.2 学习本质

Redis 的学习本质不是背命令,而是掌握 4 种能力:

  1. 建模能力
    业务需求如何映射到数据结构。
  2. 机制理解能力
    过期、淘汰、持久化、复制为什么这样设计。
  3. 工程判断能力
    什么时候适合 Redis,什么时候不适合。
  4. 排错表达能力
    出问题时会查,会讲,会取舍。

3.3 必须吃透 vs 先知道

层级 必须吃透 先知道,后深入
基础 定位、五大类型、TTL、缓存场景 冷门数据类型
机制 过期、淘汰、事务、Pipeline、持久化 更深源码细节
工程 缓存一致性、击穿雪崩、锁、限流、高可用 极复杂分布式一致性问题
深入 请求生命周期、复制、集群槽位 内核级源码优化

4. 原理解释

4.1 为什么正确学习顺序必须是"先场景后原理"

因为 Redis 不是纯理论技术,它是极强工程属性的中间件。

如果顺序反了:

  1. 你会陷入术语海洋。
  2. 会把注意力放到源码细枝末节。
  3. 反而不知道真实项目怎么用。

4.2 为什么学习闭环一定要包含排错

因为很多技术只学"正常路径",但工程上真正值钱的是:

  1. 非正常路径怎么处理。
  2. 怎么快速止血。
  3. 怎么复盘避免重演。

4.3 为什么面试表现本质上是知识结构的映射

当你的知识是连贯的,你回答自然会有层次:

  1. 定位。
  2. 原理。
  3. 场景。
  4. 风险。
  5. 权衡。

这也是为什么"会做题"不等于"会面试",而"真正理解"通常能兼顾两者。

5. 示例

5.1 一个完整知识闭环示例

问题:设计商品详情缓存

你应该能这样串起来:

  1. String 缓存商品 JSON,Key 如 product:{id}:detail
  2. 使用 Cache Aside。
  3. 设置随机 TTL 防雪崩。
  4. 缓存空值防穿透。
  5. 热点商品互斥重建防击穿。
  6. 更新时先更新数据库再删缓存。
  7. 若出现 Redis RT 波动,优先检查热 Key、大 Key、慢日志。
  8. 若业务扩张,再考虑主从、哨兵或集群。

5.2 一个复盘模板

text 复制代码
场景是什么?
为什么选择 Redis?
用了哪种数据结构?
用了哪些机制?
有哪些风险?
如何排查?
如何扩展?

6. 工程实践

6.1 建议你的学习循环

每学一个主题,都按这个顺序做:

  1. 用一句话解释它是什么。
  2. 用一个场景解释它解决什么问题。
  3. 用一个最小命令或代码示例验证。
  4. 用"为什么这样设计"解释原理。
  5. 写出 2 个误区。
  6. 回答 2 个面试题。

6.2 一周强化方法

  1. 第 1 天:复盘五大类型和命令。
  2. 第 2 天:复盘过期、淘汰、事务、Pipeline。
  3. 第 3 天:复盘持久化、复制、高可用。
  4. 第 4 天:做缓存与锁方案题。
  5. 第 5 天:做排错题。
  6. 第 6 天:做面试模拟。
  7. 第 7 天:总结错误点并补课。

6.3 下一步深入建议

  1. 更深入的 Redis Cluster。
  2. Stream、Bitmap、HyperLogLog、GEO。
  3. Lua 和 Redis Functions。
  4. 源码阅读:事件循环、对象系统、持久化、复制。
  5. 客户端连接池与应用侧容灾。

7. 常见误区

误区 表现 应对方式
学完就结束 很快遗忘 必须做复述和实操闭环
只刷面试题 实战能力弱 题目要和项目场景绑定
只看项目不看原理 一追问就断层 项目和原理必须双线并进
只学单机 Redis 上线后认知不足 至少要掌握哨兵和集群边界

8. 面试题

  1. 如果让你从零系统学习 Redis,你会怎么安排顺序?
  2. Redis 这门技术你觉得最核心的设计哲学是什么?
  3. 你觉得 Redis 学习里最容易学偏的地方是什么?
  4. 如果继续深入 Redis,你下一步会学什么,为什么?

9. 自测题

  1. 请你画出 Redis 的知识树。
  2. 请你写出你目前最薄弱的 3 个点。
  3. 请你选一个业务场景,从建模、机制、排错、扩展四个角度讲一遍。
  4. 请你用自己的话总结 Redis 的设计哲学。

10. 学完标志

学完这一阶段后,你应该能做到:

  1. 把 Redis 主干知识串成体系。
  2. 知道自己已经掌握了什么、还缺什么。
  3. 能用工程视角而不是命令视角看 Redis。
  4. 能继续独立深入 Redis 的高级主题。

学习评估体系

1. 入门达标标准

满足下面条件,说明你已经入门:

  1. 能准确解释 Redis 是什么、解决什么问题。
  2. 能区分 Redis 和 MySQL 的职责边界。
  3. 能完成 SET/GET/EXPIRE/TTL/DEL 基础操作。
  4. 能说出至少 3 个 Redis 适合的场景。

2. 初级达标标准

满足下面条件,说明你达到初级工程师可用水平:

  1. 能熟练使用五大核心数据类型。
  2. 能设计基础缓存方案。
  3. 能解释过期机制和淘汰策略。
  4. 能解释 RDB 和 AOF 的基本区别。
  5. 能回答常见基础面试题。

3. 中级达标标准

满足下面条件,说明你达到中级理解深度:

  1. 能设计缓存一致性、击穿、雪崩保护方案。
  2. 能实现基础分布式锁并说明风险。
  3. 能解释事件循环、I/O 多路复用、复制、高可用边界。
  4. 能根据单机、哨兵、集群做方案选型。
  5. 能给出 Redis 故障排查路径并说明依据。

4. 一套自测题

基础题

  1. Redis 为什么快?
  2. Redis 和 MySQL 的区别是什么?
  3. 五大数据类型分别适合什么场景?

机制题

  1. 过期删除和内存淘汰有什么区别?
  2. Redis 事务为什么不像 MySQL 那样回滚?
  3. RDB 和 AOF 如何取舍?

场景题

  1. 设计一个商品详情缓存。
  2. 设计一个短信验证码方案。
  3. 设计一个排行榜方案。

排错题

  1. Redis 慢了怎么查?
  2. 什么是大 Key、热 Key?
  3. 从库延迟严重怎么办?

5. 一套面试题

  1. Redis 是单线程吗?
  2. 为什么 Redis 不适合做复杂查询?
  3. 为什么 Hash 适合存对象?
  4. 缓存穿透、击穿、雪崩分别如何处理?
  5. 为什么更新数据库后通常删除缓存?
  6. Redis 分布式锁怎么实现?风险点有哪些?
  7. 哨兵和集群的区别是什么?
  8. Redis Cluster 为什么设计槽位?
  9. 线上 Redis 延迟抖动你怎么排查?
  10. 你项目里 Redis 的典型使用方式是什么?

6. 一套实战任务

任务 1:本地 Redis 环境

  1. 启动本地 Redis。
  2. 完成五大类型基础命令实验。
  3. 验证 TTL、事务、Pipeline。

任务 2:缓存实验

  1. 写一个"先查缓存,未命中查数据库模拟层"的示例。
  2. 加入空值缓存。
  3. 给 TTL 加随机值。

任务 3:锁与限流实验

  1. SET NX PX 实现基础锁。
  2. 用 Lua 安全释放锁。
  3. INCR + EXPIRE 实现一分钟限流。

7. 一套项目任务

项目题:做一个"社区内容服务"的 Redis 设计

要求至少覆盖:

  1. 用户资料:Hash
  2. 文章详情缓存:String
  3. 点赞关系:Set
  4. 热门排行榜:ZSet
  5. 登录会话:带 TTL 的 String/Hash
  6. 接口限流:INCR + EXPIRE
  7. 高可用方案:说明为何选单机、哨兵或集群
  8. 排错预案:说明如何监控和排查热点、慢日志、大 Key

项目验收标准

  1. 你能讲清 Key 设计。
  2. 你能讲清类型选型理由。
  3. 你能讲清一致性和高并发保护。
  4. 你能讲清排错与扩展。

8. 对你回答的评分标准

分数段 水平 说明
90-100 中级偏上 定义准确,原理清楚,场景完整,能讲 trade-off 和排错
75-89 中级入门 主要知识点完整,工程表达较好,个别深度不足
60-74 初级可用 会基础概念和常见场景,但原理和排错偏弱
40-59 入门未稳 只会零散命令,体系不完整
0-39 需要重学主干 定位、类型、机制都不清楚

细项打分维度

维度 占比 评估点
基础定义 15% 能否说清 Redis 定位与边界
类型选型 20% 能否做对数据结构建模
机制理解 20% 过期、淘汰、持久化、复制是否清楚
工程实践 20% 缓存、锁、限流、高可用方案是否合理
排错能力 15% 是否有诊断路径
面试表达 10% 是否条理清晰,有因果和权衡

9. 如何根据错误结果反向补课

如果你总在"定义题"失分

回补内容:

  1. Redis 定位。
  2. Redis 与 MySQL / Memcached 对比。
  3. Redis 为什么快。

如果你总在"选型题"失分

回补内容:

  1. 五大类型对比表。
  2. 常见业务场景映射。
  3. Key 设计规范。

如果你总在"机制题"失分

回补内容:

  1. 过期删除。
  2. 淘汰策略。
  3. 事务与 Pipeline。
  4. RDB / AOF / 复制主线。

如果你总在"工程题"失分

回补内容:

  1. Cache Aside。
  2. 缓存一致性。
  3. 穿透、击穿、雪崩。
  4. 分布式锁。
  5. 哨兵与集群。

如果你总在"排错题"失分

回补内容:

  1. 大 Key、热 Key。
  2. SLOWLOGINFOLATENCY DOCTOR
  3. 复制延迟与内存排查。

反向补课建议流程

  1. 先记录你答错的问题类型。
  2. 对应回到本文件相应阶段。
  3. 用"定义-原理-场景-排错"重新写一版答案。
  4. 自己口述录音复盘。
  5. 再做一次同类型题,直到能稳定输出。

最后总结

如果只用一句话概括 Redis:

Redis 是一个以内存为核心、以数据结构为能力、以高性能读写和状态协同为价值的系统。

如果只记住学习主线:

定位 -> 数据结构 -> 核心机制 -> 底层原理 -> 工程实践 -> 排错 -> 面试表达

如果只记住工程主线:

业务需求 -> 数据建模 -> Key 设计 -> TTL/持久化/高可用策略 -> 压测与排错 -> 复盘优化

到这里,这份 redis.md 已经形成完整闭环。后续如果你愿意,可以继续在这个文件基础上追加:

  1. Redis 实操实验记录。
  2. 你自己的面试答案。
  3. 你项目里的 Redis 方案复盘。
相关推荐
刘~浪地球3 小时前
Redis 从入门到精通(十一):持久化配置
数据库·redis·缓存
一个有温度的技术博主5 小时前
Redis主从同步进阶:深入理解增量同步与性能优化
数据库·redis·性能优化
惺忪97986 小时前
Redis安装与启动
数据库·redis·缓存
雄哥0078 小时前
linux redis升级⼿册-源码部署版
linux·运维·redis
列星随旋8 小时前
基于 Redis + Lua,实现“多维度原子限流”(令牌桶 + 滑动窗口)
java·redis·lua
0xDevNull8 小时前
Redis Lua 脚本详细教程
redis·缓存·lua
0xDevNull10 小时前
Spring Boot 中使用 Redis Lua 脚本详细教程
spring boot·redis·lua
不爱吃大饼10 小时前
Redis核心点
redis
William Dawson10 小时前
【实战分享】DTU设备高并发数据接入全流程(Redis + RabbitMQ + 数据库)
数据库·redis·rabbitmq