3

问题

线上已经运行很久的一个 Redis (阿里云64节点集群版)经常会报 CPU 偏高,经确认后发现只有 13 节点 CPU 偏高,且是其他节点的 3 倍以上,即大部分节点的 CPU 占用率在 20% 到 30%,QPS 大约是 7000,问题节点的 CPU 占用率超过 80%,QPS 是 27000。

排查问题

初次定位

我们首先怀疑是大 key 问题引起的,于是使用 monitor 命令在业务低峰时进行了 monitor,发现某个 类型为 hash 的 key 拆分了100片,每个 hash 的长度大约是 30 万。我们观察了这 100 个 key,在每个节点分布的比较均匀,不应该引起如此严重的偏移问题。

所以结论是该节点的 CPU 偏高不是由于大 key 问题引起的。

再次排查

通过阿里云的 imonitor 命令,我对指定的节点进行了监听,并将结果保存为文本文件进行分析。

用 telnet 命令连接到阿里云的 Redis Server Cluster,在 telnet 中执行

imonitor 13

将结果保存为 redis-13.txt

对结果进行分析

cat redis-13.txt | grep -o -E "1561806\d+" | sort | uniq -c

结果为

phpaAIZhO5d1dcef55d538.png

可以看出该节点的 QPS 大概为 7000 多,远不及监控上的 27000。

因此,我们确定是阿里云的监控上对应的节点和 imonitor 的节点不对应。

发现这个问题后,我们尝试用 iinfo 命令找出来 CPU 比较高的节点。

#遍历每个节点
for i in {0..63}
do
redis-cli -h $host -a iinfo $i CPU
done

通过该方法找到 5 节点的 CPU 显著高于其他节点。

再次使用 imonitor 命令获取该节点的 QPS:

cat redis-5.txt | grep -o -E "1561807\d+" | sort | uniq -c

phpQSsnaP5d1ddab5be176.png

QPS 为 28000 左右,符合监控曲线。

然后我们通过使用 redis-faina 分析 Monitor 的结果。
首先要对结果进行处理,将 imonitor 接收到的每行开头的 "+" 号去掉,执行命令

sed -i "" "s/+//g" redis-5.txt 

然后使用 redis-faina 分析结果,执行命令

python redis-faina.py redis-5.txt 

得出来访问量较高的命令,发现有一个 hget 命令的 key 和 field 明显写反了,且 QPS 很高,正是这个 key 导致了 CPU 和 miss 曲线的升高。

我们在代码库中查找出问题的 key,逐行排查,发现在一个项目中确实存在 key field 写反的情况,于是通知了开发者进行修改。

第二天开发者修改了代码并进行了发布之后,曾经偏高的 CPU 节点稳定如他,问题终于算得到了解决。

结论

  1. imonitor 命令和阿里云后台的监控的节点不一致,导致问题迟迟未被发现(阿里云反馈仅在早期的 Redis 集群中有该现象,新版的 Redis 集群都是对应的)。
  2. 使用 imonitor 和 redis-faina 一起,可以方便地排查 redis 大 key 和热 key。
  3. 具体问题要具体分析,不能解决问题的时候要变通思路,通过各种方法去尝试解决问题。

本文首发于本人博客 记一次解决线上 Redis 集群单节点 CPU 偏高问题,非本人授权请勿转载。


小狗快跑嘟嘟
2.8k 声望19 粉丝

探索,是认识这个世界的唯一方式。