Leistungsproblem beim Parsen großer Protokolldateien (~ 5 GB) mit awk, grep, sed

8

Ich beschäftige mich derzeit mit Protokolldateien mit Größen ca.. 5 GB. Ich bin ziemlich neu beim Parsen von Log-Dateien und bei der Verwendung von UNIX Bash, also werde ich versuchen, so genau wie möglich zu sein. Beim Durchsuchen von Protokolldateien mache ich Folgendes: Geben Sie die Nummer der Anforderung an, nach der gesucht werden soll, und stellen Sie dann optional die Aktion als sekundären Filter bereit. Ein typischer Befehl sieht so aus:

%Vor%

Dies ist in Ordnung mit kleineren Dateien, aber mit einer Protokolldatei, die 5 GB ist, ist es unerträglich langsam. Ich habe online gelesen, dass es großartig ist, sed oder awk zu verwenden, um die Leistung zu verbessern (oder möglicherweise sogar eine Kombination aus beidem), aber ich bin nicht sicher, wie das erreicht wird. Zum Beispiel habe ich mit awk einen typischen Befehl:

%Vor%

Grundsätzlich ist es mein ultimatives Ziel, die Datensätze (oder die Zeilennummer), die die Strings enthalten, auszudrucken und zurückzugeben (kann bis zu 4-5 sein, und ich habe Piping gelesen), um in einer Log-Datei effizient übereinzustimmen .

Nebenbei bemerkt, in der Bash-Shell, wenn ich awk verwenden und etwas verarbeiten möchte, wie wird das erreicht? Zum Beispiel:

%Vor%

Das ist ein ziemlich einfaches awk-Skript, und ich würde annehmen, dass es einen Weg gibt, dies in einen Ein-Liner-Bash-Befehl einzufügen? Aber ich bin nicht sicher, wie die Struktur ist.

Vielen Dank im Voraus für die Hilfe. Prost.

    
Albert 25.08.2011, 21:34
quelle

4 Antworten

18

Sie müssen einige Tests durchführen, um herauszufinden, wo Ihre Engpässe sind und wie schnell Ihre verschiedenen Tools funktionieren. Versuchen Sie einige Tests wie folgt:

%Vor%

Traditionell sollte egrep der Schnellste sein (ja, schneller als fgrep), aber einige moderne Implementierungen sind adaptiv und schalten automatisch auf den am besten geeigneten Suchalgorithmus um. Wenn Sie bmgrep haben (das den Boyer-Moore-Suchalgorithmus verwendet), versuchen Sie es. Im Allgemeinen werden sed und awk langsamer sein, da sie als allgemeinere Textmanipulationswerkzeuge konzipiert sind und nicht für die spezifische Aufgabe der Suche abgestimmt sind. Aber es hängt wirklich von der Implementierung ab, und der richtige Weg, das herauszufinden, ist es, Tests durchzuführen. Führen Sie sie jeweils mehrere Male aus, damit Sie nicht durch Dinge wie Caching und konkurrierende Prozesse verwirrt werden.

Wie @Ron hervorgehoben hat, kann Ihr Suchprozess festplattengebunden sein. Wenn Sie dieselbe Protokolldatei mehrmals durchsuchen, ist es möglicherweise schneller, die Protokolldatei zuerst zu komprimieren. Dies macht das Ablesen der Festplatte schneller, benötigt dann jedoch mehr CPU-Zeit für die Verarbeitung, da sie zuerst dekomprimiert werden muss. Versuchen Sie etwas wie folgt:

%Vor%

Ich habe gerade einen Schnelltest mit einer ziemlich komprimierbaren Textdatei durchgeführt, und festgestellt, dass bzip2 am besten komprimiert ist, aber dann viel mehr CPU-Zeit für die Dekomprimierung benötigt, also war die zgip-Option am schnellsten. Ihr Computer wird eine andere Platten- und CPU-Leistung als meine haben, daher können sich Ihre Ergebnisse unterscheiden. Wenn Sie irgendwelche anderen Kompressoren herumliegen haben, probieren Sie sie auch aus, und / oder probieren Sie verschiedene gzip Kompressionsgrade aus, usw.

Apropos Preprocessing: Wenn Sie dasselbe Protokoll immer wieder durchsuchen, gibt es eine Möglichkeit, nur die Protokollzeilen auszuwählen, an denen Sie interessiert sein könnten ? Wenn ja, grep sie in eine kleinere (vielleicht komprimierte) Datei, dann suchen Sie das statt der ganzen Sache. Wie bei der Komprimierung verbringen Sie etwas mehr Zeit im Voraus, aber dann läuft jede einzelne Suche schneller.

Ein Hinweis zum Piping: Wenn andere Dinge gleich sind, ist das Verteilen einer großen Datei über mehrere Befehle langsamer als die Ausführung eines einzelnen Befehls. Aber alle Dinge sind hier nicht gleich, und wenn Sie mehrere Befehle in einer Pipe verwenden (was zgrep und bzgrep tun), erhalten Sie eine bessere Gesamtleistung. Überlegen Sie auch, ob Sie tatsächlich alle Daten über die gesamte Pipe übertragen. In dem Beispiel, das Sie angegeben haben, fgrep '2064351200' example.log | fgrep 'action: example' , wird der erste fgrep den größten Teil der Datei verwerfen; Die Pipe und der zweite Befehl müssen nur den kleinen Bruchteil des Protokolls verarbeiten, das '2064351200' enthält, daher ist die Verlangsamung wahrscheinlich vernachlässigbar.

tl; dr TEST ALLE DINGE!

BEARBEITEN: Wenn die Protokolldatei "live" ist (dh neue Einträge hinzugefügt werden), aber der Großteil davon statisch ist, können Sie möglicherweise einen partiellen Vorverarbeitungsansatz verwenden: komprimieren (& amp; vielleicht prescan) das Protokoll Verwenden Sie dann beim Scannen die komprimierte (& amp; / vorgescannte) Version plus einen Teil des Teils des Protokolls, der seit dem Vorscan hinzugefügt wurde. Etwas wie das:

%Vor%

Wenn Sie mehrere verwandte Suchvorgänge durchführen möchten (z. B. eine bestimmte Anfrage, dann bestimmte Aktionen mit dieser Anfrage), können Sie vorgescannte Versionen speichern:

%Vor%     
Gordon Davisson 26.08.2011, 04:55
quelle
3

Wenn Sie die Reihenfolge Ihrer Strings nicht kennen, dann:

%Vor%

Wenn Sie wissen, dass sie nacheinander in der Zeile erscheinen:

%Vor%

(Hinweis für awk, {print} ist der Standardaktionsblock, daher kann er weggelassen werden, wenn die Bedingung gegeben ist)

Der Umgang mit Dateien, die groß sind, wird langsam sein, egal wie Sie es schneiden.

    
glenn jackman 25.08.2011 21:55
quelle
2

Bei mehrzeiligen Programmen in der Befehlszeile

%Vor%

Beachten Sie die einfachen Anführungszeichen.

    
hemflit 26.08.2011 00:45
quelle
1

Wenn Sie dieselbe Datei mehrmals verarbeiten, ist es möglicherweise schneller, sie in eine Datenbank einzulesen und vielleicht sogar einen Index zu erstellen.

    
tripleee 26.08.2011 05:27
quelle

Tags und Links