凌晨三点的告警:Redis突然吃掉了16GB内存
那天夜里,线上核心业务的Redis实例内存突然从8GB飙升至24GB,触发OOM告警。这个集群平时QPS稳定在3万左右,AOF和RDB都开着,数据量约6GB。重启后内存缓慢增长,但一周后再次爆炸------你有没有遇到过这种"间歇性内存抽风"的情况?
AOF重写的隐藏成本
表面看是内存泄漏,但INFO命令显示aof_rewrite_in_progress:1时内存激增。问题的本质在于Redis的AOF重写机制:
- 子进程的写时复制(COW)陷阱 :AOF重写由
bgrewriteaof触发的子进程完成,理论上不会阻塞主进程。但子进程需要遍历当前DB快照,此时主进程继续处理写请求------你以为COW能完美共享内存?太天真了。 - 大key的死亡拥抱:当主进程修改某个存在的大key(比如10MB的Hash),Linux的COW机制会触发整个key的内存复制。我们的业务恰好在AOF重写期间批量更新了一批商户画像的Hash结构。
bash
# 用以下命令抓出内存暴涨时的罪魁祸首
redis-cli --bigkeys
# 输出示例:
# Biggest string found 'user:ranking' has 12 bytes
# Biggest hash found 'merchant:profile:1089' has 12098342 bytes
从内核视角看内存翻倍
用smem工具抓取Redis进程的PSS(实际物理内存占用),发现:
| 阶段 | 内存(GB) | 备注 |
|---|---|---|
| 正常运行时 | 8.2 | RDB内存快照约7.5GB |
| AOF重写开始后10分钟 | 15.7 | 主进程修改了20个大Hash |
| AOF重写完成时 | 9.1 | 子进程退出后释放复制内存 |
- 关键结论*:COW机制下,子进程持有旧数据页,主进程修改数据会触发新内存分配。如果重写期间频繁改动大key,内存可能短暂膨胀到原数据的2倍!
代码层的两记闷棍
你以为开了AOF就高枕无忧?看看这段错误配置:
conf
# redis.conf 踩坑配置
auto-aof-rewrite-percentage 100 # 默认触发阈值
auto-aof-rewrite-min-size 64mb # 太小!大集群易频繁触发
appendfsync everysec # 生产环境谨慎用always!
- 更糟的是*:某些客户端库在AOF重写期间仍疯狂写入:
java
// 错误写法:无视Redis状态循环写入大对象
public void updateMerchantProfile(long merchantId, Map<String, String> profile) {
jedis.hset("merchant:profile:" + merchantId, profile); // 单个value 10MB+
}
- 正确做法*:至少要做三件事------
java
// 1. 监控AOF重写状态
if (jedis.info("persistence").contains("aof_rewrite_in_progress:1")) {
delayUpdate(queue, profile); // 进入队列延迟处理
}
// 2. 拆分大Hash
public void updateMerchantProfile(long merchantId, String field, String value) {
jedis.hset("merchant:profile:" + merchantId, field, value); // 字段级更新
}
// 3. 限流
RateLimiter rateLimiter = RateLimiter.create(5000); // QPS控制
避坑指南:AOF重写的五个生死劫
- 大key炸弹 :重写前用
redis-cli --bigkeys扫描,拆分超过1MB的key - 频繁触发 :调整
auto-aof-rewrite-min-size到当前内存的5%-10% - 写风暴 :重写期间通过
CLIENT PAUSE暂停非关键写入(Redis 6.2+支持暂停类型) - 磁盘IO雪崩 :避免
appendfsync always与AOF重写同时发生 - 版本差异 :Redis 7.0的Multi Part AOF能缓解此问题,但COW机制依然存在
终极解法:让子弹飞一会儿
现在的方案很暴力但有效:
- 在低峰期通过
BGREWRITEAOF手动触发重写 - 重写期间降级非核心功能
- 彻底重构大key为分片结构
- 血泪总结*:AOF重写不是免费的午餐。当你的Redis内存莫名翻倍时,先看看是不是这个"老实人"在搞事。
你在业务中如何处理AOF重写问题?欢迎聊聊你的实战解法。