Die Shell-Abarbeitung beschleunigen

Wie du mit parallelen Prozessen effizienter in der Shell arbeitest

Die Linux-Shell deines Servers arbeitet Befehle und Scripte sequentiell ab: ein Kommando nach dem anderen. Die Möglichkeiten von Mehrkern-Prozessoren werden dabei nicht genutzt, sodass umfangreiche Befehle und Scripte eine hohe Laufzeit aufweisen können, während der Grossteil der Prozessorkerne aussen vor bleibt. Mit GNU parallel änderst du dies und lässt Shell die Kerne deines Servers ausnutzen.

Wie Sie GNU parallel auf deinem Linux-System einsetzst

Ob GNU parallel bereits auf deinem System installiert ist, prüfst du unter Debian mit dpkg -s parallel. Wenn es installiert ist, wird dir eine Beschreibung des Tools angezeigt, die mit dem Verweis auf die Homepage “https://www.gnu.org/software/parallel/” endet.

Falls GNU parallel noch nicht installiert ist, hole dies unter Debian mit apt-get install parallel nach. Für Paket-Manager anderer Linux-Distributionen steht in der Regel ebenfalls ein Installationspaket bereit.

Das Kommando parallel baust du nun in deine Befehle oder den Aufruf deiner Scripte ein. Die parallel zu verarbeitenden Kommandos nimmt GNU parallel bei der Ausführung entweder von stdin (der Standardeingabe) oder aus Dateien entgegen. Dabei nutzst du insbesondere die folgenden zwei Parameter, um die parallele Abarbeitung zu steuern:

  • –keep-order: Sorgt dafür, dass auch bei der parallelen Abarbeitung die Reihenfolge der Ausgabe identisch zur Ausgabe bei der sequentiellen Abarbeitung bleibt
  • –jobs: Gibt die gewünschte Anzahl an gleichzeitig auszuführenden Kommandos pro Prozessorkern in Prozent (z.B. 100%) bzw. die Anzahl der gleichzeitig auszuführenden Kommandos (z.B. 4) an

Eine Übersicht sämtlicher Parameter erhaltest du unter http://www.gnu.org/software/parallel/man.html#options.

So beschleunigst du deine Shell-Befehle mit GNU parallel

GNU parallel kommt beispielsweise dann zum Einsatz, wenn ein Kommando auf eine grössere Anzahl von Dateien angewendet werden soll. Da die Bearbeitung des Kommandos für die einzelnen Dateien unabhängig voneinander ist, kann diese parallel geschehen. Ein Beispiel: Das Packen sämtlicher Log-Dateien unter “/var/log/www/” in einer separaten gzip-Datei für die Archivierung lässt du wie folgt parallelisieren:

  1. Wechsel in das Verzeichnis “/var/log/www/”.
  2. Führe das folgende Kommando aus:

ls *.log | parallel gzip {}

Dabei sorgt ls *.log wie gewohnt für eine Auflistung sämtlicher Dateien mit der Endung “.log” im aktuellen Verzeichnis. Per Pipe (“|”) wird diese Auflistung nun an parallel übergeben. parallel übergibt dann die Abarbeitung der Dateiauflistung an gzip, wobei die zwei geschweiften Klammern (“{}”) angeben, an welcher Stelle des von parallel ausgeführten Kommandos die durch ls aufgelisteten Dateinamen eingefügt werden.

Durch die Verwendung der geschweiften Klammern steuerst du die an das parallel ausgeführte Kommando übergebenen Parameter auch, wenn diese abgewandelt werden sollen. So ist “{.}” beispielsweise Platzhalter für einen Dateinamen ohne Dateiendung, wodurch “access.log” zu “access” wird. Dies nutzst du beispielsweise bei der parallelen Umbenennung von Dateien:

ls *.log | parallel mv {} {.}.bak

Mit dieser Zeile führt parallel per mv die Umbenennung jeder Log-Datei des aktuellen Verzeichnisses durch. Angenommen das Verzeichnis enthält die Log-Dateien “1.log” und “2.log”, werden also parallel ausgeführt:

mv 1.log 1.bak

mv 2.log 2.bak

platzhalter

Abbildung: Mit weiteren Varianten der Platzhalter für Eingabeparameter gibst du auch die Verwendung des Dateipfades vor. Das ist beispielsweise hilfreich, wenn du mit dem Kommando find Dateien aus unterschiedlichen Verzeichnissen zusammensuchst und diese parallel verarbeiten lässt. Sämtliche Varianten der Platzhalter findest du unter http://www.gnu.org/software/parallel/man.html#options.

Weitere Beispiele für die Arbeit mit GNU parallel findest du unter http://www.gnu.org/software/parallel/man.html