将Redis监控细节添加到Django页面里

Redis的监控一直是重点中的重点,市面上开源的Redis界面监控也不在少数了,但是自己做一个监控页面更加有针对性,而且更加有逼格。我们主要监控redis除了常规的cpu、内存、Key数之外,还有如下几个方面:阻塞客户端数量、使用内存峰值、内存碎片率、缓存命中率、失效KEY、慢日志和连接数。这里挑几个简单的说。

获取连接细节情况

首先先来搞定“获取redis的连接细节”。在django里先做一个model,如下:

1
2
3
4
5
6
7
8
9
class redisconnection(models.Model):
rank = models.CharField(verbose_name='排名',max_length=10)
num = models.CharField(verbose_name='服务器连接数',max_length=50)
ip = models.GenericIPAddressField(verbose_name='服务器内网IP地址')
date = models.DateField(auto_now_add=True)
time = models.TimeField(auto_now_add=False, auto_now=True)

def __unicode__(self):
return self.host

可见我们只是需要排名、具体的IP、当时有多少连接以及当时时间这4个指标而已。

我承认我道行不够,捅咕两个小时也没有研究出来怎么用python2.7去获取redis的连接数细节,于是乎就用shell写了一个简单的脚本。如下:

1
2
3
4
5
6
7
8
9
10
11
#!/bin/bash
#获取当前连接最多的前五个IP地址和数量到Mysql
redis-cli -h redis地址 -p 6379 -a redis密码 client list | awk '{print $2}'| cut -d = -f 2| cut -d : -f 1 | sort | uniq -c | sort -rn |head -5 > clientip.txt
MYSQL="mysql -h数据库地址 -u数据库账号 -p数据库密码 --default-character-set=utf8 -A -N"
cat -n clientip.txt | while read rank num IP
do
echo ${num}
echo ${IP}
sql="insert into databases.table(num,ip,date,time,rank) values('${num}','${IP}',curdate(),now(),'${rank}');"
$MYSQL -e "$sql"
done

这里先简单解释一下:
1.client list是查看redis连接细节的命令,然后通过awk获取第二列,再分别通过“=”和“,”来分割两次,排序去重统计个数最后取出前五名输入到clientip.txt这个文件里;
2.连接mysql,-A的含义是不去预读全部数据表信息;-N的含义是获取数据信息省去列名称;
3.使用cat -n自动获取到行号当做排名,循环赋值;
4.curdate(),now()这俩是sql,但是需要shell里正确使用sql就要-e;

执行效果如下:
akb48

剩下的内容就是在views.py里拿值然后通过render反馈到前端页面,这里不说了。

如果使用了Redis中间件,那么就不能统计redis的client list了,而是到中间件服务器里,使用ss -art | awk '{print $5}' | grep '^[1-9]' | cut -d : -f 1 | sort | uniq -dc | sort -nr获取详细连接情况。

获取缓存命中率

缓存命中率是info Stats命令里keyspace_hits/(keyspace_hits+keyspace_misses)的值,比如我这个redis:
akb48

这个值正常来说应该是90%以上,如果缓存命中率过低,那么要排查对缓存的用法是否有问题,我这个就很不合格…

获取缓存命中率的shell脚本如下:

1
2
3
4
5
6
7
8
9
10
11
#!/bin/bash
#获取当前缓存命中率到Mysql
hit=$(redis-cli -h redis地址 -p 6379 -a redis密码 info Stats | grep "keyspace_hits" | cut -d : -f 2)
miss=$(redis-cli -h redis地址 -p 6379 -a redis密码 info Stats | grep "keyspace_misses" | cut -d : -f 2)
HIT=$(echo $hit | tr -d '\r')
MISS=$(echo $miss | tr -d '\r')
total=$(expr $HIT + $MISS)
percent=$(awk 'BEGIN{printf "%.2f\n",'$HIT'/'$total'}')
MYSQL="mysql -h数据库地址 -u数据库账号 -p数据库密码 --default-character-set=utf8 -A -N"
sql="insert into databases.table(num,date,time) values('${percent}',curdate(),now());"
$MYSQL -e "$sql"

这里要注意!hitmiss结果是自带”\r”的,所以要去掉。不然的话就会有expr: non-numeric argument。而且如果用bc命令获取除法结果的话,低于1的值是不会出现整数0,即如果得到的结果是0.97,那么只会显示.97,至于如何出现这个0,可以去看 http://www.361way.com/linux-bc-point-zero/4960.html

现在已经通过脚本取到了值,那么剩下的内容就是django去弄一个model,之后在views.py里拿值然后通过render反馈到前端页面,这里不说了。执行效果如下:
akb48

其他补充

redis的慢日志操作也是我们比较关注的一点。一般来说我们使用slowlog len来获取当前慢日志的总条数,而是用slowlog reset对其进行清理工作。获取它的shell脚本跟上面两个大同小异,这里也略过不表了。

如果要是想获取redis的cpu和内存,最好的方法通过zabbix拿值,CPU使用率的item是:system.cpu.util[],内存使用率的item是:vm.memory.size[pavailable]

整个页面做完的效果如下:
akb48

参考资料

https://segmentfault.com/a/1190000009915519
https://blog.csdn.net/secretx/article/details/73498148
http://www.cnblogs.com/iforever/p/4459857.html
https://morrisjs.github.io/morris.js/lines.html

感谢您请我喝咖啡~O(∩_∩)O,如果要联系请直接发我邮箱chenx1242@163.com,我会回复你的
-------------本文结束感谢您的阅读-------------