Redis 基础
核心定义 Redis 是一个高性能的内存型 Key-Value 数据库,支持丰富的数据结构、持久化、主从复制、哨兵高可用和 Cluster 分片,常用于缓存、计数器、排行榜、分布式锁和会话存储等场景。
1. 关系型数据库与非关系型数据库
关系型数据库通常使用 SQL(Structured Query Language,结构化查询语言)操作数据。它将复杂数据组织为表、行、列,并依赖表结构、约束和事务保证数据一致性。
Redis 属于非关系型数据库,核心特点是以 Key-Value 方式组织数据,并把主要数据保存在内存中,因此读写性能很高。
| 对比项 | 关系型数据库 | Redis |
|---|---|---|
| 数据模型 | 表、行、列 | Key-Value 与多种数据结构 |
| 存储位置 | 以磁盘为主,内存缓存加速 | 以内存为主,可持久化到磁盘 |
| 查询方式 | SQL | Redis 命令 |
| 典型用途 | 事务型业务数据 | 缓存、计数、排行榜、队列、锁 |
| 一致性能力 | 强事务能力 | 更偏高性能与灵活数据结构 |
2. Redis 核心特征
2.1. 高性能
Redis 使用 C 语言实现,数据主要存储在内存中,并采用高效的数据结构和事件驱动模型,因此具有很高的读写性能。
2.2. 支持多种数据结构
Redis 不只支持简单字符串,还支持 Hash、List、Set、Sorted Set、Bitmap、HyperLogLog、GEO、Stream 等结构,适合不同业务场景。
2.3. 支持持久化
Redis 可以通过 RDB、AOF 或混合持久化将内存数据保存到磁盘,用于实例重启后的数据恢复。
2.4. 支持复制和高可用
Redis 支持主从复制。结合 Sentinel 可以实现主节点故障后的自动切换;结合 Redis Cluster 可以实现分片和高可用。
2.5. 适合作为分布式缓存
Redis 常用于缓存热点数据,减少数据库访问压力,提高系统整体读性能。
3. Redis 常用数据类型
| 数据类型 | 说明 | 典型场景 |
|---|---|---|
| String | 字符串、整数、浮点数 | 缓存值、计数器、分布式锁 |
| Hash | 字段和值组成的字典 | 对象缓存、用户信息 |
| List | 有序列表,可从两端插入弹出 | 消息队列、最新列表 |
| Set | 无序且不重复集合 | 标签、去重、交并差集 |
| Sorted Set | 带 score 的有序集合 | 排行榜、延迟队列 |
| Bitmap | 按 bit 统计 | 签到、在线状态 |
| HyperLogLog | 基数统计 | UV 统计 |
| GEO | 地理位置索引 | 附近的人、门店距离 |
| Stream | 消息流 | 消息队列、事件流 |
4. String 类型
String 是 Redis 最基础的数据类型,值可以是普通字符串、整数或浮点数。
常用命令:
| 命令 | 作用 |
|---|---|
SET key value | 设置字符串键值 |
GET key | 获取字符串值 |
MSET k1 v1 k2 v2 | 批量设置多个键值 |
MGET k1 k2 | 批量获取多个键值 |
INCR key | 整数自增 1 |
INCRBY key n | 整数按指定步长自增 |
INCRBYFLOAT key n | 浮点数按指定步长自增 |
SETNX key value | key 不存在时才设置 |
SETEX key seconds value | 设置值并指定过期时间 |
示例:
SET user:1:name alice
GET user:1:name
INCR page:view
SETEX verify:code:1001 300 9527
5. Hash 类型
Hash 是字段和值组成的字典结构,适合存储对象。
常用命令:
| 命令 | 作用 |
|---|---|
HSET key field value | 设置字段值 |
HGET key field | 获取字段值 |
HMGET key f1 f2 | 批量获取字段 |
HGETALL key | 获取所有字段和值 |
HKEYS key | 获取所有字段 |
HVALS key | 获取所有值 |
HINCRBY key field n | 字段值按整数自增 |
HSETNX key field value | 字段不存在时才设置 |
示例:
HSET user:1 name alice age 20
HGET user:1 name
HINCRBY user:1 age 1
6. List 类型
List 是有序列表,可以从左侧或右侧插入、弹出元素。它类似双向链表,适合队列、栈和最新消息列表。
特点:
- 元素有序。
- 元素可以重复。
- 两端插入和删除效率高。
- 按索引范围查询适合小范围读取。
常用命令:
| 命令 | 作用 |
|---|---|
LPUSH key element | 从左侧插入元素 |
RPUSH key element | 从右侧插入元素 |
LPOP key | 从左侧弹出元素 |
RPOP key | 从右侧弹出元素 |
LRANGE key start stop | 获取指定范围元素 |
BLPOP key timeout | 阻塞式左侧弹出 |
BRPOP key timeout | 阻塞式右侧弹出 |
示例:
LPUSH queue:task task1
RPUSH queue:task task2
LRANGE queue:task 0 -1
7. Set 类型
Set 是无序且不重复的集合,底层类似哈希表,适合去重和集合运算。
特点:
- 无序。
- 元素不可重复。
- 查找效率高。
- 支持交集、并集、差集。
常用命令:
| 命令 | 作用 |
|---|---|
SADD key member | 添加元素 |
SREM key member | 删除元素 |
SCARD key | 获取元素数量 |
SISMEMBER key member | 判断元素是否存在 |
SMEMBERS key | 获取所有元素 |
SINTER key1 key2 | 求交集 |
SDIFF key1 key2 | 求差集 |
SUNION key1 key2 | 求并集 |
示例:
SADD user:1:tags linux redis mysql
SISMEMBER user:1:tags redis
SINTER user:1:tags user:2:tags
8. Sorted Set 类型
Sorted Set 是带分数 score 的有序集合。元素不重复,但可以按照 score 排序。
底层通常由 Hash 与跳表等结构配合实现,适合排行榜、权重排序和延迟队列。
常用命令:
| 命令 | 作用 |
|---|---|
ZADD key score member | 添加或更新元素分数 |
ZREM key member | 删除元素 |
ZSCORE key member | 获取元素分数 |
ZRANK key member | 获取升序排名 |
ZCARD key | 获取元素数量 |
ZCOUNT key min max | 统计分数范围内元素数量 |
ZINCRBY key n member | 增加元素分数 |
ZRANGE key start stop | 按排名范围获取元素 |
ZRANGEBYSCORE key min max | 按分数范围获取元素 |
示例:
ZADD rank:score 100 alice 90 bob
ZRANGE rank:score 0 -1 WITHSCORES
ZINCRBY rank:score 10 alice
9. 常用通用命令
| 命令 | 作用 | 注意事项 |
|---|---|---|
KEYS pattern | 查看匹配 key | 生产环境慎用,可能阻塞 Redis |
SCAN cursor MATCH pattern COUNT n | 渐进式扫描 key | 生产环境更推荐 |
DEL key | 删除 key | 同步删除,大 key 可能阻塞 |
UNLINK key | 异步删除 key | 更适合删除大 key |
EXISTS key | 判断 key 是否存在 | 返回存在数量 |
EXPIRE key seconds | 设置过期时间 | 用于缓存 TTL |
TTL key | 查看剩余过期时间 | -1 表示无过期,-2 表示不存在 |
TYPE key | 查看 key 类型 | 排查数据结构 |
示例:
SCAN 0 MATCH user:* COUNT 100
EXPIRE user:1 3600
TTL user:1
TYPE user:1
10. Redis 持久化
Redis 是内存数据库。为了避免进程退出后数据永久丢失,需要将内存数据保存到磁盘。Redis 常见持久化方式包括 RDB、AOF 和混合持久化。
| 持久化方式 | 原理 | 优点 | 缺点 |
|---|---|---|---|
| RDB | 定期生成内存快照 | 文件紧凑,恢复快 | 两次快照之间可能丢数据 |
| AOF | 记录写命令日志 | 数据丢失更少 | 文件更大,恢复可能较慢 |
| 混合持久化 | AOF 文件前半段为 RDB,后半段为增量命令 | 兼顾恢复速度和数据完整性 | 依赖 Redis 4.0+ |
11. RDB 持久化
RDB 全称 Redis Database Backup file,也称 Redis 数据快照。它会把某一时刻的内存数据保存为 RDB 文件。
bgsave 执行流程:
- 主进程 fork 子进程。
- 子进程读取内存数据并写入临时 RDB 文件。
- 写入完成后替换旧 RDB 文件。
- 主进程继续处理请求。
fork 使用 Copy-On-Write 机制:
- 主进程读数据时共享内存页。
- 主进程写数据时复制被修改的内存页。
- 子进程基于 fork 时刻的数据生成快照。
RDB 缺点:
- 快照间隔内的数据可能丢失。
- fork 子进程会带来瞬时开销。
- 大实例生成 RDB 可能造成磁盘 IO 压力。
12. AOF 持久化
AOF(Append Only File)会记录 Redis 执行过的写命令,实例重启时通过重放命令恢复数据。
AOF 三种刷盘策略:
| 策略 | 含义 | 优点 | 缺点 |
|---|---|---|---|
appendfsync always | 每次写入都刷盘 | 数据最安全 | 性能最差 |
appendfsync everysec | 每秒刷盘一次 | 性能和安全折中 | 最多丢 1 秒数据 |
appendfsync no | 交给操作系统刷盘 | 性能较好 | 丢数据风险更高 |
生产环境常用:
appendonly yes
appendfsync everysec
13. RDB 与 AOF 对比
| 对比项 | RDB | AOF |
|---|---|---|
| 数据完整性 | 较弱,可能丢快照间隔内数据 | 较强,everysec 通常最多丢 1 秒 |
| 文件大小 | 较小 | 较大 |
| 恢复速度 | 较快 | 取决于 AOF 大小 |
| 写入开销 | 主要发生在 bgsave | 持续追加写命令 |
| 适合场景 | 备份、快速恢复 | 生产数据安全要求较高场景 |
推荐策略:生产环境通常开启 AOF everysec,并根据业务恢复要求保留 RDB 作为备份手段。详见 Redis 持久化机制。
14. Redis 主从复制
Redis 主从复制用于将主节点数据同步到一个或多个从节点,提高读扩展能力和高可用基础能力。
核心概念:
| 概念 | 说明 |
|---|---|
replication id | 数据集标识,用于判断是否属于同一复制历史 |
offset | 复制偏移量,用于判断主从同步进度 |
repl_backlog | 复制积压缓冲区,用于支持部分重同步 |
| 全量同步 | 主节点生成 RDB 并发送给从节点 |
| 增量同步 | 主节点发送 backlog 中缺失的写命令 |
主从同步简化流程:
从节点连接主节点
↓
发送 replication id 和 offset
↓
主节点判断能否增量同步
↓
可增量:发送缺失命令
不可增量:生成 RDB 进行全量同步
↓
进入持续命令传播阶段
详见 Redis 主从同步完整深度详解。
15. Redis Sentinel 哨兵
Sentinel 用于监控 Redis 主从集群并在主节点故障时自动故障转移。
Sentinel 主要职责:
- 监控:持续检查 master 和 replica 是否可用。
- 自动故障恢复:master 故障后选举新的 master。
- 通知:向客户端或运维系统通知拓扑变化。
- 配置更新:让其他 replica 重新指向新的 master。
故障判断:
| 状态 | 含义 |
|---|---|
| 主观下线 | 单个 Sentinel 认为实例不可用 |
| 客观下线 | 达到 quorum 数量的 Sentinel 都认为 master 不可用 |
16. Sentinel 选主与故障转移
Sentinel 选择新 master 时通常参考:
- 排除与旧 master 断开时间过长的 replica。
- 优先选择
slave-priority更高的 replica。 - 优先选择复制 offset 更大的 replica。
- 如果仍相同,比较运行 ID。
故障转移流程:
- Sentinel 选出一个 replica 作为新 master。
- 向该节点发送
SLAVEOF NO ONE。 - 让其他 replica 指向新 master。
- 旧 master 恢复后成为新 master 的 replica。
17. Redis 分片集群
Redis 分片集群用于将数据分散到多个 master 节点,突破单机内存和吞吐瓶颈。
Redis Cluster 的核心特征:
- 集群中有多个 master,每个 master 负责一部分槽位。
- 每个 master 可以有多个 replica。
- 集群使用 16384 个 hash slot 分配数据。
- 节点之间通过 Gossip 协议感知状态。
- 客户端可以访问任意节点,必要时通过重定向找到正确节点。
示意:
key -> CRC16(key) % 16384 -> slot -> 对应 master 节点
详见 Redis 分片完整详解。
关联文档
- Redis 核心原理:系统理解 Redis 单线程模型、数据结构和持久化机制。
- Redis 持久化机制:深入理解 RDB、AOF 和混合持久化。
- Redis 主从同步完整深度详解:理解主从复制、offset 和 repl_backlog。
- Redis 三种高可用方案完整详解:理解主从、Sentinel 和 Cluster 的架构选型。
- Redis 面试题:配套 Redis 高频面试问题。
