redis的info命令几乎是每个运维和后端开发都会用到的工具,它能在不安装任何额外客户端的情况下,把实例内部的状态一次性吐出来。但正因为信息量大,不少人在实际排查时只看used_memory这一项,错过了很多更早暴露异常的信号。这篇文章按模块逐段拆解info的输出,告诉你哪些字段必须重点关注、异常时该怎么判断原因,以及如何把这些指标落地成日常监控。

INFO命令的基本用法和返回结构
info命令支持整体执行,也支持按模块单独执行。整体执行时直接输入info即可,返回内容按#号开头的注释行分成多个section,比如Server、Clients、Memory、Persistence、Stats、Replication、CPU、Keyspace等。如果你只关心某一块,可以用info memory、info stats、info replication这样的形式精确获取,减少不必要的数据传输,在网络抖动或者实例压力较大时这个细节很有用。
需要特别说明的是,info的输出并不是一次数据库查询,而是直接读取服务端内部维护的计数器和状态变量,所以执行代价极低,即使实例每秒承受十几万请求,执行info也不会造成明显压力。你可以放心在高频监控中使用它,比如每5秒采集一次,配合脚本写入时序数据库做趋势分析。
从Redis 7开始,还支持INFO EVERYTHING查看所有模块,以及通过INFO SECTION的形式查看errorstat等新增模块。不同大版本之间字段有差异,做监控采集时最好先确认目标版本支持的字段,避免脚本解析报错。
Memory模块:内存指标是重中之重
Memory模块里最核心的是三个字段:used_memory表示分配器分配的总内存(包含数据、缓冲区、元数据),used_memory_rss表示操作系统视角下进程占用的物理内存,used_memory_peak则是历史峰值。很多人只看used_memory,其实真正反映健康度的是used_memory和rss的比值,也就是mem_fragmentation_ratio。这个比值在1.0到1.5之间属于正常;小于1说明rss比逻辑内存还小,通常意味着发生了swap,此时会伴随明显的延迟抖动,是最危险的信号;大于1.5则说明碎片率高,可能是频繁的写入删除导致分配器无法归还内存。
碎片率过高时不要急着重启,可以先看看是否配置了maxmemory并启用了淘汰策略。Redis 4以上提供了主动碎片整理功能,通过activedefrag yes开启(需要编译时引入jemalloc支持),开启后碎片率通常会缓慢回落。如果实例内存确实不足,rss接近甚至超过机器物理内存,那就要考虑扩容或者拆分实例,否则swap一旦发生,延迟会从亚毫秒直接劣化到几十毫秒。
另外maxmemory和maxmemory_policy这两个字段也要纳入监控,一旦运行期间被人改动过淘汰策略,行为可能和预期完全不同。配合evicted_keys(Stats模块里)可以判断是否已经因为内存不足开始驱逐key,如果这个计数持续增长而业务没有感知,说明容量规划已经落后了。
Stats模块:连接与吞吐的关键信号
Stats模块是判断实例是否过载的主要依据。instantaneous_ops_per_sec是最近一秒的命令执行数,反映实时吞吐;total_commands_processed是累计值,两个相减可以得到任意时间段的QPS。连接方面重点看rejected_connections,这个计数器一旦大于零,说明达到了maxclients上限,有客户端被拒绝。偶发的一次可能是短连接风暴,持续增长则要检查是否连接泄漏或者需要调大maxclients并相应调整操作系统的文件描述符限制。
keys相关的命中率指标也很重要:keyspace_hits和keyspace_misses的比值就是缓存命中率。如果命中率从99%慢慢掉到90%以下,可能是key过期策略变了、热数据规模增长,或者出现了大量不存在的key查询(缓存穿透)。结合expired_keys和evicted_keys一起看,能大致定位是哪一种情况。
网络和慢查询相关可以关注total_net_input_bytes、total_net_output_bytes,输出流量远大于输入流量时通常是bigkey被频繁整取。如果还开启了latency monitor,配合latest_fork_usec可以判断持久化fork是否造成停顿:这个值是最近一次fork耗费的微秒数,实例越大这个值越高,如果达到几百毫秒,说明RDB触发的卡顿可能是延迟尖刺的元凶。
Replication与持久化模块:数据安全的最后防线
Replication模块在主从架构下必须监控。master_link_status为up表示复制正常,down则要立刻排查网络或主库状态;master_repl_offset和slave_repl_offset的差值是复制延迟,差值持续增大说明从库追不上,可能是网络带宽不足或者从库负载过高。作为主库时,关注connected_slaves的数量是否符合预期,以及每个从库的offset列表。
Persistence模块重点看两个标志位:rdb_last_bgsave_status和aof_last_write_status。任何一个不是ok都意味着持久化出了问题,比如磁盘写满、权限变更等。这类故障平时不影响读写,业务无感知,但一旦重启数据就会大量丢失,所以必须配置告警。同时观察rdb_last_bgsave_time_sec和rdb_current_bgsave_time_sec,如果bgsave耗时越来越长,说明数据集增长已经影响到fork效率,需要提前规划。
把上面这些指标整理成一张采集清单,用脚本每隔几秒执行一次info并写入Prometheus或者时序数据库,设置好阈值告警,就能在问题演变成故障之前发现苗头。常用的告警建议可以参考下表。
| 指标 | 告警阈值建议 | 说明 |
|---|---|---|
| mem_fragmentation_ratio | >1.5或<1 | 碎片过高或发生swap |
| used_memory | >maxmemory的80% | 接近容量上限 |
| rejected_connections | >0 | 有客户端被拒绝 |
| master_link_status | 不为up | 主从复制中断 |
| rdb_last_bgsave_status | 不为ok | 持久化失败 |
一个简单的采集脚本示例
下面给出一段shell脚本,定时采集核心指标并输出CSV格式,方便接入现有的监控体系。你也可以把它改成直接推送到Prometheus pushgateway的方式。
#!/bin/bash
HOST=127.0.0.1
PORT=6379
PASS=yourpassword
while true; do
TS=$(date +%s)
INFO=$(redis-cli -h $HOST -p $PORT -a $PASS info memory stats replication 2>/dev/null)
MEM=$(echo "$INFO" | grep used_memory: | head -1 | cut -d: -f2 | tr -d '\r')
FRAG=$(echo "$INFO" | grep mem_fragmentation_ratio: | cut -d: -f2 | tr -d '\r')
OPS=$(echo "$INFO" | grep instantaneous_ops_per_sec: | cut -d: -f2 | tr -d '\r')
REJ=$(echo "$INFO" | grep rejected_connections: | cut -d: -f2 | tr -d '\r')
LINK=$(echo "$INFO" | grep master_link_status: | cut -d: -f2 | tr -d '\r')
echo "$TS,$MEM,$FRAG,$OPS,$REJ,$LINK"
sleep 5
done脚本里的字段提取方式比较朴素,胜在依赖少、易理解。如果实例数量多,建议直接使用redis_exporter这类现成组件,它对info各模块做了解析,配合Grafana模板可以省去大量开发工作。无论采用哪种方式,核心思路都是一致的:让info的数据形成时间序列,单点数值的意义远小于趋势变化。比如内存缓慢爬升、命中率逐步下滑、fork耗时逐月增加,这些只有放在时间轴上才能看清,也是容量规划最可靠的依据。