両方のノードで要求された上位10個のIP

両方のノードで要求された上位10個のIP

2つのWebサーバーがあり、要求数に基づいてソートされた上位10個のIPを知りたいです。

WebサーバーはApacheベースなので、access.logファイルを見てください。

問題は、これらのファイルが大容量なので、必ずローカルにストリーミングしたくないのですが、ストリーミングでできる方法がないかと思います。実際にはSSH経由でこのコンピュータにアクセスできます。

私の考えの1つの方法は、次のように実行することです。

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

3番目の逆整列は、再び流す必要があるデータ量を減らします。

{
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)。ここで送信されるデータは、数とアドレスのペアです。次に、3番目の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

もちろんテストされていません。

おすすめ記事