【Redis八股|第1篇】Redis 是什么?为什么它这么快?
前言
从这一篇开始,我们进入 Redis 八股与实战系列。
Redis 是 Java 后端面试中非常高频的知识点。只要简历里写了 Redis,面试官就很可能会问:
- Redis 是什么?
- Redis 一般用来做什么?
- Redis 为什么这么快?
- Redis 是单线程还是多线程?
- Redis 和 MySQL 有什么区别?
- Redis 为什么适合做缓存?
- Redis 常见应用场景有哪些?
很多同学刚开始学 Redis 时,只知道它是缓存,能让查询变快。但如果面试官继续追问“为什么快”,就容易说不清楚。
这一篇我们先不急着讲复杂命令,而是先把 Redis 的定位、特点、常见使用场景,以及它为什么快讲清楚。
一、Redis 是什么?
Redis 全称是:
Remote Dictionary Server它是一个基于内存的高性能键值型数据库。
可以简单理解为:
Redis 是一个速度非常快的内存数据库,常用来做缓存、计数器、排行榜、分布式锁、验证码、登录状态等功能。
Redis 中的数据通常是以key-value的形式存储的。
比如:
username:1 -> zhangsan user:token:abc -> 用户登录信息 product:1001 -> 商品详情其中:
key 表示数据的唯一标识 value 表示真正保存的数据和 MySQL 不一样,Redis 不是通过表、字段、行来组织数据,而是通过 key 来直接访问 value。
二、Redis 和 MySQL 有什么区别?
MySQL 是关系型数据库,Redis 是键值型内存数据库。
可以先看一张表:
| 对比点 | MySQL | Redis |
|---|---|---|
| 数据模型 | 表、字段、记录 | key-value |
| 存储位置 | 主要存磁盘 | 主要存内存 |
| 查询方式 | SQL 查询 | 根据 key 查询 |
| 速度 | 相对较慢 | 非常快 |
| 适合场景 | 持久化业务数据 | 缓存、高并发、临时数据 |
| 是否支持复杂查询 | 支持 | 不擅长 |
| 数据可靠性 | 更适合长期保存 | 通常作为辅助存储 |
比如员工信息、订单信息、支付记录这类核心业务数据,一般会存到 MySQL 中。
而商品详情缓存、验证码、登录 token、热点数据、接口限流计数等,更适合放到 Redis 中。
简单理解:
MySQL:负责保存核心数据 Redis:负责提高访问速度、减轻数据库压力三、Redis 常见使用场景
Redis 在 Java 后端项目中非常常见,下面列几个最典型的场景。
1. 缓存热点数据
比如商品详情页访问量很高,如果每次都查 MySQL,数据库压力会很大。
可以把商品详情放到 Redis 中:
product:1001 -> 商品详情JSON查询时先查 Redis,如果 Redis 有数据,就直接返回。
如果 Redis 没有数据,再查 MySQL,并把查到的数据写入 Redis。
流程如下:
请求商品详情 ↓ 先查 Redis ↓ Redis 有数据:直接返回 ↓ Redis 没数据:查 MySQL ↓ 写入 Redis ↓ 返回结果这样可以减少 MySQL 查询压力。
2. 保存验证码
比如短信验证码、邮箱验证码,一般都有过期时间。
login:code:13800000000 -> 9527可以设置 5 分钟过期:
setex login:code:138000000003009527Redis 天然支持过期时间,非常适合保存这类临时数据。
3. 保存登录 token
用户登录成功后,后端可以生成 token,并把用户信息保存到 Redis。
login:token:abc123 -> 用户信息同时设置过期时间,比如 30 分钟。
后续请求携带 token,后端根据 token 去 Redis 查询用户信息。
4. 计数器
Redis 的自增命令非常适合做计数器。
比如文章阅读量:
incr article:1001:readCount每访问一次,就自增 1。
还可以用于:
- 点赞数
- 收藏数
- 接口访问次数
- 短信发送次数
- 限流计数
5. 排行榜
Redis 的ZSet有分数排序能力,非常适合做排行榜。
比如积分排行榜:
user:rank 张三 -> 100 李四 -> 200 王五 -> 150可以按照分数从高到低查询排名。
6. 分布式锁
在分布式系统中,多个服务实例可能同时操作同一份资源。
这时可以使用 Redis 实现分布式锁。
比如:
setlock:order:1001 value nx ex30表示只有 key 不存在时才设置成功,并且 30 秒后自动过期。
实际项目中更推荐使用 Redisson 来实现分布式锁。
四、Redis 为什么这么快?
这是面试中最常问的问题之一。
Redis 快主要有几个原因:
- 基于内存操作
- 数据结构设计高效
- 单线程模型避免线程切换开销
- I/O 多路复用
- 命令执行简单高效
- 使用非阻塞网络模型
下面逐个来看。
五、原因一:基于内存操作
Redis 主要把数据存储在内存中。
内存访问速度远高于磁盘。
MySQL 很多数据最终要和磁盘打交道,而 Redis 大部分操作直接在内存中完成。
比如根据 key 查询 value:
get user:1Redis 可以直接从内存数据结构中找到对应值。
这就是 Redis 快的最核心原因。
可以简单理解:
MySQL:更多依赖磁盘和复杂查询 Redis:主要在内存中通过 key 直接访问六、原因二:数据结构高效
Redis 不只是简单的 key-value,它支持多种高效数据结构:
- String
- Hash
- List
- Set
- ZSet
这些数据结构都针对不同场景做了优化。
比如:
get user:1可以快速获取字符串。
hget user:1 name可以快速获取对象中的某个字段。
zrevrange rank09withscores可以快速获取排行榜前 10 名。
Redis 内部对这些结构做了很多优化,所以执行效率很高。
七、原因三:单线程避免线程切换
很多人会疑惑:
Redis 是单线程,为什么还这么快?
这里要先说明一点:
Redis 的核心命令执行模型长期以来主要是单线程处理的,但这并不代表 Redis 整个程序只有一个线程。后续版本中,Redis 在网络 I/O、持久化等方面也有多线程能力。
面试时常说的“Redis 单线程”,主要是指:
Redis 的命令执行主要由单线程完成。
单线程有什么好处?
- 不需要频繁进行线程上下文切换
- 不需要复杂加锁
- 不会因为多线程竞争导致性能损耗
- 数据操作逻辑更简单
Redis 的操作通常非常快,瓶颈不在 CPU 计算,而更多在网络 I/O 和内存访问。
所以单线程模型反而减少了很多复杂度。
八、原因四:I/O 多路复用
Redis 虽然命令执行主要是单线程,但它可以同时处理大量客户端连接。
这是因为 Redis 使用了 I/O 多路复用机制。
可以简单理解为:
一个线程可以监听多个客户端连接,哪个连接有请求,就处理哪个连接。
如果没有 I/O 多路复用,一个线程可能只能阻塞等待一个客户端。
这样效率会很低。
有了 I/O 多路复用,Redis 可以同时管理大量连接,而不需要为每个连接都创建一个线程。
这也是 Redis 高并发能力的重要原因。
九、原因五:命令执行简单
Redis 的很多命令都比较简单直接。
比如:
setname zhangsan get name incr count expire token300这些操作通常不涉及复杂 SQL 解析、查询优化、磁盘随机读写、多表关联等流程。
而 MySQL 查询可能涉及:
SQL 解析 优化器选择执行计划 索引判断 磁盘 IO 事务控制 锁机制 结果集返回所以 Redis 在简单 key-value 访问场景下会非常快。
十、Redis 是不是可以替代 MySQL?
不能。
这是一个非常重要的点。
Redis 很快,但它不能完全替代 MySQL。
原因是:
- Redis 主要基于内存,成本更高
- Redis 不适合复杂关系查询
- Redis 不适合保存所有核心业务数据
- Redis 持久化能力通常不作为唯一可靠存储
- MySQL 更适合事务、关联查询、长期数据存储
比如订单表、支付记录、用户资产这些数据,必须以 MySQL 这类关系型数据库作为核心存储。
Redis 更适合做辅助:
MySQL 保存真实数据 Redis 提供高速缓存十一、Redis 和缓存的关系
Redis 最常见的用途就是缓存。
缓存的核心思想是:
把访问频率高、变化不频繁的数据放到更快的存储中,减少后端数据库压力。
比如商品详情:
第一次访问:
Redis 没有 ↓ 查 MySQL ↓ 写入 Redis ↓ 返回数据第二次访问:
Redis 有数据 ↓ 直接返回这样第二次就不需要访问 MySQL。
但是缓存也会带来新问题,比如:
- 缓存和数据库一致性
- 缓存穿透
- 缓存击穿
- 缓存雪崩
- 缓存过期策略
这些都是后面 Redis 系列要重点讲的内容。
十二、Spring Boot 中 Redis 常见使用方式
在 Java 项目中,常见方式是通过RedisTemplate操作 Redis。
示例:
@AutowiredprivateStringRedisTemplatestringRedisTemplate;publicvoidsaveCode(Stringphone,Stringcode){Stringkey="login:code:"+phone;stringRedisTemplate.opsForValue().set(key,code,5,TimeUnit.MINUTES);}查询验证码:
publicStringgetCode(Stringphone){Stringkey="login:code:"+phone;returnstringRedisTemplate.opsForValue().get(key);}这里:
opsForValue()表示操作 Redis 的 String 类型。
后面项目实战文章中可以专门写 Spring Boot 整合 Redis。
十三、面试标准回答
如果面试官问:
Redis 是什么?为什么这么快?
可以这样回答:
Redis 是一个基于内存的高性能 key-value 数据库,常用于缓存、验证码、登录 token、计数器、排行榜、分布式锁等场景。
Redis 快的主要原因有几个。第一,它的数据主要存储在内存中,内存访问速度远高于磁盘。第二,Redis 提供了高效的数据结构,比如 String、Hash、List、Set、ZSet。第三,Redis 核心命令执行主要是单线程,避免了多线程上下文切换和锁竞争。第四,Redis 使用 I/O 多路复用,可以用少量线程处理大量客户端连接。第五,Redis 命令执行通常比较简单,不像关系型数据库那样涉及复杂 SQL 解析、多表关联和执行计划。
不过 Redis 不能完全替代 MySQL。MySQL 更适合保存核心业务数据,Redis 更适合做缓存和高性能辅助存储。
十四、常见问题总结
1. Redis 是数据库还是缓存?
Redis 本质上是一个内存型 key-value 数据库。
但在项目中,它最常见的使用方式是缓存。
2. Redis 为什么比 MySQL 快?
主要因为 Redis 基于内存操作,数据结构简单高效,命令执行模型轻量,并且使用 I/O 多路复用。
3. Redis 是单线程吗?
面试中说的单线程,主要指 Redis 核心命令执行主要由单线程处理。
但 Redis 整个系统并不是绝对只有一个线程,比如持久化、网络 I/O 等方面也可能有其他线程参与。
4. Redis 能不能替代 MySQL?
不能。
Redis 适合缓存和临时高性能数据,MySQL 更适合核心业务数据持久化、事务和复杂查询。
5. Redis 适合保存什么数据?
适合保存:
- 热点数据
- 临时数据
- 验证码
- token
- 计数器
- 排行榜
- 分布式锁 key
不适合把所有核心业务数据都只放在 Redis 中。
十五、实际开发建议
在项目中使用 Redis 时,建议注意下面几点:
- 不要把 Redis 当成万能数据库
- 核心业务数据仍然要落 MySQL
- Redis 更适合做缓存和高性能辅助存储
- 缓存数据要设置合理过期时间
- key 命名要有业务前缀
- 不要把超大对象随便放入 Redis
- 使用 Redis 时要考虑缓存一致性问题
- 高并发场景要关注缓存穿透、击穿、雪崩
十六、总结
这一篇主要学习了 Redis 是什么,以及 Redis 为什么这么快。
Redis 是一个基于内存的高性能 key-value 数据库,常用于缓存、验证码、登录 token、计数器、排行榜、分布式锁等场景。
Redis 快的原因主要包括:基于内存操作、高效数据结构、单线程命令执行模型、I/O 多路复用、命令简单高效。
不过 Redis 不能完全替代 MySQL。真实项目中更常见的架构是:MySQL 作为核心数据存储,Redis 作为缓存和高性能辅助组件。
下一篇我们继续学习 Redis 中最基础也最重要的内容:五大基本数据类型。
