Redis 配置与优化全攻略
前言
1. 关系型数据库 vs 非关系型数据库
关系型数据库(SQL)
非关系型数据库(NoSQL)
2. Redis 简介
3. Redis 安装与部署
4. Redis 常用命令
5. Redis 高可用
6. 持久化机制
6.1 RDB 持久化
① 原理
② 触发条件
③ 执行流程
④ 启动加载
⑤ 优缺点
6.2 AOF 持久化
① 原理
② 开启 AOF
③ 执行流程
④ 启动加载
⑤ 优缺点
6.3 对比总结
7. 性能管理与优化
内存指标与碎片率
优化建议
内存淘汰策略
8. 常见缓存问题与解决方案
8.1 缓存穿透
8.2 缓存击穿
8.3 缓存雪崩
8.4 综合实践建议
结语
前言
Redis 是目前使用最广泛的高性能内存数据库之一。本文从基础概念到安装部署、常用命令、高可用、持久化机制,再到性能优化,一文带你全面掌握 Redis。
1. 关系型数据库 vs 非关系型数据库
关系型数据库(SQL)
-
特点:表格模型(行+列)、使用 SQL 语言、强事务 ACID、纵向扩展(升级硬件)。
-
常见产品:MySQL、Oracle、PostgreSQL。
-
场景示例:银行转账,必须保证两边同时成功,事务性要求强。
非关系型数据库(NoSQL)
-
特点:键值对/文档/图结构存储、无需固定表结构、高并发、高可扩展、横向扩展(增加节点)。
-
常见产品:Redis、MongoDB、HBase、Memcached。
-
场景示例:微信聊天,一条消息可能是文字、图片、语音,不适合表格存储,更适合用文档型数据库。
2. Redis 简介
-
定义:开源、C 语言编写、基于内存、支持持久化的键值数据库。
-
优势:
-
高性能:读取可达 11 万次/s,写入 8 万次/s。
-
支持多种数据结构:String、List、Hash、Set、Sorted Set。
-
支持持久化:RDB、AOF。
-
主从复制,方便数据备份。
-
-
为什么快?
-
纯内存操作,避免磁盘 IO。
-
单线程,避免锁开销。
-
I/O 多路复用,高并发。
-
应用示例:
-
秒杀库存扣减、订单写入放在 Redis,减轻数据库压力。
-
抖音热搜榜:用 Sorted Set 存储关键词和热度,实时排序。
3. Redis 安装与部署
-
停防火墙、关闭 SELinux。
-
安装依赖:
yum install -y gcc gcc-c++ make
。 -
下载并解压 Redis 源码,执行
make && make PREFIX=/usr/local/redis install
。 -
使用
cd utils/install_server.sh
配置服务,按提示输入路径。 -
建立软链接
ln -s /usr/local/redis/bin/* /usr/local/bin/
方便全局使用。 -
常用控制命令:
/etc/init.d/redis_6379 start|stop|restart|status
-
修改
/etc/redis/6379.conf
:-
bind 127.0.0.1 192.168.x.x
:监听地址。 -
port 6379
:默认端口。 -
daemonize yes
:守护进程。 -
logfile /var/log/redis_6379.log
:日志文件。
-
4. Redis 常用命令
-
客户端工具:
-
redis-cli -h host -p port -a password
-
-
压力测试:
-
redis-benchmark -c 100 -n 100000
-
-
数据操作:
set key value get key exists key del key keys pattern rename oldkey newkey
-
多数据库:
-
默认 0~15 共 16 个库。
-
select n
切换库,move key n
移动数据。 -
flushdb
清空当前库,flushall
清空所有库(慎用)。
-
5. Redis 高可用
-
持久化:RDB/AOF 将内存数据保存到磁盘,防止进程退出后丢失。
-
主从复制:一主多从,主写从读,实现负载均衡。
-
哨兵(Sentinel):主机宕机自动切换到从机。
-
集群(Cluster):多节点分片存储,解决单机容量限制和写入瓶颈。
6. 持久化机制
6.1 RDB 持久化
① 原理
RDB 是将 Redis 某一时刻的内存数据快照(Snapshot)保存到磁盘的二进制文件 dump.rdb
中。 Redis 通过 fork
一个子进程把内存数据写入临时 RDB 文件,完成后再替换旧文件。
② 触发条件
-
手动触发:
-
save
:阻塞主进程直到完成,不推荐在线上使用。 -
bgsave
:fork
子进程执行保存,主进程继续处理请求(推荐)。
-
-
自动触发: 在
redis.conf
里通过save m n
配置:save 900 1 save 300 10 save 60 10000
-
其他触发:
-
从节点全量复制时,主节点会自动执行
bgsave
。 -
执行
shutdown
时如果没开启 AOF,会自动做一次 RDB。
-
③ 执行流程
-
主进程检查是否已有持久化子进程在运行,若有则直接返回。
-
fork
子进程(此过程主进程短暂阻塞)。 -
子进程把内存数据写入临时 RDB 文件。
-
写完后原子替换旧文件,发送完成信号给主进程。
-
主进程更新状态。
④ 启动加载
Redis 启动时若开启 AOF 优先加载 AOF,否则加载 RDB 文件。载入期间 Redis 会阻塞直至完成。
⑤ 优缺点
-
优点:文件紧凑、体积小、适合全量备份和传输;恢复速度快;对性能影响小。
-
缺点:无法做到实时持久化,可能丢失几分钟数据;
fork
阻塞和磁盘 IO 压力。
6.2 AOF 持久化
① 原理
AOF(Append Only File)是把 Redis 执行过的写/删除命令按 Redis 协议格式追加到日志文件中。重启时 Redis 重新执行 AOF 文件中的命令恢复数据。查询类命令不会写入 AOF。
② 开启 AOF
默认关闭,需要在 redis.conf
开启:
appendonly yes appendfilename "appendonly.aof" appendfsync everysec
③ 执行流程
-
命令追加 (append):Redis 先将命令追加到 AOF 缓冲区
aof_buf
。 -
文件写入/同步 (write & fsync):
-
appendfsync always
:每条命令都 fsync,同步最安全但最慢。 -
appendfsync no
:仅 write,由 OS 决定何时刷盘,不安全但最快。 -
appendfsync everysec
:每秒 fsync 一次(默认,性能与安全折中)。
-
-
文件重写 (rewrite):
-
AOF 文件越来越大时 Redis 通过
BGREWRITEAOF
重写文件。 -
重写并不是读取旧 AOF,而是把当前内存状态重新生成最少命令集写入新文件。
-
过期数据、无效命令不写入;多条命令可合并成一条,大幅压缩文件。
-
触发:
-
手动:
bgrewriteaof
。 -
自动:满足
auto-aof-rewrite-min-size
和auto-aof-rewrite-percentage
。
-
-
-
重写期间缓冲:Redis 把新写命令同时追加到旧缓冲区和
aof_rewrite_buf
,确保新文件与当前状态一致。
④ 启动加载
Redis 启动时若 AOF 开启则优先加载 AOF;AOF 文件不存在时才加载 RDB。 若 AOF 文件尾部不完整(如宕机),且 aof-load-truncated yes
,则忽略尾部继续启动。
⑤ 优缺点
-
优点:实时性更好(秒级持久化)、可读性强、兼容性好。
-
缺点:文件大、恢复速度慢、写磁盘频率高对性能影响更大,重写过程也有 fork 阻塞与 IO 压力。
6.3 对比总结
特性 | RDB | AOF |
---|---|---|
持久化方式 | 周期性快照 | 逐条命令日志 |
文件大小 | 小 | 大 |
恢复速度 | 快 | 慢 |
数据安全 | 可能丢几分钟 | 丢失不超过 1 秒(默认) |
性能影响 | 小 | 大 |
实践建议:
-
对数据安全要求不高:仅 RDB。
-
对实时性要求高:开启 AOF(默认 everysec)+定期 RDB 做全量备份。
-
Redis 4.0 以后支持混合持久化,结合两者优点。
7. 性能管理与优化
内存指标与碎片率
-
used_memory
:实际用来存储数据的内存。 -
used_memory_rss
:进程占用的物理内存。 -
内存碎片率 =
used_memory_rss / used_memory
:-
≈1:正常。
-
1.5:碎片较高,低峰期重启 Redis 释放碎片。
-
<1:内存不足可能触发 swap。
-
查看命令:
redis-cli info memory
优化建议
-
合理规划实例内存(单实例不超过物理内存 70%~80%)。
-
多用 Hash 结构存储减少碎片。
-
给 Key 设置过期时间:
set session:123 abcdef EX 3600
-
设置最大内存与淘汰策略:
maxmemory 2gb maxmemory-policy allkeys-lru
-
关闭或限制 swap。
内存淘汰策略
当数据量超过 maxmemory
时,Redis 按策略回收空间:
策略 | 描述 |
---|---|
volatile-lru | 从有 TTL 的 Key 中淘汰最少使用的 |
volatile-ttl | 从有 TTL 的 Key 中淘汰最快过期的 |
volatile-random | 从有 TTL 的 Key 中随机淘汰 |
allkeys-lru | 从所有 Key 中淘汰最少使用的(最常用) |
allkeys-random | 从所有 Key 中随机淘汰 |
noeviction | 不淘汰,内存不足时报错 |
实践建议:
-
缓存场景:
allkeys-lru
。 -
需要保留核心数据但允许部分丢失:
volatile-lru
。 -
严格要求数据不丢失:
noeviction
。
8. 常见缓存问题与解决方案
8.1 缓存穿透
现象:请求的 Key 在缓存和数据库都不存在,大量请求直达数据库,造成压力。 原因:恶意攻击或查询不存在数据。
解决方案:
-
缓存空值:把不存在的数据也缓存一份空对象并设置较短 TTL。
-
布隆过滤器(Bloom Filter):在缓存前加过滤器,请求 Key 不在过滤器中直接返回空,减少 DB 查询。
-
参数校验:对明显非法参数直接拦截。
8.2 缓存击穿
现象:某个热点 Key 正好过期瞬间,大量请求同时穿透到数据库。 原因:缓存数据过期瞬间并发请求落到 DB。
解决方案:
-
热点数据不过期:为热点 Key 设置长 TTL 或永不过期。
-
加互斥锁(Mutex):第一个请求获得锁去 DB,其余请求等待。
-
预加载/异步刷新:在数据快过期前提前刷新缓存。
-
过期时间随机化:在 TTL 上加随机值避免集中过期。
8.3 缓存雪崩
现象:大量缓存同时失效或 Redis 宕机,所有请求涌入数据库。 原因:集中过期、缓存不可用、没有熔断限流。
解决方案:
-
过期时间分散:设置 TTL 时加上随机数,避免同一时刻大面积过期。
-
双缓存机制:在缓存失效前提前准备备用缓存,主缓存宕机时快速切换。
-
限流与熔断:在应用层限制请求速率,避免瞬时打爆数据库。
-
Redis 高可用:主从+哨兵或集群,减少缓存整体不可用风险。
8.4 综合实践建议
-
穿透 → 布隆过滤器 + 缓存空值。
-
击穿 → 热点 Key 不过期 + 加锁或提前刷新。
-
雪崩 → TTL 随机 + 限流熔断 + 高可用部署。
结语
掌握 Redis 的 RDB/AOF 持久化原理、缓存问题与解决方案,不仅能保证数据安全,也能让你的系统在高并发场景下稳定运行。