我有两个网络服务器,我想知道按请求数排序的前 10 个 ip。
网络服务器是基于 Apache 的,所以我需要查看 access.log 文件。
问题是由于这些文件很大,我真的希望不要在本地传输它们,因此我想知道是否有办法在流媒体中做到这一点。我确实可以通过 ssh 访问这些机器。
我想,一种方法是运行这样的东西:
awk "{ print $1 }" access.log | sort | uniq -c | sort -n | tail
在两台机器上,然后以某种方式在本地组合结果,但这显然是错误的。
答案1
由于概念上只关心文件大小,因此所需要的只是
{
ssh server2 cat /path/to/access.log
cat /local/path/to/access.log
} | awk '{print $1}' | sort | uniq -c | sort -n | tail
然而,可以采取许多措施来提高速度。
首先仅通过网络发送 IP 地址,以减少带宽。
{
ssh server2 awk '{print $1}' /path/to/access.log
cat /local/path/to/access.log
} | awk '{print $1}' | sort | uniq -c | sort -n | tail
其次,利用 awk 的散列来消除排序的需要。这将阶数 n*lg(n) 替换为阶数 n。这使用一个关联数组来seen
计算每个 ip 地址被看到的次数,并在最后打印出计数和地址。
{
ssh server2 awk '{print $1}' /path/to/access.log
cat /local/path/to/access.log
} | awk '{seen[$1]++} END {for (i in seen){print seen[i],i}}' | sort -n | tail
第三次反向排序,再次减少需要流动的数据量
{
ssh server2 awk '{print $1}' /path/to/access.log
cat /local/path/to/access.log
} | awk '{seen[$1]++} END {for (i in seen){print seen[i],i}}' | sort -rn | head
根据数据的不同,在远程 Web 服务器上预处理数据可能是有意义的。 (seen
数组重命名为s
以节省输入)。这里发送的数据是计数和地址对。然后我们在第三个 awk 进程中在本地将它们相加。
{
ssh server2 awk '{s[$1]++}END{for (i in s){print s[i],i}}' /path/to/access.log
awk '{s[$1]++}END{for (i in s){print s[i],i}}' /local/path/to/access.log
} | awk '{s[$2]+=$1}END{for (i in s){print s[i],i}}' | sort -rn | head
当然未经测试。