Edited at

数百万行あるログから、ごく一部分の期間を最短時間で取得

More than 3 years have passed since last update.

数百万行あるログから、ごく一部分の期間を最短時間で取得


課題

システムを運用していると数百万行を超える膨大なログの中から、ほんの数行のログを抜き出したいことがある。

それもできることなら時間もかけず、サーバーに負荷もかけずに行いたい。


検証

Vagrantで仮想マシンCentOS 6.4を立ち上げて検証。

実現するアプローチはいくつもあるが、今回は大きく2つを調べる。

・sedコマンドで行数を指定して抽出

・headで一度抜き取り、そこからtail

どちらが短時間で目的を達成できるか検証した。

検証対象のファイルは500万行あるログファイルとし、

頭の方( 1万行目~ 1万1000行目)

中の方(250万行目~250万1000行目)

下の方(499万行目~499万1000行目)

の3パターンで検証した。


頭の方( 1万行目~ 1万1000行目)

抽出条件

10,000件目から11,000件目の1000件を抜き出す。

1.png


sedコマンドによる抽出

 time sed -n 10000,10999p nginx_access.log > sed-output

real 5m1.768s
user 0m0.330s
sys 0m40.347s

sedコマンドでは約5分強かかった。


head->tailによる抽出

 time head -n 10999 nginx_access.log | tail -n 1000 > headtail-output

real 0m1.097s
user 0m0.000s
sys 0m0.084s

約1秒で抽出ができた。


差分確認

もちろんsedで取り出しても、head->tailで取り出しても中身は同じ。

diff headtail-output sed-output

(何も表示されない。差分なし)


中の方(250万行目~250万1000行目)

抽出条件

2,500,000件目から2,501,000件目の1000件を抜き出す。

250.png


sedコマンドによる抽出

 time sed -n 2500000,2500999p nginx_access.log > sed-output

real 4m38.208s
user 0m0.439s
sys 0m41.766s

約4分40秒かかった。


head->tailによる抽出

 time head -n 2500999 nginx_access.log | tail -n 1000 > headtail-output

real 4m26.298s
user 0m0.684s
sys 0m32.164s

約4分半かかった。

若干head->tailのが早いが、その差は10秒程度。

vagrantを使って自分のマシンに仮想サーバでの検証なので、ほとんど誤差かもしれない。


差分確認

もちろんsedで取り出しても、head->tailで取り出しても中身は同じ。

diff headtail-output sed-output

(何も表示されない。差分なし)


下の方(499万行目~499万1000行目)

抽出条件

4,990,000件目から4,991,000件目の1000件を抜き出す。

499.png


sedコマンドによる抽出

 time sed -n 4990000,4990999p nginx_access.log > sed-output

real 5m1.196s
user 0m0.431s
sys 0m42.043s

約5分強かかった。


head->tailによる抽出

 time head -n 4990999 nginx_access.log | tail -n 1000 > headtail-output

real 10m57.515s
user 0m1.098s
sys 0m25.951s

下の方だとhead->tailは11分かかった。

sedコマンドでは安定の5分での取得。

逆にtail->head であればすぐに取得が可能だった。


差分確認

もちろんsedで取り出しても、head->tailで取り出しても中身は同じ。

diff headtail-output sed-output

(何も表示されない。差分なし)


結論

簡単にsedコマンドで取得しがちだが、

ファイルの上の方の情報を取得したい場合は head->tailが最も早い。

(逆に下の方の情報を取得したい場合は tail->head)

sedコマンドによる情報取得は早くはないが、抽出場所(上か中か下か)による影響は受けない。