Redis 的内存淘汰策略是当内存使用量达到预设阈值时,通过特定算法选择并删除部分数据以释放空间的核心机制。以下是其常见算法及技术细节的梳理:
一、淘汰策略分类与核心算法
Redis 提供 8 种淘汰策略,按淘汰范围可分为两类:
1. 针对所有键(Allkeys 策略)
-
allkeys-lru(最近最少使用)
- 原理:近似 LRU 算法,通过随机采样(默认 5 个键)比较访问时间戳,淘汰最久未访问的键。
- 特点:平衡性能与精度,采样数越多精度越高(通过
maxmemory-samples
配置)。 - 适用场景:热点数据频繁访问的缓存系统(如 API 响应缓存)。
-
allkeys-lfu(最不经常使用,Redis 4.0+)
- 原理:基于访问频率的 LFU 算法,结合概率计数器(如 Morris 计数器)和时间衰减机制(
lfu-decay-time
参数控制衰减速度)。 - 特点:能精准识别长期热点数据,避免“缓存污染”(如偶尔访问的冷数据)。
- 适用场景:访问频率差异大的场景(如推荐系统缓存)。
- 原理:基于访问频率的 LFU 算法,结合概率计数器(如 Morris 计数器)和时间衰减机制(
-
allkeys-random(随机淘汰)
- 原理:从所有键中随机选择淘汰。
- 特点:实现简单,性能开销低,但可能误删高价值数据。
- 适用场景:数据无明显访问模式或测试环境。
2. 仅针对设置了过期时间的键(Volatile 策略)
-
volatile-lru
- 原理:与
allkeys-lru
类似,但仅淘汰设置了过期时间(TTL)的键。 - 适用场景:混合数据场景(如临时缓存与持久化数据共存)。
- 原理:与
-
volatile-lfu(Redis 4.0+)
- 原理:与
allkeys-lfu
类似,但仅作用于带 TTL 的键。 - 适用场景:关注访问频率的临时数据(如限时活动缓存)。
- 原理:与
-
volatile-ttl
- 原理:淘汰剩余生存时间(TTL)最短的键。
- 特点:基于过期时间排序,逻辑清晰。
- 适用场景:需快速清理即将过期的数据(如会话缓存)。
-
volatile-random
- 原理:从带 TTL 的键中随机淘汰。
- 适用场景:对淘汰顺序无要求的临时数据场景。
3. 特殊策略
- noeviction(默认策略)
- 行为:内存不足时拒绝写入操作(如 SET、LPUSH),返回错误(OOM),但允许读取和删除。
- 适用场景:数据绝对不能丢失的场景(如金融交易记录),需配合监控和降级机制。
二、算法实现细节
-
近似 LRU 优化
- Redis 通过维护一个全局 LRU 时钟(精度 1 秒)减少维护开销,避免严格 LRU 的链表操作。
- 采样策略:默认随机采样 5 个键,通过
maxmemory-samples
参数调整采样数(值越大精度越高,但 CPU 开销增加)。
-
LFU 的概率计数器
- 使用 8 位
logc
字段记录访问频率,结合lfu-log-factor
控制增长难度(值越大,计数器增长越慢)。 - 时间衰减:通过
lfu-decay-time
参数(单位:分钟)模拟访问频率随时间衰减。
- 使用 8 位
-
TTL 优先淘汰
- 维护过期键的最小堆,优先淘汰堆顶元素(即将过期的键),结合定期扫描与惰性删除减少堆维护开销。
三、策略选择建议
场景类型 | 推荐策略 | 理由 |
---|---|---|
纯缓存场景 | allkeys-lru | 保留热点数据,平衡性能与精度 |
访问频率差异大 | allkeys-lfu | 精准识别长期热点,避免缓存污染 |
临时数据(如会话) | volatile-ttl | 快速清理即将过期的数据 |
混合数据(缓存+持久化) | volatile-lru | 保护无 TTL 的键,避免 OOM |
无明显访问模式 | allkeys-random | 实现简单,性能开销低 |
数据绝对不可丢失 | noeviction | 拒绝写入操作,需配合监控和降级机制 |
四、配置与优化实践
-
基础配置
# 设置内存上限(建议为物理内存的 70%-80%) maxmemory 4gb # 选择淘汰策略(推荐 allkeys-lru 或 allkeys-lfu) maxmemory-policy allkeys-lru # 调整 LRU 采样数(提升精度需增加 CPU 开销) maxmemory-samples 10 # LFU 衰减因子(默认 1 分钟) lfu-decay-time 1
-
性能优化
- 大键优化:避免存储超过 10KB 的键,使用
redis-cli --bigkeys
扫描。 - 惰性删除:开启
lazyfree-lazy-eviction yes
异步删除大键。 - 内存碎片:通过
INFO MEMORY
监控mem_fragmentation_ratio
(建议值 < 1.5)。
- 大键优化:避免存储超过 10KB 的键,使用
-
监控指标
- 使用
INFO stats
查看evicted_keys
统计淘汰次数。 - 配置
notify-keyspace-events
监听淘汰事件。
- 使用
五、高级扩展
- 多实例分片:通过 Redis Cluster 提升内存容量。
- 持久化协同:结合 AOF 重写与淘汰策略,避免内存峰值。
- 混合淘汰:通过 Lua 脚本实现自定义淘汰逻辑(如结合业务标签)。
通过合理配置淘汰策略与持续优化,Redis 能在高并发场景下保持卓越的内存管理能力,为业务提供稳定支撑。