背景
线上某个redis连接数过万,老报警,于是产生刚需:快速知道某个redis的client分布.
用于快速找出连接数占用最多的客户端.
shell
习惯python的老司机处理这点小事,那还不是手到擒来.可是偶尔不也想装个逼,用shell么?
先上代码,接着解读
#!/bin/bash
host=$1
port=$2
echo $host: $port
redis-cli -h $host -p $port client list | awk '{print $2}'| cut -d = -f 2| cut -d : -f 1 | sort | uniq -c | sort -rn | awk '{"host " $2 | getline h; print $1 "\t" $2 "\t" h;}'| awk '{print $1 "\t" $2 "\t" $7}'
解读
首先是
redis-cli
的client list
命令列出所有client信息.
注意:如果client数特别多,可能超过输出长度限制
每一行输出信息如下:
id=2 addr=127.0.0.1:49759 fd=5 name= age=5471 idle=5455 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=get
接着是
awk
输出第二列addr=127.0.0.1:49759
接着是
cut
命令,-d =
指定以=
分隔,-f 2
获取分隔后的第二列,也就是127.0.0.1:49759
同上,继续
cut
,:
分隔,取第一列127.0.0.1
(客户端IP)
感觉这两个cut
可以合二为一接着
sort
排序接着
sort -rn
按连接数排个倒序.结果如下160 10.83.72.99
142 10.83.80.63
141 10.83.73.112
140 10.83.80.101
140 10.83.203.68
139 10.83.73.118
139 10.83.212.136
135 10.83.225.53
135 10.83.225.33
132 10.83.80.103
132 10.83.225.52
128 10.83.225.32
128 10.83.225.31
125 10.83.73.89
125 10.83.200.53
123 10.83.72.217
16 127.0.0.1这个时候已经知道那些客户端占用连接数最多了,但是显示的是IP,不直观,能不能把IP那一列换成域名或者说主机名呢?
接着
awk '{"host " $2 | getline h; print $1 "\t" $2 "\t" h;}'
慢慢来,花括号里一共两条语句,第一条语句对第二例(也就是IP)调用系统命令host
,同时把结果保存在变量h
里.getline
获取前面shell的结果,传参就存在参数里,不传就默认 $0
print
输出第一列(计数),第二列(IP),h
(主机信息,也就是host
命令的结果)结果如下:
160 10.83.72.99 99.72.83.10.in-addr.arpa domain name pointer xxx009.com. 142 10.83.80.63 63.80.83.10.in-addr.arpa domain name pointer xxx008.com. 141 10.83.73.112 112.73.83.10.in-addr.arpa domain name pointer xxx003.com. 140 10.83.80.101 101.80.83.10.in-addr.arpa domain name pointer xxx001.com. 140 10.83.203.68 68.203.83.10.in-addr.arpa domain name pointer yyy009.com. 139 10.83.73.118 118.73.83.10.in-addr.arpa domain name pointer xxx007.com. 139 10.83.212.136 136.212.83.10.in-addr.arpa domain name pointer xxx010.com. 135 10.83.225.53 53.225.83.10.in-addr.arpa domain name pointer xxx014.com. 135 10.83.225.33 33.225.83.10.in-addr.arpa domain name pointer xxx015.com. 132 10.83.80.103 103.80.83.10.in-addr.arpa domain name pointer xxx005.com. 132 10.83.225.52 52.225.83.10.in-addr.arpa domain name pointer xxx012.com. 128 10.83.225.32 32.225.83.10.in-addr.arpa domain name pointer xxx013.com. 128 10.83.225.31 31.225.83.10.in-addr.arpa domain name pointer xxx011.com. 125 10.83.73.89 89.73.83.10.in-addr.arpa domain name pointer xxx002.com. 125 10.83.200.53 53.200.83.10.in-addr.arpa domain name pointer xxx006.com. 123 10.83.72.217 217.72.83.10.in-addr.arpa domain name pointer xxx004.com. 7 127.0.0.1 1.0.0.127.in-addr.arpa domain name pointer localhost.
最后一个
awk
输出需要的列:第一列(计数),第7列(主机名)
最终结果160 10.83.72.99 xxx009.com. 142 10.83.80.63 xxx008.com. 141 10.83.73.112 xxx003.com. 140 10.83.80.101 xxx001.com. 140 10.83.203.68 yyy009.com. 139 10.83.73.118 xxx007.com. 139 10.83.212.136 xxx010.com. 135 10.83.225.53 xxx014.com. 135 10.83.225.33 xxx015.com. 132 10.83.80.103 xxx005.com. 132 10.83.225.52 xxx012.com. 128 10.83.225.32 xxx013.com. 128 10.83.225.31 xxx011.com. 125 10.83.73.89 xxx002.com. 125 10.83.200.53 xxx006.com. 123 10.83.72.217 xxx004com. 15 127.0.0.1 localhost.
感觉最后两个
awk
也可以合二为一,在一个awk
里既调用host
又筛选指定列
More
shell 很烂,写的很渣渣,高手求指点