🔥1、简述
在高并发、高性能应用场景中,Redis 以其极快的读写性能被广泛使用。然而,Redis 是内存数据库——当内存被占满时,会发生什么?我们该如何应对?
本篇文章将围绕以下几个核心点展开:
- Redis 内存满的表现与风险
- 内存淘汰策略原理
- 实践配置与使用示例
- 应对建议与优化方案
📚 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 服务才能稳如磐石。