Redis:我们如何应对内存满的状况

admin
4
2025-07-23

🔥1、简述

在高并发、高性能应用场景中,Redis 以其极快的读写性能被广泛使用。然而,Redis 是内存数据库——当内存被占满时,会发生什么?我们该如何应对?

本篇文章将围绕以下几个核心点展开:

  • Redis 内存满的表现与风险
  • 内存淘汰策略原理
  • 实践配置与使用示例
  • 应对建议与优化方案

image-nrad.png


📚 2、内存满了会发生什么?

当 Redis 达到或超过配置的最大内存限制(maxmemory),并且当前策略无法释放空间时:

  • 写入操作会失败,返回错误:

    (error) OOM command not allowed when used memory > 'maxmemory'
    
  • 读取操作仍然可以正常进行。

  • Redis 不会崩溃,但性能和业务可能会受到严重影响。


🎯 3、内存管理机制

Redis 通过以下配置参数控制内存行为:

3.1 maxmemory

设置 Redis 使用的最大内存上限(单位支持 KB/MB/GB):

maxmemory 512mb

可以通过命令行动态设置:

CONFIG SET maxmemory 512mb

注意:默认没有限制,即最大使用服务器全部可用内存。

3.2 maxmemory-policy —— 淘汰策略

当内存满了,Redis 会根据设置的淘汰策略尝试释放空间:

策略名 描述
noeviction (默认) 不淘汰,写入失败
allkeys-lru 所有键中,淘汰最少使用的
volatile-lru 仅对设置了 TTL 的键使用 LRU
allkeys-random 所有键中,随机淘汰
volatile-random 仅 TTL 键中随机淘汰
volatile-ttl 仅 TTL 键中,淘汰即将过期的键
allkeys-lfu 所有键中,淘汰最少使用频率的(>= 4.0)
volatile-lfu 仅 TTL 键中淘汰最少频率的

设置方式:

CONFIG SET maxmemory-policy allkeys-lru

✂️ 4、实践样例:模拟内存占满

4.1 环境准备

docker run -d --name redis-test -p 6379:6379 redis --maxmemory 100mb --maxmemory-policy allkeys-lru

4.2 快速写入大数据

public void fillRedis(RedisTemplate<String, String> redisTemplate) {
    for (int i = 0; i < 1_000_000; i++) {
        redisTemplate.opsForValue().set("key" + i, "value" + i);
    }
}

4.3 执行后观察:

used_memory_human:100.00M
evicted_keys: 1000+

说明:Redis 会自动淘汰旧键,保证新数据写入成功(因我们设置了 allkeys-lru 策略)。


🔒 5、如何避免内存用尽带来的问题?

✅ 5.1 设置合理的 maxmemory 限制

maxmemory 1gb

确保 Redis 不会把系统内存全部吃完。

✅ 5.2 开启 TTL 和淘汰策略

  • 给所有非永久缓存设置过期时间:
redisTemplate.opsForValue().set("user:123", "data", 1, TimeUnit.HOURS);
  • 配置策略:
maxmemory-policy volatile-lru

只对有 TTL 的数据进行淘汰。

✅ 5.3 使用 MEMORY DOCTOR 诊断

Redis 4.0+ 支持:

MEMORY DOCTOR

会输出内存异常使用的诊断建议。

✅ 5.4 设置 maxmemory-samples

CONFIG SET maxmemory-samples 10

提高 LRU 采样精度(默认为 5)。

✅ 5.5 监控与报警

使用 Prometheus + Grafana、Redis Exporter 监控:

  • 内存使用率
  • 命中率
  • 淘汰键数量
  • OOM 错误计数

✅ 5.6 高级优化建议

问题 优化建议
热点键过多 使用 Redis Cluster 分片存储
大 key 占用内存 拆分大 key 或使用压缩结构(如 ziplist)
数据过期不均 加入随机 TTL 偏移
历史数据无法淘汰 增加缓存分类,按业务类型控制 TTL

🔚 6、总结

Redis 是内存数据库,内存是生命线。了解 Redis 内存用尽时的行为,有助于我们设计更稳定的缓存架构。

状态 行为 是否可恢复
未设置 maxmemory,内存无限增长 可能导致机器 OOM、Redis 宕机
设置了 maxmemory + 淘汰策略 自动淘汰旧数据,性能降低
设置了 maxmemory,无淘汰策略 写入失败、抛出 OOM 错误

实际项目中:

  • 缓存需有明确生命周期(TTL)
  • 使用合适的淘汰策略
  • 限制最大内存
  • 建立内存监控体系

做好这些准备,你的 Redis 服务才能稳如磐石。

动物装饰