1. 问题描述重构
当前遇到一个生产环境紧急故障:一个支撑上万家企业的SaaS平台Redis集群,承担着商品、支付、物流、营销等多个核心服务的数据存储。集群入流量突然被打满(达到4-6GB/s),导致部分服务不可用并报错。急需快速定位:
-
哪个或哪些Key被异常频繁调用(热Key问题)
-
哪个客户端IP在发送大量请求(异常源头)
-
每个客户端的确切入流量数据(精准定位)
2. 排查原理与实战示例
排查原理图

3. 实战命令与示例输出
3.1. 查看实时状态(首要诊断)
命令:
redis-cli -h 192.168.1.100 -p 6379 -a yourpassword --stat
示例输出(异常情况):
------- data ------ --------------------- load -------------------- - child - keys mem clients blocked requests connections 5000000 15.8G 250 0 1850000000(+850000) 250
分析:每秒请求数增加85万(+850000),明显异常。
3.2. 分析客户端连接(定位异常源头)
命令:
redis-cli -h 192.168.1.100 -p 6379 -a yourpassword client list
示例输出(异常模式1:代码BUG):
[root@zb-yunweitest-mysql-204-201 data]# redis-cli -h 172.21.204.201 client list id=53 addr=172.21.204.200:46102 laddr=172.21.204.201:6379 fd=8 name= age=9 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=40954 argv-mem=0 obl=0 oll=1 omem=12582936 tot-mem=12644392 events=rw cmd=get user=default redir=-1 id=54 addr=172.21.204.200:46104 laddr=172.21.204.201:6379 fd=9 name= age=9 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 argv-mem=0 obl=0 oll=1 omem=12582936 tot-mem=12603440 events=rw cmd=get user=default redir=-1 id=55 addr=172.21.204.200:46106 laddr=172.21.204.201:6379 fd=10 name= age=9 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 argv-mem=0 obl=0 oll=1 omem=12582936 tot-mem=12603440 events=rw cmd=get user=default redir=-1 id=56 addr=172.21.204.200:46108 laddr=172.21.204.201:6379 fd=11 name= age=9 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 argv-mem=0 obl=0 oll=1 omem=12582936 tot-mem=12603440 events=rw cmd=get user=default redir=-1 id=57 addr=172.21.204.200:46110 laddr=172.21.204.201:6379 fd=12 name= age=9 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 argv-mem=0 obl=0 oll=1 omem=12582936 tot-mem=12603440 events=rw cmd=get user=default redir=-1 id=58 addr=172.21.204.200:46112 laddr=172.21.204.201:6379 fd=13 name= age=9 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 argv-mem=0 obl=0 oll=1 omem=12582936 tot-mem=12603440 events=rw cmd=get user=default redir=-1 id=59 addr=172.21.204.200:46114 laddr=172.21.204.201:6379 fd=14 name= age=9 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 argv-mem=0 obl=0 oll=1 omem=12582936 tot-mem=12603440 events=rw cmd=get user=default redir=-1 id=60 addr=172.21.204.200:46116 laddr=172.21.204.201:6379 fd=15 name= age=9 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 argv-mem=0 obl=0 oll=1 omem=12582936 tot-mem=12603440 events=rw cmd=get user=default redir=-1 id=61 addr=172.21.204.200:46118 laddr=172.21.204.201:6379 fd=16 name= age=9 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 argv-mem=0 obl=0 oll=1 omem=12582936 tot-mem=12603440 events=rw cmd=get user=default redir=-1 id=62 addr=172.21.204.200:46120 laddr=172.21.204.201:6379 fd=17 name= age=9 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 argv-mem=0 obl=0 oll=1 omem=12582936 tot-mem=12603440 events=rw cmd=get user=default redir=-1 id=64 addr=172.21.204.201:26266 laddr=172.21.204.201:6379 fd=18 name= age=0 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=26 qbuf-free=40928 argv-mem=10 obl=0 oll=0 omem=0 tot-mem=61466 events=r cmd=client user=default redir=-1
(上百个类似连接)
诊断:IP 10.0.1.23 的大量连接idle=0且执行简单ping,表明存在代码BUG或连接池配置错误。
3.3. 客户端入流量统计方法
方法一:使用Redis内置指标(基础估算)
Redis的client list命令提供了每个客户端的输入缓冲区信息:
# 提取客户端输入缓冲区信息
redis-cli client list | awk ' # 1. 解析 client list 输出,提取 IP、omem、tot-mem、argv-mem { # 初始化变量 ip = ""; omem = 0; tot_mem = 0; argv_mem = 0; # 遍历每个字段(格式:key=value) for (i=1; i<=NF; i++) { split($i, kv, "="); # 分割 key 和 value(如 "addr=172.21.204.200:46102" → kv[1]="addr", kv[2]="172.21.204.200:46102") if (kv[1] == "addr") { split(kv[2], addr, ":"); # 提取 IP(去掉端口,如 "172.21.204.200:46102" → addr[1]="172.21.204.200") ip = addr[1]; } else if (kv[1] == "omem") { omem = kv[2]; } else if (kv[1] == "tot-mem") { tot_mem = kv[2]; } else if (kv[1] == "argv-mem") { argv_mem = kv[2]; } } # 按 IP 分组累加(存储为字节) sum_omem[ip] += omem; sum_tot_mem[ip] += tot_mem; sum_argv_mem[ip] += argv_mem; # 统计每个 IP 的连接数 conn_count[ip]++; } # 2. 处理完所有行后,格式化输出结果 END { # 打印表头(左对齐,占20字符) printf "%-20s %-8s %-20s %-20s %-20s\n", "客户端IP", "连接数", "omem总和(MB)", "tot-mem总和(MB)", "argv-mem总和(MB)"; printf "%-20s %-8s %-20s %-20s %-20s\n", "--------", "--------", "------------", "--------------", "--------------"; # 遍历所有 IP,输出统计结果(字节转 MB:除以 1024*1024,保留2位小数) for (ip in sum_omem) { omem_mb = sum_omem[ip] / (1024*1024); tot_mem_mb = sum_tot_mem[ip] / (1024*1024); argv_mem_mb = sum_argv_mem[ip] / (1024*1024); printf "%-20s %-8d %.2f %.2f %.6f\n", ip, conn_count[ip], omem_mb, tot_mem_mb, argv_mem_mb; } } '
示例输出:
客户端IP 连接数 omem总和(MB) tot-mem总和(MB) argv-mem总和(MB) -------- -------- ------------ -------------- -------------- 172.21.204.200 10 108.00 108.20 0.000000 127.0.0.1 1 0.00 0.06 0.000010
分析:显示每个客户端的输入缓冲区大小,可以间接反映流量大小。
方法二:使用系统级网络监控(推荐)
使用iftop工具按IP监控实时网络流量:
# 安装 iftop
sudo apt install iftop
# 监控Redis端口流量,按源IP分组
sudo iftop -P -N -n -i eth0 -f "port 6379" -F 192.168.1.100/32
示例输出:
interface: eth0 IP address: 192.168.1.100 MAC address: 00:1a:2b:3c:4d:5e Listening on Redis port 6379 15:30:01 - 15:30:31 # 30秒流量统计 Source IP => Redis Server Traffic 10.0.1.23 => 192.168.1.100 4.2Mb/s 10.0.5.67 => 192.168.1.100 1.8Mb/s 10.0.3.45 => 192.168.1.100 0.5Mb/s
方法三:使用tcpdump深度分析(精准测量)
# 捕获指定客户端IP的Redis流量
sudo tcpdump -i eth0 -s 0 -w redis_traffic.pcap host 10.0.1.23 and port 6379
# 分析捕获的数据包大小
sudo tcpdump -nn -r redis_traffic.pcap -w - | awk '{print $3}' |
grep '10.0.1.23' |
awk -F. '{print $1"."$2"."$3"."$4}' |
sort | uniq -c | sort -nr
示例输出:
# 显示每个客户端发送的数据包数量 12542 10.0.1.23 3845 10.0.5.67 1298 10.0.3.45
方法四:使用Prometheus+Redis Exporter(长期监控)
如果已部署监控系统,可以配置以下查询:
# 查询各客户端入流量排名
topk(10, rate(redis_net_input_bytes_total{instance="redis-cluster"}[5m]))
3.4. 分析慢查询(识别低效操作)
命令:
redis-cli -h 192.168.1.100 -p 6379 -a yourpassword slowlog get 5
示例输出(大Key问题):
1) 1) (integer) 145787
2) (integer) 1645678901
3) (integer) 12543
4) 1) "HGETALL"
2) "product:inventory:store:002"
5) "10.0.3.45:57218"
诊断:IP 10.0.3.45 执行HGETALL耗时12.5秒,大HashKey导致阻塞。
4. 总结与行动指南
4.1 发现的问题类型
-
代码BUG型:某IP产生大量无效请求(如频繁ping)
-
热Key访问型:单一Key被超高并发访问
-
大Key阻塞型:单个大Value操作耗时过长
-
流量异常型:特定客户端发送过量请求
4.2 立即行动方案
-
精准流量分析:使用
iftop或tcpdump确认10.0.1.23的异常流量 -
紧急重启:重启异常IP(如
10.0.1.23)上的服务 -
临时限流:使用iptables对异常IP进行流量限制
# 限制单个IP的入流量为1Mb/s sudo iptables -A INPUT -p tcp -s 10.0.1.23 --dport 6379 -m limit --limit 1mb/s -j ACCEPT
4.3 长期治理策略
-
实施流量监控:
-
部署Prometheus监控各客户端Redis流量
-
设置客户端级流量告警阈值
-
-
架构优化:
-
为不同服务创建独立的Redis实例
-
实施客户端级速率限制(使用Redis模块或代理中间件)
-
-
流量分析与优化:
# 定期生成客户端流量报告 sudo iftop -t -P -N -n -i eth0 -f "port 6379" -F 192.168.1.100/32 -s 3600 > redis_traffic_report.txt
通过以上系统化的排查和流量统计方法,您不仅可以快速定位Redis流量激增的根本原因,还能精准识别问题客户端并采取有效措施恢复服务稳定性。
posted on
浙公网安备 33010602011771号