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
もちろんテストされていません。