Redis 从入门到实战:一篇搞定缓存、持久化、主从、哨兵与集群
摘要:Redis 是后端开发必会的技术栈之一。本文从零开始,系统梳理 Redis 的核心概念、五种数据类型、八大应用场景、RDB/AOF 持久化机制、主从复制、哨兵高可用、Cluster 集群部署以及 Docker 容器化实战,配合大量可复制的命令示例,适合初学者入门和老兵复习。
目录
- 一、Redis 是什么
- 二、Redis 为什么快
- 三、五种核心数据类型
- 四、八大应用场景
- 五、持久化:RDB 与 AOF
- 六、安装与配置
- 七、主从复制
- 八、哨兵模式(Sentinel)
- 九、Redis Cluster 集群
- 十、Docker 容器化部署
- 十一、总结
一、Redis 是什么
Redis(Remote Dictionary Server)是一个开源的、基于内存的高性能 Key-Value 数据库,使用 C 语言编写,遵循 BSD 协议。
三个核心特点:
- 持久化:支持将内存数据保存到磁盘,重启后可重新加载
- 丰富的数据结构:不仅支持 String,还提供 List、Set、Zset、Hash 等
- 主从备份:支持 Master-Slave 模式的数据备份
二、Redis 为什么快
| 特性 | 说明 |
|---|---|
| 🚀 纯内存操作 | 数据存在内存中,微秒级响应,QPS 可达 10 万~100 万+ |
| 🧵 单线程模型 | Redis 6.0 前核心网络 IO 为单线程,避免上下文切换和锁竞争 |
| 📡 IO 多路复用 | 基于 Linux epoll,一个线程管理多个 socket 连接 |
| 💾 高效数据结构 | C 语言实现,数据结构设计简洁高效 |
| 📝 简单协议 | RESP 协议解析成本极低 |
IO 多路复用 — 通俗理解
你去小吃街买饭:烧烤、饺子、炒菜。如果每样排队等(串行),耗时最长;三个人分别排(多线程),快但开销大;你跟每个老板说"好了叫我"(epoll),一个线程同时等三份——这就是 IO 多路复用。
Linux 上三套 API:select(轮询)→ poll(轮询升级版)→ epoll(事件通知,主流方案)。
三、五种核心数据类型
Redis 所有 Key 都是字符串,Value 支持以下五种类型:
3.1 String(字符串)
最基本类型,二进制安全,最大 512MB。
SET key value [EX seconds] [PX milliseconds] [NX|XX]
GET key
SETEX key seconds value # 设置并指定过期时间
SETNX key value # 仅当 key 不存在时设置(分布式锁)
INCR key / DECR key # 原子递增 / 递减
INCRBY key increment # 增加指定值
MSET k1 v1 k2 v2 # 批量设置
MGET k1 k2 # 批量获取
STRLEN key # 字符串长度
APPEND key value # 追加内容
GETSET key value # 设置新值并返回旧值
SET命令的可选参数:EX(秒级过期)、PX(毫秒级过期)、NX(不存在才设)、XX(存在才设)。
# 基本操作
127.0.0.1:6379> SET name wang EX 100 # 100秒后过期
OK
127.0.0.1:6379> TTL name # 查看剩余时间
(integer) 95
127.0.0.1:6379> SETNX title ceo # 仅当不存在时设置
(integer) 1
127.0.0.1:6379> SET title cto XX # 仅当存在时覆盖
OK
3.2 List(列表)
有序可重复的字符串链表,支持左右两端操作,常用于消息队列。
LPUSH key value [value ...] # 左侧插入
RPUSH key value [value ...] # 右侧插入
LPOP key # 左侧弹出
RPOP key # 右侧弹出
BRPOP key timeout # 阻塞式右侧弹出(秒)
LLEN key # 列表长度
LRANGE key start stop # 按范围获取
LINDEX key index # 按索引获取
LREM key count value # 删除指定元素
127.0.0.1:6379> LPUSH queue "msg1" "msg2"
(integer) 2
127.0.0.1:6379> BRPOP queue 5 # 阻塞等待5秒
1) "queue"
2) "msg1"
3.3 Set(集合)
无序、不重复的字符串集合,支持交/并/差集运算。
SADD key member [member ...] # 添加成员
SREM key member [member ...] # 删除成员
SMEMBERS key # 列出所有成员
SISMEMBER key member # 判断是否成员
SCARD key # 集合大小
SINTER key1 key2 # 交集
SUNION key1 key2 # 并集
SDIFF key1 key2 # 差集
127.0.0.1:6379> SADD tags:1 "redis" "database" "nosql"
(integer) 3
127.0.0.1:6379> SADD tags:2 "redis" "cache"
(integer) 2
127.0.0.1:6379> SINTER tags:1 tags:2 # 共同标签
1) "redis"
3.4 Zset(Sorted Set,有序集合)
每个元素关联一个 Score,按 Score 自动排序。
ZADD key score member [score member ...]
ZRANGE key start stop [WITHSCORES] # 按索引范围(升序)
ZREVRANGE key start stop [WITHSCORES] # 按索引范围(降序)
ZREM key member [member ...] # 删除成员
ZSCORE key member # 查询分数
ZRANK key member # 查询排名(升序)
ZCOUNT key min max # 按分数范围统计
🏆 典型应用:排行榜(商品销量、游戏积分、实时投票)。
127.0.0.1:6379> ZADD leaderboard 100 "player1" 200 "player2" 150 "player3"
(integer) 3
127.0.0.1:6379> ZREVRANGE leaderboard 0 -1 WITHSCORES
1) "player2"
2) "200"
3) "player3"
4) "150"
5) "player1"
6) "100"
3.5 Hash(哈希)
键值对集合,适合存储对象。
HSET key field value [field value ...]
HGET key field
HGETALL key
HDEL key field [field ...]
HEXISTS key field
HLEN key
HINCRBY key field increment
HKEYS key / HVALS key
127.0.0.1:6379> HSET user:1001 name "张三" age 25 city "北京"
(integer) 3
127.0.0.1:6379> HGET user:1001 name
"张三"
127.0.0.1:6379> HINCRBY user:1001 age 1
(integer) 26
四、八大应用场景
🗂️ 1. 热点数据缓存(Cache-Aside 模式)
读请求 → 查 Redis → 命中返回 / 未命中 → 查 DB → 回写 Redis → 返回
要点:合理 TTL、缓存键命名规范(product:info:1001)、空值缓存防止穿透。
🔒 2. 分布式锁
# 加锁:仅当 key 不存在时设置,30秒过期
SET lock:order:1001 unique_value NX PX 30000
# 解锁:Lua 脚本原子判断 + 删除
EVAL "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end" 1 lock:order:1001 unique_value
要点:加锁设过期 → 解锁用 Lua 保证原子性 → 长任务定时续期。
📊 3. 计数器与限流
INCR article:read:10086 # 阅读量 +1
INCR rate:api:/user:20240709 # 接口调用计数
EXPIRE rate:api:/user:20240709 60 # 每分钟最多 N 次
🏆 4. 排行榜系统
用 Zset 的 Score 排序,ZREVRANGE 取 Top N,ZRANK 查排名。
🔑 5. 分布式会话(Session)
多实例共享 Session,设置过期时间自动清理。
✉️ 6. 消息队列
List + LPUSH / BRPOP:生产者推入,消费者阻塞等待。
🗳️ 7. 位图(Bitmap)
用户签到、活跃统计、权限标记,极致节省空间。
📍 8. 地理位置(GEO)
附近的人 / 店铺查询,GEOADD + GEORADIUS。
五、持久化:RDB 与 AOF
Redis 是内存数据库,一旦宕机数据即丢失。持久化机制将数据写入磁盘。
5.1 RDB(Redis DataBase)— 快照
定时将内存数据生成快照保存到 dump.rdb 文件。
触发方式:
# 手动触发
SAVE # 同步阻塞,主进程执行,生产禁用
BGSAVE # 异步 Fork 子进程执行,推荐
# 配置文件自动触发
save 900 1 # 900秒内修改1个Key
save 300 10 # 300秒内修改10个Key
save 60 10000 # 60秒内修改10000个Key
| SAVE | BGSAVE | |
|---|---|---|
| 执行方式 | 主进程 | Fork 子进程 |
| 是否阻塞 | ✅ 阻塞所有请求 | ❌ 仅 Fork 瞬间阻塞 |
| 适用场景 | 测试环境 | 生产环境 |
5.2 AOF(Append Only File)— 追加日志
记录每条写命令到 appendonly.aof 文件,重启时回放恢复数据。
# redis.conf
appendonly yes # 开启 AOF
appendfsync always # 每条命令都刷盘(最安全,最慢)
appendfsync everysec # 每秒刷盘一次(推荐,最多丢1秒数据)
appendfsync no # 由操作系统决定(最快,最不安全)
| 策略 | 安全性 | 性能 | 推荐 |
|---|---|---|---|
always |
最高(不丢数据) | 最低 | 极少用 |
everysec |
高(最多丢1秒) | 高 | ✅ 生产推荐 |
no |
低 | 最高 | 不推荐 |
5.3 RDB vs AOF 对比
| 维度 | RDB | AOF |
|---|---|---|
| 文件大小 | 小(压缩二进制) | 大(文本命令) |
| 恢复速度 | 快 | 慢(需回放命令) |
| 数据安全 | 可能丢几分钟数据 | 最多丢1秒(everysec) |
| 资源消耗 | Fork 子进程,瞬间高 | 持续 IO 写入 |
| 推荐 | AOF + RDB 混合使用 | — |
💡 最佳实践:生产环境同时开启 RDB 和 AOF(
everysec),RDB 用于快速恢复,AOF 保证数据安全。
六、安装与配置
6.1 YUM 安装(CentOS 8)
# 安装
dnf install -y redis
# 启动并设置开机自启
systemctl enable redis --now
# 验证
ss -ntl | grep 6379
redis-cli ping # 返回 PONG 即成功
6.2 源码编译安装(通用)
# 安装依赖
yum install -y tcl gcc gcc-c++
# 编译
tar zxvf redis-6.2.14.tar.gz -C /usr/local/
cd /usr/local/redis-6.2.14/
make && make install
# 后台启动
redis-server redis.conf &
6.3 多实例
redis-server --port 6380 # 启动第二个实例
redis-cli -p 6380 # 连接到第二个实例
6.4 关键配置项速查
| 配置项 | 默认值 | 说明 |
|---|---|---|
bind 127.0.0.1 |
127.0.0.1 |
绑定地址,远程访问改 0.0.0.0 |
port 6379 |
6379 |
监听端口 |
protected-mode yes |
yes |
保护模式,无密码时仅本地连接 |
timeout 0 |
0 |
客户端空闲超时(0=不超时) |
tcp-keepalive 300 |
300 |
TCP 心跳探测间隔(秒) |
daemonize no |
no |
是否后台运行 |
requirepass |
空 | 连接密码 |
maxmemory |
0 | 最大内存限制(0=不限制) |
💡 6379 的冷知识:MERZ 是作者 antirez 和朋友用的俚语(形容"愚蠢"),在手机键盘上对应数字 6379。
七、主从复制
Redis 主从复制实现数据冗余和读写分离:
- Master 可读可写,Slave 只读
- 一个 Master 可以有多个 Slave
- 数据流向:Master → Slave 单向
实验拓扑
| 角色 | IP | 主机名 |
|---|---|---|
| Master | 192.168.108.10 | master |
| Slave01 | 192.168.108.11 | slave01 |
| Slave02 | 192.168.108.12 | slave02 |
配置
# === 所有节点:配置 redis.conf ===
bind 0.0.0.0 -::1
# === Slave 节点额外配置:指向 Master ===
# redis.conf 方式:
replicaof 192.168.108.10 6379
# 命令行方式:
127.0.0.1:6379> REPLICAOF 192.168.108.10 6379
同步原理
1. Slave → Master: 发送 SYNC 命令
2. Master: 启动 BGSAVE 生成 RDB,同时缓冲新增写命令
3. Master → Slave: 传输 RDB 文件
4. Slave: 加载 RDB,完成首次全量同步
5. Master → Slave: 持续发送增量写命令(增量同步)
验证
# Master 查看复制状态
redis-cli INFO replication
# role:master
# connected_slaves:2
# Slave 查看
redis-cli INFO replication
# role:slave
# master_link_status:up ← 关键:必须为 up
# 数据验证:Master 写入
127.0.0.1:6379> SET name laogao
OK
# Slave 读取
127.0.0.1:6379> GET name
"laogao" # ✅ 同步成功
取消主从
127.0.0.1:6379> REPLICAOF NO ONE
八、哨兵模式(Sentinel)
在主从基础上实现自动故障转移,是 Redis 原生高可用方案。
核心功能
| 功能 | 说明 |
|---|---|
| 监控 | 持续检查 Master 和 Slave 是否正常运行 |
| 通知 | 节点异常时通过 API 告警 |
| 自动故障转移 | Master 宕机后,自动选举新 Master |
| 配置提供者 | 客户端通过 Sentinel 获取最新 Master 地址 |
⚠️ Sentinel 本身不存储数据,只负责监控与协调。
哨兵判断流程
主观下线(SDOWN):一个 Sentinel 认为 Master 不可达
↓
客观下线(ODOWN):≥ quorum 个 Sentinel 都认为 Master 不可达
↓
选举 Leader Sentinel → 发起故障转移 → 提升 Slave 为新 Master
Sentinel 配置
# sentinel.conf
sentinel monitor mymaster 192.168.108.10 6379 2
# 名称 Master IP 端口 quorum
sentinel down-after-milliseconds mymaster 30000
sentinel failover-timeout mymaster 180000
sentinel parallel-syncs mymaster 1
# quorum=2:至少2个哨兵认为挂了才算客观下线
启动哨兵
redis-sentinel sentinel.conf &
# 查看哨兵状态
redis-cli -p 26379
127.0.0.1:26379> INFO sentinel
# sentinel_masters:1
# master0:name=mymaster,status=ok,address=192.168.108.10:6379,slaves=2,sentinels=3
九、Redis Cluster 集群
哨兵解决高可用,Cluster 解决数据分片(水平扩展)。
核心概念
- Redis Cluster 将整个键空间划分为 16384 个哈希槽
- 数据映射公式:
slot = CRC16(key) % 16384 - 每个节点负责一部分槽,支持在线迁移
┌─────────────┬──────────────┬──────────────┐
│ Master 1 │ Master 2 │ Master 3 │
│ slot 0-5460 │slot 5461-10922│slot 10923-16383│
│ Slave 1 │ Slave 2 │ Slave 3 │
└─────────────┴──────────────┴──────────────┘
创建 3 主 3 从集群
# 一键创建
redis-cli --cluster create \
192.168.108.21:6379 \
192.168.108.22:6379 \
192.168.108.23:6379 \
192.168.108.24:6379 \
192.168.108.25:6379 \
192.168.108.26:6379 \
--cluster-replicas 1 # 每主1从
# 验证
redis-cli -c -h 192.168.108.21 -p 6379 cluster nodes
redis-cli -c -h 192.168.108.21 -p 6379 cluster info
# cluster_state:ok ← 关键状态
# cluster_slots_assigned:16384
客户端连接(-c 模式)
redis-cli -c -h 192.168.108.21 -p 6379
127.0.0.1:6379> SET name wang
OK
127.0.0.1:6379> GET age
-> Redirected to slot [741] located at 192.168.108.21:6379
"18"
故障转移验证
关掉一个 Master,集群自动将对应 Slave 提升为新 Master:
# 关掉 master 1
[root@redis1 ~]# init 0
# 在存活的节点上查看
redis-cli -c -h 192.168.108.22 -p 6379 cluster nodes
# 原 slave 已被选举为新 master ✅
# cluster_state:ok ← 集群仍然正常
十、Docker 容器化部署
# 启动 Redis 容器
docker run --name redis \
-p 6379:6379 \
-d \
-v /data/redis:/data \
redis
# 查看 Redis 信息
docker exec redis redis-cli INFO server
# 数据操作
docker exec redis redis-cli SET name wang
docker exec redis redis-cli GET name
# "wang"
# 持久化(数据保存在挂载的 /data/redis/dump.rdb)
docker exec redis redis-cli SAVE
十一、总结
技术选型参考
| 场景 | 方案 |
|---|---|
| 单机缓存 | Redis 单实例 |
| 读写分离 + 数据冗余 | 主从复制(1 主 N 从) |
| 自动故障转移 | 哨兵模式(≥ 3 个 Sentinel) |
| 海量数据 + 水平扩展 | Redis Cluster(≥ 6 节点,3 主 3 从) |
| 开发 / 测试环境 | Docker 一键部署 |
📖 本文基于个人 Redis 学习笔记整理,内容覆盖从入门到生产部署的完整链路。如有纰漏,欢迎评论区交流指正。
🔗 相关资源:Redis 官网 | Redis 中文文档 )
更多推荐




所有评论(0)