Redis 淘汰策略、持久化与高可用
Redis 淘汰策略、持久化与高可用
一、淘汰策略
Redis 作为内存数据库,所有数据存储在内存中。当内存使用达到上限(maxmemory)时,Redis 需要根据配置的策略淘汰部分数据,以容纳新写入的数据。
1. 淘汰策略触发时机
- 内存使用达到
maxmemory限制,且客户端发起新写入操作(如SET、LPUSH等)。 - 淘汰只在写操作时触发,读操作不会淘汰数据。
2. RedisObject 与 LRU/LFU 字段
每个键值对由 redisObject 结构管理,其中包含一个 24 位的 lru 字段:
- LRU 模式:存储最后一次访问的时间戳(秒级),精度约为 194 天。
- LFU 模式:分为 16 位“最后一次访问时间”和 8 位“访问频次计数器”。
通过 OBJECT IDLETIME key 可以查看键的空闲时间(秒),该命令会更新 lru 字段(为了准确返回空闲时间,会临时更新)。
3. 淘汰策略类型
Redis 提供八种淘汰策略(通过 maxmemory-policy 配置):
| 策略 | 说明 | 适用场景 |
|---|---|---|
noeviction |
默认策略,内存满时写入报错 | 不允许任何数据丢失的场景 |
allkeys-lru |
从所有键中淘汰最近最少使用的 | 通用缓存,适合大部分场景 |
volatile-lru |
从设置了过期时间的键中淘汰最近最少使用的 | 要求缓存数据有明确过期时间 |
allkeys-lfu |
从所有键中淘汰最不经常使用的 | 访问频率差异明显的场景 |
volatile-lfu |
从设置了过期时间的键中淘汰最不经常使用的 | 同上,且要求数据带过期时间 |
allkeys-random |
随机淘汰所有键 | 对访问模式无要求,可快速释放内存 |
volatile-random |
随机淘汰设置了过期时间的键 | 同上 |
volatile-ttl |
淘汰剩余生存时间(TTL)最短的键 | 优先淘汰即将过期的数据 |
注意:
volatile-*策略仅作用于带过期时间的键,如果没有任何带过期时间的键,则退化为noeviction。- 采样机制:每次淘汰时,从
maxmemory-samples(默认 5)个候选键中选出最符合策略的键淘汰,避免全量扫描,平衡性能与准确性。
4. LRU vs LFU
- LRU(Least Recently Used):基于“最近使用时间”,使用 24 位时间戳记录最后一次访问。
- LFU(Least Frequently Used):基于“访问频率”,使用 8 位计数器动态增长,但会随时间衰减,避免冷数据长期占据内存。
通过 redis.conf 配置:
maxmemory 4gb
maxmemory-policy allkeys-lru
maxmemory-samples 10
5. 过期键的删除策略
淘汰策略解决的是内存满的问题,而过期键删除解决的是键到期后自动删除的问题。Redis 采用两种方式:
- 惰性删除:当客户端访问一个已过期的键时,发现过期立即删除并返回空。
- 定期删除:后台任务每秒执行多次,从设置了过期时间的键中随机抽样检查,删除其中过期的键。
这两种方式结合,既保证 CPU 友好,又避免大量过期键长期占用内存。
二、持久化
Redis 提供 RDB 和 AOF 两种持久化机制,用于在服务器重启时恢复数据。
1. RDB(Redis Database)
RDB 是内存快照,将某个时间点的数据以二进制形式保存到磁盘。
工作原理
- 主进程
fork出一个子进程。 - 子进程将当前内存数据写入临时 RDB 文件。
- 写入完成后,用临时文件替换旧文件。
由于 fork 采用写时复制(COW),子进程与父进程共享物理内存,仅在父进程修改数据时才会复制被修改的页,因此 RDB 对内存的影响较小。
触发方式
- 手动:
SAVE(阻塞)或BGSAVE(后台)。 - 自动:根据
save配置(如save 900 1表示 900 秒内至少有 1 次修改则自动执行BGSAVE)。
优缺点
| 优点 | 缺点 |
|---|---|
| 文件紧凑,恢复速度快 | 可能丢失最后一次快照后的数据 |
| 适合备份,可异地存储 | 频繁 fork 可能影响性能 |
2. AOF(Append Only File)
AOF 记录所有写操作的 Redis 协议文本,重启时重放这些命令来恢复数据。
刷盘策略
通过 appendfsync 配置:
always:每次写入都同步到磁盘,最安全,但性能最差。everysec:每秒异步同步一次,折中方案(默认)。no:由操作系统决定,性能最好,但可能丢失更多数据。
AOF 重写(Rewrite)
由于 AOF 文件会不断增长,且包含冗余命令(如对同一键多次 SET),Redis 通过 BGREWRITEAOF 生成一个最小化的 AOF 文件,原理与 RDB 类似:fork 子进程读取内存数据,直接转换为命令写入新 AOF 文件,期间父进程的写操作记录到重写缓冲区,重写完成后追加到新文件。
优缺点
| 优点 | 缺点 |
|---|---|
| 数据安全性高,可做到秒级丢失 | 文件体积大,恢复速度慢 |
| 可读性好,易于修复 | 对磁盘 I/O 压力大 |
3. 混合持久化(Redis 4.0+)
结合 RDB 和 AOF 的优点:AOF 重写时,将 RDB 快照(二进制)作为文件开头,后续增量命令以 AOF 格式追加。这样重启时先加载 RDB 部分(快),再重放增量 AOF 命令,兼顾安全性与恢复速度。
配置:
aof-use-rdb-preamble yes
4. 大键对持久化的影响
- RDB:大键会使
fork复制的页表变大,增加fork耗时;写时复制时,若大键被修改,会复制整个大键内存页,造成内存短暂翻倍。 - AOF:大键的写入会产生大量协议文本,增加文件体积;刷盘时可能阻塞主线程(尤其在
always策略下)。
建议:避免使用大键,可通过拆分或使用合适的数据结构(如 Hash 分段)优化。
三、高可用方案
1. 主从复制
主从复制是 Redis 高可用的基础,实现数据冗余备份。
复制原理
- 从节点向主节点发送
REPLICAOF <master_ip> <master_port>命令(或启动时配置replicaof)。 - 主节点收到命令后,启动后台子进程生成 RDB 快照,并发送给从节点。
- 从节点清空自身数据,加载 RDB。
- 主节点将复制期间收到的写命令缓存在环形缓冲区中,从节点加载完 RDB 后,主节点将缓冲区的命令增量发送给从节点。
- 后续主节点异步将写命令同步给从节点。
复制偏移量与环形缓冲区
- 主节点维护一个复制偏移量,每次发送数据时偏移量增加。
- 每个从节点也记录自己的偏移量。
- 主节点使用一个固定大小的环形缓冲区存储最近发送的命令。如果从节点断线重连后,其偏移量仍在缓冲区内,则进行增量同步;否则触发全量同步。
优缺点
| 优点 | 缺点 |
|---|---|
| 实现简单,支持读写分离 | 无自动故障转移 |
| 异步复制,主节点性能高 | 可能丢失少量数据 |
2. 哨兵模式(Sentinel)
哨兵模式在主从复制基础上增加了自动故障转移能力。
架构
- 哨兵节点(通常部署奇数个)监控主从节点状态。
- 当多数哨兵确认主节点不可用时,选举出一个新主节点,并修改配置,通知客户端。
关键概念
- 主观下线:单个哨兵实例与主节点连接超时。
- 客观下线:超过
quorum个哨兵确认主观下线,触发故障转移。
故障转移流程
- 哨兵集群选举一个 Leader(基于 Raft 协议)。
- Leader 从从节点中选出一个数据最新的(复制偏移量最大)作为新主节点。
- 将其他从节点指向新主节点。
- 通过发布订阅机制通知客户端更新主节点地址。
缺点
- 故障转移期间服务不可用(通常 10-30 秒)。
- 配置复杂,不适合超大规模集群。
3. Redis 集群(Redis Cluster)
Redis Cluster 提供数据分片和高可用的一体化方案,支持横向扩展。
核心特性
- 去中心化:所有节点对等,无中心代理。
- 数据分片:将 16384 个哈希槽分配给多个主节点。
- 高可用:每个主节点可配备多个从节点,主节点故障时从节点自动提升为主节点。
数据分布
- 键通过
CRC16(key) % 16384确定属于哪个槽。 - 槽由主节点管理,客户端通过
MOVED或ASK重定向访问正确节点。 - 支持动态添加/删除节点,通过重新分片迁移槽。
客户端连接
- 客户端需要支持集群协议(如
hiredis-cluster)。 - 连接任一节点,获取槽位映射表,之后根据键计算槽位直接访问对应节点。
故障转移
- 采用故障检测:节点间通过
Gossip协议交换状态,半数以上节点认为某主节点不可达,则标记为FAIL,并从其从节点中选举新主节点(基于复制偏移量优先)。
配置示例
创建集群(6 个节点,3 主 3 从):
redis-cli --cluster create 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 \
127.0.0.1:7004 127.0.0.1:7005 127.0.0.1:7006 --cluster-replicas 1
优缺点
| 优点 | 缺点 |
|---|---|
| 支持海量数据(可线性扩展) | 部署运维复杂 |
| 自动故障转移 | 跨槽操作(如多键事务)受限 |
| 无中心节点,性能高 | 客户端需支持集群协议 |

浙公网安备 33010602011771号