Skip to content

Redis-内存淘汰策略

Redis作为内存数据库,当内存使用达到maxmemory限制时,会根据配置的淘汰策略自动移除部分键值对。以下是Redis支持的8种内存淘汰策略及其适用场景:

淘汰策略分类

不淘汰策略

  • noeviction(默认策略)
    • 特点:达到内存限制时拒绝所有写操作,只允许读操作
    • 适用场景:数据绝对不能丢失的场景,如金融交易系统
    • 风险:可能导致服务不可用,需配合监控告警

全局随机淘汰

  • allkeys-random
    • 特点:从所有键中随机选择淘汰
    • 适用场景:所有键价值均等的场景
    • 示例:CONFIG SET maxmemory-policy allkeys-random

最近最少使用淘汰

  • allkeys-lru
    • 特点:基于近似LRU算法淘汰最久未使用的键
    • 实现:随机采样5个键淘汰最久未使用的(可配置采样数)
    • 适用场景:典型缓存场景
    • 调优:maxmemory-samples 10(提高采样精度)

最少频率使用淘汰

  • allkeys-lfu(Redis 4.0+)
    • 特点:淘汰访问频率最低的键
    • 实现:基于Morris计数器实现近似LFU
    • 适用场景:热点数据分布不均匀的场景
    • 调优:lfu-log-factor 10(控制计数器饱和速度)

带过期时间的键淘汰

  • volatile-random

    • 特点:从设置了TTL的键中随机淘汰
    • 适用场景:混合持久数据和缓存数据的场景
  • volatile-lru

    • 特点:从设置了TTL的键中淘汰最久未使用的
    • 适用场景:缓存数据有不同重要性的场景
  • volatile-lfu(Redis 4.0+)

    • 特点:从设置了TTL的键中淘汰访问频率最低的
    • 适用场景:需要精细控制缓存淘汰的场景
  • volatile-ttl

    • 特点:淘汰剩余生存时间最短的键
    • 实现:扫描过期字典快速找到即将过期的键
    • 适用场景:时效性敏感数据的缓存

策略选择指南

策略数据安全性内存利用率实现复杂度适用场景
noeviction简单关键数据存储
allkeys-lru中等通用缓存
allkeys-lfu最高较高热点数据缓存
volatile-ttl简单时效性缓存
allkeys-random简单无差别缓存

配置与监控

关键配置

bash
# 设置最大内存(示例:4GB)
maxmemory 4294967296

# 设置淘汰策略
maxmemory-policy allkeys-lru

# LRU/LFU调优参数
maxmemory-samples 5      # LRU采样数量
lfu-log-factor 10        # LFU计数器对数因子
lfu-decay-time 1         # LFU计数器衰减时间(分钟)

监控指标

bash
# 查看内存使用情况
redis-cli info memory | grep -E "used_memory|maxmemory|evicted_keys"

# 重要指标说明:
# used_memory_human:当前内存使用量
# maxmemory_human:配置的内存上限
# mem_fragmentation_ratio:内存碎片率
# evicted_keys:累计淘汰键数量

优化技巧

混合策略实现

通过Redis模块或客户端实现二级淘汰策略:

  1. 对关键数据设置volatile-ttl
  2. 对普通缓存使用allkeys-lru
  3. 通过OBJECT freq命令手动调整键的LFU计数器

动态策略调整

lua
-- 根据时间段自动切换策略
local hour = tonumber(redis.call('TIME')[1]) % 24
if hour >= 8 and hour < 20 then
    redis.call('CONFIG', 'SET', 'maxmemory-policy', 'allkeys-lru')
else
    redis.call('CONFIG', 'SET', 'maxmemory-policy', 'volatile-ttl')
end

大Key特殊处理

对大对象实施特殊淘汰逻辑:

bash
# 监控大Key
redis-cli --bigkeys

# 对大Key单独设置更短的TTL
redis-cli expire large_key 3600

生产环境建议

  1. 容量规划:预留20%-30%内存缓冲,避免频繁淘汰
  2. 监控告警:设置used_memory超过90%的告警
  3. 压力测试:模拟淘汰场景验证策略效果
  4. 数据预热:重启后主动加载热点数据
  5. 混合持久化:配合AOF/RDB确保数据可恢复