跨两个节点请求的前 10 个 IP

跨两个节点请求的前 10 个 IP

我有两个网络服务器,我想知道按请求数排序的前 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

当然未经测试。

相关内容