《Redis 备忘录:一篇笔记,搞定 90% 的生产场景》
·
Redis
1. Redis 简介
Redis 是完全开源的,遵守 BSD 协议,是一个高性能的 key-value 数据库。
1.1 Redis三大特点
- 持久化:可将内存中的数据保存在磁盘中,重启时加载使用。
- 丰富的数据结构:不仅支持简单的 key-value,还支持 list、set、zset、hash 等。
- 数据备份:支持 master-slave 模式的数据备份。
1.2 Redis 优势
- 性能极高:10万~100万+ QPS,微秒级响应。
- 丰富的数据类型:Strings、Lists、Hashes、Sets、OrderedSets。
- 原子性:所有操作都是原子性的,支持事务(MULTI / EXEC)。
- 丰富的特性:支持 publish/subscribe、通知、key 过期等。
1.3 与其他 key-value 存储的不同
- 更复杂的数据结构,并提供原子性操作。
- 内存操作,内部复杂性高,但磁盘格式紧凑、追加方式产生。
2. Redis 数据类型
| 类型 | 说明 |
|---|---|
| string | 最基本类型,二进制安全,最大 512MB |
| hash | 键值对集合,适合存储对象 |
| list | 简单字符串列表,按插入顺序排序,可重复 |
| set | 无序集合,元素唯一 |
| zset (sorted set) | 有序集合,每个元素关联一个分数(score) |
3. 哈希槽(Redis Cluster)
- 槽的数量:16384 个(0 ~ 16383),固定数量。
- 映射规则:
HASH_SLOT = CRC16(key) mod 16384 - 数据分布:每个集群节点负责一部分槽。支持动态迁移与扩容。
4. Redis 常见应用场景
| 场景 | 说明 |
|---|---|
| 热点数据缓存 | Cache-Aside 模式,设置合理 TTL |
| 分布式锁 | SETNX + Lua 脚本,设置过期时间 |
| 计数器与限流 | INCR 原子递增,过期时间实现限流 |
| 排行榜系统 | SortedSet 按分数排序 |
| 分布式会话 | 集中存储用户会话信息 |
| 消息队列 | List 的 LPUSH / BRPOP,简单队列 |
| 位图应用 | 签到、活跃用户统计 |
| 地理信息存储 | GEO 数据结构,LBS 场景 |
5. Redis 特性
- 速度快:10W QPS,基于内存,C 语言实现
- 单线程(6.0 版本前)
- 持久化:RDB 和 AOF
- 支持多种数据结构
- 功能丰富:Lua 脚本、发布订阅、事务、Pipeline
- 简单:单机核心代码约 23000 行
- 主从复制
- 高可用和分布式:哨兵、集群
5.1 单线程模型
Redis 使用单线程处理请求(6.0 前),原因:
- 操作基于内存,快;数据库访问硬盘,慢
- 核心功能比数据库简单
- 避免线程竞争开销
- 使用 epoll 实现 IO 多路复用
5.2 IO 多路复用(epoll)
- 一个线程处理多个 socket
- Linux 提供 select、poll、epoll 三套 API
- 类似于点餐时“好了叫我”的回调机制
6. 持久化
6.1 RDB(Redis DataBase)
- 快照方式,保存某个时刻的内存数据到
dump.rdb - 触发方式:
save(同步,阻塞)、bgsave(异步,fork 子进程) - 配置触发:
save 900 1、save 300 10、save 60 10000 - 优点:恢复数据快,文件紧凑,适合备份
- 缺点:可能丢失最近一次快照后的数据,fork 子进程消耗内存
6.2 AOF(Append-only File)
- 记录每个写操作命令,追加到
appendonly.aof - 写入策略:
always:每个写操作都同步,最安全但慢everysec:每秒同步一次,默认,最多丢 1 秒数据no:由操作系统决定,最快但不安全
- AOF 重写:压缩命令集,减少文件大小,使用
bgrewriteaof - 优点:数据更完整,丢失数据少
- 缺点:文件大,恢复数据慢
当 RDB 和 AOF 都开启时,Redis 优先使用 AOF 恢复数据。
7. Pipeline 流水线
- 将一组 Redis 命令打包,一次 RTT 传输,减少网络往返时间。
- 适用于不支持批量操作的命令(如多次
hgetall)。 - 网络延迟越大,Pipeline 性能提升越明显。
8. 缓存问题
8.1 缓存穿透
- 定义:查询不存在的数据(缓存和数据库中都没有),请求直接打到数据库。
- 解决方案:
- 接口层校验
- 缓存空结果(短 TTL)
- 布隆过滤器
8.2 缓存击穿
- 定义:热点 key 过期瞬间,大量并发请求同时打到数据库。
- 解决方案:
- 加锁排队
- 热点 key 设置为永不过期(需主动更新)
8.3 缓存雪崩
- 定义:大面积 key 同时过期或 Redis 宕机,所有请求涌入数据库。
- 解决方案:
- 过期时间加随机值
- 搭建高可用集群(哨兵、Cluster)
- 服务限流熔断(Sentinel、Hystrix)
- 多级缓存(本地缓存 + Redis)
9. 主从复制
- 目的:数据冗余、读写分离
- 特点:
- 一个 master 可以有多个 slave
- 一个 slave 只能有一个 master
- 数据流向 master → slave 单向
- master 可读写,slave 只读
- 工作原理:
- slave 向 master 发送
sync命令 - master 启动后台存盘进程,收集修改命令
- master 传送 RDB 文件给 slave
- slave 加载数据完成首次同步
- 后续增量同步
- slave 向 master 发送
10. 哨兵模式(Sentinel)
- 目的:在主从复制基础上实现自动故障转移(高可用)
- 核心功能:监控、通知、自动故障转移、配置提供者
- 故障转移流程:
- 主观下线(SDOWN)
- 客观下线(ODOWN)——多个 Sentinel 确认
- 选举 Leader 执行故障转移
- 提升最优从节点为新 master
- 重配其他从节点
- 通知客户端
11. Redis Cluster 集群
- 目的:解决单机容量、性能、单点故障问题,实现水平扩展
- 核心特点:
- 无中心架构,数据分片(16384 个哈希槽)
- 主从复制 + 自动故障转移
- 节点间通过 Gossip 协议通信
- 数据映射:
HASH_SLOT = CRC16(key) mod 16384 - 故障转移:当 master 宕机,其 slave 自动选举成为新 master
- 使用场景:海量数据(>100GB)、高并发(QPS ≥ 5万)
集群搭建示例(3主3从)
bash
# 在所有节点配置
bind 0.0.0.0
cluster-enabled yes
# 创建集群(任意节点)
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
12. 常用命令
| 命令 | 说明 |
|---|---|
INFO |
查看服务器状态信息 |
SELECT <db> |
切换数据库(0-15) |
KEYS * |
查看所有 key(生产环境慎用!) |
DBSIZE |
当前库 key 数量 |
FLUSHDB |
清空当前库 |
FLUSHALL |
清空所有库 |
SHUTDOWN |
关闭 Redis 服务 |
CONFIG GET/SET |
动态修改配置 |
SLOWLOG GET/LEN/RESET |
慢查询日志 |
13. 安装(CentOS 7 源码安装)
bash
# 安装依赖
yum install tcl gcc gcc-c++ -y
# 解压
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 &
# 客户端连接
redis-cli
14. 配置文件核心参数
| 参数 | 说明 |
|---|---|
bind 127.0.0.1 |
监听地址,远程访问需改为 0.0.0.0 |
port 6379 |
监听端口 |
daemonize no |
是否守护进程 |
databases 16 |
逻辑数据库数量 |
save 900 1 |
RDB 触发条件 |
appendonly no |
是否开启 AOF |
appendfsync everysec |
AOF 同步策略 |
requirepass foobared |
访问密码 |
maxclients 10000 |
最大客户端连接数 |
15. 消息队列实现
生产者/消费者模式(List)
LPUSH+RPOP或RPUSH+LPOP- 阻塞式:
BRPOP/BLPOP
发布者/订阅者模式(Pub/Sub)
SUBSCRIBE channel订阅频道PUBLISH channel message发布消息
16. Python 连接 Redis 示例
python
import redis
r = redis.Redis(host='192.168.108.172', port=6379, password='123456', db=0)
# 字符串操作
r.set('color1', 'red')
value = r.get('color1')
print(value)
# 列表操作
r.lpush('mylist', 'nihao')
r.lpush('mylist', 'laogao')
print(r.lrange('mylist', 0, -1))
# 哈希操作
r.hset('student', 'name', 'lisi')
r.hset('student', 'age', '18')
print(r.hgetall('student'))
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐
所有评论(0)