确认是否被oom killer杀死:执行dmesg -t | grep -i "killed process",若输出含redis-server及时间戳,则是内核强制终止;此时redis未设maxmemory或配置过大,导致used_memory_rss超物理内存触发oom。

Redis内存占满导致服务崩溃,别急着重启或删数据——先确认是不是真的“Redis自己吃光了内存”,还是操作系统OOM Killer干的。 很多线上故障表面是Redis崩了,实际是Linux内核看到redis-server进程占用内存太多,直接发SIGKILL把它杀了。这种情况下,redis-cli info memory 根本连不上,日志里也找不到Redis主动报错,只有一句 Killed process xxx (redis-server) 出现在 /var/log/messages 或 dmesg 里。
怎么看是不是被OOM Killer杀掉的
这是最常被跳过的一步,但能帮你省下两小时无效排查:
- 执行
dmesg -T | grep -i "killed process",如果输出里有redis-server和时间戳,基本就是它干的 - 检查系统日志:
journalctl -b | grep -i "out of memory\|oom" - 对比Redis进程崩溃时间和
dmesg中OOM事件时间是否一致(注意时区) - 如果确认是OOM Killer所为,说明Redis没设
maxmemory,或者设了但值太大,超出了物理内存余量
Redis自身内存暴增的快速定位命令
如果Redis还能响应,优先跑这四条命令,顺序不能乱:
Linux 性能分析与调优专家,覆盖 CPU、内存、磁盘 I/O、网络、内核参数、编译优化、容器/K8s。适用场景:系统卡顿/高负载、内存不足/OOM/Swap 高、CPU 异常/iowait 高。
-
redis-cli info memory | grep -E "(used_memory|mem_fragmentation_ratio|used_memory_peak)":看真实内存用量、碎片率(>1.5 就偏高)、峰值内存(判断是否曾冲高后回落) -
redis-cli info clients | grep -E "(connected_clients|client_longest_output_list|client_biggest_input_buf)":重点盯client_longest_output_list,超过 10000 就危险,说明某个客户端缓冲区卡住了大响应 -
redis-cli client list | awk '$4 > 100000000 {print $1,$3,$4,$12}':筛选omem超过 100MB 的连接,$4是 omem 字段,$12是最近命令(比如hgetall、smembers) -
redis-cli memory doctor:Redis 4.0+ 自带诊断,会提示 “high_memory_usage”、“big_value” 或 “many_clients” 等直接线索
clients.normal 占用 11GB 内存怎么处理
这是你贴出的典型现象:clients.normal 消耗远超键值总大小,说明问题不在数据本身,而在客户端连接管理上:
- 默认配置
client-output-buffer-limit normal 0 0 0表示不限制普通客户端输出缓冲区,一旦客户端不读、网络卡、或执行了keys *这类命令,缓冲区就无限涨 - 立刻执行
redis-cli client kill addr <port></port>杀掉omem最高的那个连接,内存通常秒降 - 长期修复必须改配置:在
redis.conf中设client-output-buffer-limit normal 2mb 64kb 60(2MB硬限制 / 64KB软限制 / 超过软限持续60秒就断开) - 检查应用端是否用了长连接但没做连接池复用,或有没有漏掉
close()导致连接堆积
真正麻烦的不是内存涨起来,而是涨得悄无声息——比如某个定时任务每小时跑一次 hgetall big_user_profile,客户端却因异常没消费响应,缓冲区就每天多攒10MB。这类问题不会出现在慢日志里,也不会触发 maxmemory 淘汰,只会等某天 omem 突破临界点,把整个实例拖垮。










