Redis
Redis 是什么?一文看懂 Redis 的原理、数据结构与应用场景
Redis 是一个开源的内存数据存储系统,常被用作缓存、数据库、消息队列和实时数据处理组件。Redis 将数据主要存储在内存中,因此具有非常高的读写性能,被广泛应用于 Web、互联网服务、分布式系统和高并发场景。
一句话理解
Redis = 一个速度非常快的内存数据存储系统。
如果把传统数据库理解成“仓库”,那么 Redis 更像是放在程序旁边的“高速货架”。
程序经常需要访问的数据,可以先放到 Redis 中:
用户请求
↓
先查询 Redis
↓
有数据 → 直接返回
↓
没有数据
↓
查询 MySQL
↓
将结果写入 Redis
↓
返回结果
这样可以减少数据库访问次数,提高系统响应速度。
基础信息
项目 | 内容 |
|---|---|
名称 | Redis |
全称 | Remote Dictionary Server |
类型 | 内存数据存储系统 |
数据存储 | 以内存为主 |
数据结构 | String、List、Set、Hash、Sorted Set 等 |
常见用途 | 缓存、Session、排行榜、计数器、分布式锁、消息队列等 |
主要特点 | 高性能、低延迟、丰富的数据结构 |
常见搭配 | MySQL、PostgreSQL、Java、Spring Boot 等 |
开源协议 | 不同版本和发行版可能有所不同,使用前应查看对应版本许可 |
什么是 Redis?
Redis 是一种 键值型(Key-Value)数据存储系统。
最简单的 Redis 数据可以理解为:
Key → Value
例如:
user:10001 → 张三
程序可以通过 Key 快速找到对应的数据。
与传统关系型数据库不同,Redis 的数据主要存储在内存中,并且提供了丰富的数据结构和操作命令。
例如:
String
Hash
List
Set
Sorted Set
因此 Redis 不只是一个简单的“缓存”。
它还可以用于:
- 计数
- 排行榜
- Session 管理
- 分布式锁
- 消息传递
- 实时数据处理
Redis 为什么这么快?
Redis 性能高,主要与它的数据访问方式、内存存储以及高效的数据结构等因素有关。
1. 数据主要存储在内存中
内存的访问速度通常远高于磁盘。
传统数据库在某些场景下需要进行磁盘 I/O,而 Redis 主要在内存中完成数据访问,因此能够提供非常低的访问延迟。
2. 数据结构设计高效
Redis 针对不同场景提供了多种数据结构。
例如:
String → 简单键值
Hash → 对象数据
List → 列表 / 队列
Set → 去重集合
Sorted Set → 排行榜
开发人员可以根据业务场景选择合适的数据结构。
3. 网络模型和执行机制高效
Redis 的命令处理模型经过专门设计,能够高效处理大量客户端请求。
不过需要注意:
Redis 快并不意味着所有操作都是“瞬间完成”。
如果执行了非常复杂、非常耗时的操作,仍然可能影响 Redis 的整体性能。
Redis 的核心数据结构
Redis 最重要的特点之一,就是提供了丰富的数据结构。
1. String
String 是 Redis 最基础的数据类型。
例如:
user:name → 张三
也可以保存数字:
page:view → 1000
然后执行增加操作:
INCR page:view
结果:
1001
因此 String 非常适合:
- 缓存
- 计数器
- Token
- 配置数据
- 简单键值数据
2. Hash
Hash 可以理解为一个小型对象。
例如用户:
user:10001
里面包含:
name → 张三
age → 20
city → 北京
可以理解为:
user:10001
├── name → 张三
├── age → 20
└── city → 北京
Hash 非常适合保存结构化对象。
3. List
List 是一个有序列表。
例如:
message:list
A
B
C
D
可以从头部或者尾部添加、删除元素。
因此 List 可以用于:
- 消息队列
- 最新消息列表
- 任务列表
- 简单队列
4. Set
Set 是无序集合,并且元素不能重复。
例如:
article:1:tags
AI
Redis
Java
数据库
如果再次加入:
AI
不会产生重复数据。
因此 Set 适合:
- 标签
- 去重
- 共同好友
- 用户兴趣
- 集合运算
5. Sorted Set
Sorted Set,也称为 ZSet。
它与 Set 类似,同样不允许元素重复,但每个元素都会关联一个分数。
例如:
player:rank
张三 → 9800
李四 → 9500
王五 → 9200
Redis 可以根据分数进行排序。
因此非常适合:
- 游戏排行榜
- 积分排行榜
- 热度排行
- 销量排行
- 权重排序
Redis 的常见应用场景
Redis 最常见的用途就是缓存。
但实际上,它的应用范围远不止缓存。
1. 数据缓存
这是 Redis 最经典的应用场景。
例如一个网站查询文章:
用户
↓
Redis
↓
缓存命中
↓
直接返回
如果 Redis 中没有:
用户
↓
Redis
↓
没有数据
↓
MySQL
↓
查询结果
↓
写入 Redis
↓
返回用户
这样可以减少 MySQL 的压力。
2. Session 存储
在传统单机应用中,用户登录信息可能存储在服务器本地。
但是当系统变成多台服务器:
用户
↓
负载均衡
↙ ↓ ↘
Server1 Server2 Server3
如果 Session 存储在某一台服务器上,就可能出现 Session 不一致的问题。
可以将 Session 放到 Redis:
Server1 ─┐
Server2 ─┼→ Redis
Server3 ─┘
这样不同服务器都可以访问统一的 Session 数据。
3. 分布式锁
在分布式系统中,多台服务器可能同时操作同一个资源。
例如:
服务器 A
↓
抢购商品
服务器 B
↓
抢购商品
如果没有控制,可能出现超卖。
Redis 可以利用相关机制实现分布式锁,从而控制多个服务实例对共享资源的并发访问。
4. 计数器
例如统计网站访问量:
page:view = 100000
用户访问一次:
INCR page:view
变成:
100001
Redis 的原子操作非常适合处理这种高频计数场景。
5. 排行榜
例如游戏排行榜:
玩家A → 9800
玩家B → 9500
玩家C → 9200
使用 Sorted Set 可以方便地按照分数进行排序。
因此 Redis 经常用于:
- 游戏排行榜
- 热门文章
- 商品销量排行
- 用户积分排行
6. 消息队列
Redis 的 List、Stream 等能力可以用于构建消息传递机制。
例如:
生产者
↓
Redis
↓
消息队列
↓
消费者
不过对于复杂、超大规模、强可靠性的消息系统,还需要根据业务需求考虑专门的消息队列产品。
Redis 的过期时间
Redis 一个非常重要的功能是:
数据可以设置过期时间。
例如:
login:token:10001
设置:
TTL = 3600 秒
一个小时后数据自动失效。
这对于缓存非常重要。
例如:
商品信息
↓
Redis
↓
设置过期时间:10分钟
10 分钟之后,缓存自动失效。
下次查询时再从数据库读取最新数据。
Redis 持久化是什么?
虽然 Redis 主要使用内存保存数据,但 Redis 也提供持久化机制,可以将数据保存到磁盘。
这样即使 Redis 进程发生重启,也可以在一定条件下恢复数据。
常见的持久化方式包括:
RDB
RDB 可以理解为:
某一个时间点的数据快照。
例如:
10:00 → 创建快照
11:00 → 创建快照
12:00 → 创建快照
Redis 可以将某个时间点的数据保存下来。
优点:
- 文件相对紧凑
- 恢复速度较快
- 适合备份
缺点:
- 两次快照之间发生的数据变化可能无法通过该快照恢复
AOF
AOF 可以理解为:
记录 Redis 执行过的写操作。
例如:
SET user:1 Tom
SET user:2 Jack
INCR counter
这些操作可以被记录下来。
Redis 重启时,可以通过重新执行相关操作恢复数据。
AOF 通常能够提供更细粒度的数据持久化能力,但文件可能更大。
Redis 和 MySQL 有什么区别?
Redis 和 MySQL 并不是简单的“谁替代谁”的关系。
它们通常会一起使用。
对比 | Redis | MySQL |
|---|---|---|
类型 | 内存数据存储 | 关系型数据库 |
数据模型 | Key-Value + 多种数据结构 | 表、行、列 |
主要存储 | 内存为主 | 磁盘为主 |
查询方式 | Key 和数据结构操作 | SQL |
典型特点 | 高性能、低延迟 | 数据管理能力强 |
常见用途 | 缓存、计数、排行榜 | 核心业务数据 |
数据持久化 | 支持 | 支持 |
事务能力 | 支持相关事务机制 | 完整关系型事务体系 |
适合场景 | 高频访问、实时数据 | 持久化业务数据 |
实际项目中经常采用:
用户请求
↓
Redis
↙ ↘
命中缓存 缓存不存在
↓ ↓
返回数据 MySQL
↓
查询数据
↓
写入 Redis
Redis 和 MySQL 可以形成互补。
什么是缓存穿透?
缓存穿透是缓存系统中的一个常见问题。
例如用户不断查询一个根本不存在的数据:
查询 ID=999999
↓
Redis 没有
↓
MySQL 也没有
↓
返回不存在
如果攻击者不断查询大量不存在的 ID:
大量请求
↓
Redis全部未命中
↓
大量访问MySQL
↓
数据库压力增大
这就是缓存穿透。
常见解决方式包括:
- 缓存空值
- 布隆过滤器
- 参数校验
- 限流
什么是缓存击穿?
缓存击穿通常指:
某个热点数据的缓存突然失效,大量请求同时访问数据库。
例如:
热门商品
↓
Redis缓存
↓
突然过期
↓
大量用户同时访问
↓
全部请求MySQL
可能导致数据库瞬间压力增大。
常见解决方式包括:
- 互斥锁
- 分布式锁
- 热点数据不过期
- 逻辑过期
- 合理设置缓存策略
什么是缓存雪崩?
缓存雪崩通常指大量缓存数据在相近时间同时失效。
例如:
商品A → 10:00过期
商品B → 10:00过期
商品C → 10:00过期
商品D → 10:00过期
大量请求同时访问数据库:
Redis
↓
大量缓存失效
↓
MySQL
↓
数据库压力暴增
常见解决方式包括:
- 给缓存过期时间增加随机值
- 热点数据提前预热
- 多级缓存
- 限流
- 降级
- 集群部署
Redis 的高可用
在生产环境中,通常不能只部署一个 Redis 实例。
因为如果 Redis 出现故障:
Redis宕机
↓
缓存无法访问
↓
大量请求访问数据库
↓
数据库压力增加
因此生产环境通常会根据业务规模采用:
- 主从复制
- Sentinel
- Redis Cluster
- 云 Redis 服务
等方案。
Redis Cluster 是什么?
Redis Cluster 是 Redis 提供的一种分布式集群方案。
它可以将数据分布到多个 Redis 节点。
例如:
Redis Cluster
┌────┼────┐
↓ ↓ ↓
Node1 Node2 Node3
↓ ↓ ↓
数据A 数据B 数据C
这样可以通过多个节点共同承担数据和请求压力。
Redis Cluster 主要用于:
- 数据分片
- 横向扩展
- 提高整体容量
- 提高系统可用性
Redis 有什么优点?
1. 性能高
主要基于内存进行数据访问,可以提供非常低的访问延迟。
2. 数据结构丰富
不仅支持简单 Key-Value,还提供:
- String
- Hash
- List
- Set
- Sorted Set
- Stream 等
3. 应用场景广泛
可以用于:
- 缓存
- Session
- 排行榜
- 计数器
- 分布式锁
- 消息传递
4. 支持过期机制
非常适合缓存临时数据。
5. 支持持久化
可以通过 RDB、AOF 等机制保存数据。
Redis 有什么缺点?
Redis 并不是所有场景下都适合。
1. 内存成本较高
Redis 主要依赖内存存储数据。
相比磁盘,内存成本通常更高。
因此不适合无脑将所有业务数据都放入 Redis。
2. 数据容量受到内存限制
如果数据量非常大,需要考虑:
- 内存容量
- 数据淘汰
- 数据分片
- 集群扩展
3. 数据可靠性需要额外设计
Redis 虽然支持持久化,但不同持久化策略具有不同的可靠性和性能特点。
对于核心业务数据,通常不能简单把 Redis 当成唯一的数据存储。
Redis 和 Memcached 有什么区别?
Redis 和 Memcached 都可以用于缓存。
对比 | Redis | Memcached |
|---|---|---|
数据结构 | 丰富 | 相对简单 |
String | 支持 | 支持 |
Hash | 支持 | 不支持原生 Hash |
List | 支持 | 不支持 |
Set | 支持 | 不支持 |
Sorted Set | 支持 | 不支持 |
持久化 | 支持 | 主要定位为缓存 |
应用场景 | 缓存 + 数据结构应用 | 主要用于缓存 |
Redis 因为数据结构更加丰富,因此在现代应用中拥有非常广泛的使用场景。
Java 项目中如何使用 Redis?
在 Java 项目中,Redis 经常与 Spring Boot 一起使用。
典型架构:
React / Vue 前端
↓
Spring Boot
↓
Redis
↓
MySQL
例如用户访问商品详情:
Controller
↓
Service
↓
查询 Redis
↓
缓存命中?
↙ ↘
是 否
↓ ↓
返回 MySQL
↓
写入Redis
↓
返回
在 Spring 生态中,可以通过 Spring Data Redis 等方式访问 Redis。
Redis 的典型项目架构
一个比较典型的 Web 系统可能是:
用户
↓
Nginx
↓
Spring Boot
↓
┌──────┴──────┐
↓ ↓
Redis MySQL
↓
缓存 / Session /
排行榜 / 计数器 /
分布式锁 / 消息
Redis 通常承担高频、低延迟的数据访问任务,而 MySQL 等数据库负责保存核心业务数据。
Redis 适合什么时候使用?
如果你的系统存在下面这些需求,可以考虑 Redis:
- 数据需要高频读取
- 对响应速度要求较高
- 数据允许缓存
- 需要计数器
- 需要排行榜
- 需要 Session 共享
- 需要分布式锁
- 需要临时数据存储
- 需要简单的消息传递
Redis 不适合什么时候使用?
如果数据具有以下特点,就不应该简单地全部放入 Redis:
- 数据量特别巨大
- 必须长期可靠保存
- 需要复杂 SQL 查询
- 需要复杂表关联
- 数据不能接受丢失
- 内存成本过高
这类场景通常应该使用专业数据库作为主要存储。
一个完整的 Redis 使用示例
假设 AI学习猫网站需要缓存百科文章。
用户访问:
/knowledge/redis
服务器首先查询:
knowledge:redis
如果 Redis 中存在:
Redis → 返回文章
如果 Redis 中不存在:
Redis
↓
没有
↓
MySQL
↓
查询文章
↓
写入 Redis
↓
返回用户
下一位用户再次访问:
用户
↓
Redis
↓
直接返回
这样就可以减少数据库查询,提高网站访问速度。
常见问题 FAQ
Redis 是数据库吗?
Redis 可以作为数据库使用,但它更准确地说是一种内存数据存储系统。它既可以承担数据库角色,也经常作为缓存、消息传递组件等使用。
Redis 为什么快?
主要因为 Redis 以高效的内存数据访问为基础,同时采用了高效的数据结构和请求处理机制。
Redis 只能做缓存吗?
不是。Redis 还可以用于 Session、排行榜、计数器、分布式锁、消息传递等场景。
Redis 数据会丢失吗?
Redis 支持持久化,但是否可能丢失数据取决于具体部署方式、持久化配置以及故障情况。因此核心业务数据通常不建议只依赖 Redis 保存。
Redis 和 MySQL 可以一起使用吗?
可以,而且非常常见。MySQL 通常保存核心业务数据,Redis 用于缓存和高频访问数据。
Redis 支持哪些数据结构?
常见结构包括 String、Hash、List、Set、Sorted Set,以及较新的 Stream 等数据结构。
Redis 适合高并发吗?
Redis 非常适合大量高频、低延迟的数据访问场景,但高并发系统仍需要结合连接管理、缓存策略、集群、限流、数据库等整体架构进行设计。
总结
Redis 是一个高性能的内存数据存储系统。
它最初经常被用于:
缓存数据
但随着功能不断丰富,Redis 已经可以应用于:
缓存 + Session + 计数器 + 排行榜 + 分布式锁 + 消息传递 + 实时数据处理
Redis 最核心的特点可以总结为:
Redis
│
├── 内存存储
├── 高性能
├── 低延迟
├── 丰富的数据结构
├── 支持过期时间
├── 支持持久化
├── 支持高可用
└── 支持分布式集群
如果你正在学习后端开发,可以把 Redis 放在这条学习路线中:
Java → Spring Boot → MySQL → Redis → 消息队列 → 分布式 → 微服务
掌握 Redis 后,再进一步学习 缓存设计、分布式锁、Redis Cluster、缓存穿透、缓存击穿和缓存雪崩,就能够逐渐理解 Redis 在真实生产系统中的使用方式。
相关知识
- MySQL
- 数据库
- 缓存
- Key-Value 数据库
- 分布式锁
- 消息队列
- Redis Cluster
- RDB
- AOF
- 缓存穿透
- 缓存击穿
- 缓存雪崩
- Spring Boot
- Spring Data Redis
延伸阅读
如果想系统学习 Redis,可以按照下面的顺序:
Redis基础 → 数据类型 → 常用命令 → Key设计 → 过期机制 → 缓存策略 → RDB/AOF → Redis主从 → Sentinel → Redis Cluster → 分布式锁 → 缓存问题 → Redis性能优化
这样可以从“会使用 Redis”逐渐进阶到“能够进行 Redis 架构设计”。