Redis内存数据监控实战( 二 )


Redis内存数据监控实战


在服务器上执行一下该工具,便能够完成一次统计和上报了 。可以把整个过程做成一个脚本,用定时任务每隔1小时跑一次,就基本实现了准实时的内存数据分布的监控,效果图如下:
Redis内存数据监控实战



Redis内存数据监控实战


由图可见,一旦出现某块业务的数据持续上涨的情况,可以很快发现并及时处理 。
二、数据写入流量实时监控
内存数据分布准实时监控可以做到小时级的数据监控,可以分析监控较慢增长的数据,但无法及时监控导短时间内数据量突增的情况 。针对这种情况,采用服务端实时网络抓包、分析报文、统计上报的方案来实现数据写入流量实时监控 。
网络抓包工具有很多,这里采用最常用wireshark 。wireshark不仅可以快速抓包,还拥有强大的过滤器引擎,可以使用过滤器筛选出redis的数据包,排除无关信息的干扰 。在redis服务器上执行以下命令:
/usr/sbin/tshark-i eth0 -n -f 'tcp port 6379' -a duration:10 -t ad -lT fields -Eseparator="," -E quote=n -e ip.src -e tcp.srcport -e ip.dst -etcp.dstport -e data.data -e data.len > /rdis-networkflow-reporter/data.txt此命令是抓取Redis服务的6379端口的报文,持续10秒,将报文中过滤出来源ip、来源端口、目标ip、目标端口、数据内容、报文长度等字段,并输出至一个文本文件 。为什么只抓取10s?因为wireshark在抓取包并导出文本文件的过程会显著提高cpu,特别是在流量很高的情况,会对服务器性能产生影响 。因此,可以根据服务器的实际情况进行持续时间的调整 。需要注意的是,数据内容被转换成了十六进制,后面做统计的时候需要转换成字符串 。
接下来对报文数据内容的解析,解析之前先要简单了解一下Redis的通信协议 。Redis客户端使用RESP(Redis的序列化协议)协议与Redis的服务器端进行通信,在RESP协议中,数据类型取决于第一个字节:
  • 对于简单字符串,第一个字节是“+”
  • 对于错误,第一个字节是“ – ”
  • 对于整数,第一个字节是“:”
  • 对于批量字符串,第一个字节是“$”
  • 对于数组,第一个字节是“*”
  • 协议的不同部分始终以“ ”(CRLF)结尾
因为主要提取报文中的写入命令,而写入命令通常都是至少包含三部分:命令、key、value 。对于协议来讲,这属于一个数组,因此会以*开头,后面跟着一个十进制的数字,该数字是数组中元素的个数 。例如:字符串写入指令set hey helloworld,报文的前缀则是*3 。接下来的命令本身作为一个字符串,报文则以“$”字节开始,后面是组成字符串的字节数(前缀长度),然后是命令本身 。所以set对应的报文就是$3 set 。同理hey helloworld也是字符串,因此,整个命令的报文便是*3 $3 set $3 hey $10 helloworld。
下一步需要整理出哪些命令是要关注的,因为并不是所有的写入操作都值得去统计,比如DEL、INCR等操作就不会增加内存 。这里在统计工具中进行了判断:
Redis内存数据监控实战


最后,在统计工具中对整个文本文件进行逐行解析,统计写入操作的来源ip、来源端口、key的前缀以及写入数据的大小,并上报至监控预警平台 。把整个过程做成脚本,配上定时任务,即可实现数据写入流量实时监控,效果图如下:
一旦出现写入流量突增,既可以立即定位到key的前缀,方便清理数据,还可以根据来源ip和端口定位到具体的应用进程,从根源上阻止异常流量 。

推荐阅读