Suche…
Einführung
Jobs in GNU Linux können mit GNU parallel parallelisiert werden. Ein Job kann ein einzelner Befehl oder ein kleines Skript sein, das für jede der Zeilen in der Eingabe ausgeführt werden muss. Die typische Eingabe ist eine Liste von Dateien, eine Liste von Hosts, eine Liste von Benutzern, eine Liste von URLs oder eine Liste von Tabellen. Ein Job kann auch ein Befehl sein, der aus einer Pipe liest.
Syntax
- parallel [Optionen] [Befehl [Argumente]] <Listenargumente>
Parameter
Möglichkeit | Beschreibung |
---|---|
-jn | Führen Sie n Jobs parallel aus |
-k | Behalte die gleiche Reihenfolge |
-X | Mehrere Argumente mit Kontext ersetzen |
--colsep regexp | Geteilte Eingabe bei Regex für Positionsersetzungen |
{} {.} {/} {/.} {#} | Ersatzstrings |
{3} {3.} {3/} {3/.} | Positionswechselstrings |
-S sshlogin | Example: [email protected] |
--trc {}.bar | Abkürzung für --transfer --return {} .bar --cleanup |
--onall | Führen Sie den angegebenen Befehl mit Argument für alle sshlogins aus |
--nonall | Führen Sie den angegebenen Befehl ohne Argumente für alle sshlogins aus |
--pipe | Teilen Sie stdin (Standardeingabe) auf mehrere Jobs auf. |
--recend str | Ende-Trennzeichen für --pipe aufzeichnen. |
--recstart str | Starttrennzeichen für --pipe aufzeichnen. |
Parallelisieren Sie sich wiederholende Aufgaben auf der Liste der Dateien
Viele wiederkehrende Aufträge können effizienter ausgeführt werden, wenn Sie mehr Ressourcen Ihres Computers (z. B. CPU und RAM) verwenden. Im Folgenden finden Sie ein Beispiel für die parallele Ausführung mehrerer Jobs.
Angenommen, Sie haben eine < list of files >
, beispielsweise eine Ausgabe von ls
. Lassen Sie diese Dateien auch bz2-komprimiert sein und die folgende Reihenfolge der Aufgaben muss ausgeführt werden.
- Dekomprimieren Sie die bz2-Dateien mit
bzcat
in stdout - Grep (z. B. Filter) Zeilen mit bestimmten Schlüsselwörtern mit
grep <some key word>
- Übergeben Sie die zu verkettende Ausgabe mithilfe von
gzip
in eine einzige komprimierte Datei
Wenn Sie dies mit einer while-Schleife ausführen, kann dies folgendermaßen aussehen
filenames="file_list.txt"
while read -r line
do
name="$line"
## grab lines with puppies in them
bzcat $line | grep puppies | gzip >> output.gz
done < "$filenames"
Mit GNU Parallel können wir drei parallele Jobs gleichzeitig ausführen
parallel -j 3 "bzcat {} | grep puppies" ::: $( cat filelist.txt ) | gzip > output.gz
Dieser Befehl ist einfach, präzise und effizienter, wenn die Anzahl der Dateien und die Dateigröße groß sind. Die Jobs werden von parallel
-j 3
, Option -j 3
startet 3 parallele Jobs und die Eingabe in die parallelen Jobs wird von :::
. Die Ausgabe wird schließlich an gzip > output.gz
STDIN parallelisieren
Nehmen wir an, wir haben 1 große Datei (z. B. 30 GB), die zeilenweise konvertiert werden muss. convert.sh
, wir haben ein Skript, convert.sh
, das diese <task>
erledigt. Wir können den Inhalt dieser Datei an stdin weiterleiten, um sie in Chunks wie z. B. aufzunehmen und zu bearbeiten
<stdin> | parallel --pipe --block <block size> -k <task> > output.txt
wobei <stdin>
von etwas wie cat <file>
.
Als reproduzierbares Beispiel nl -n rz
unsere Aufgabe nl -n rz
. Nehmen Sie eine beliebige Datei, meine ist data.bz2
und übergeben Sie sie an <stdin>
bzcat data.bz2 | nl | parallel --pipe --block 10M -k nl -n rz | gzip > ouptput.gz
Das obige Beispiel nimmt <stdin>
von bzcat data.bz2 | nl
, wo ich nl
nur als Beweis für das Konzept aufgenommen habe, dass die endgültige output.gz
in der Reihenfolge output.gz
wird, in der sie empfangen wurde. parallel
die <stdin>
in Blöcke mit einer Größe von 10 MB aufgeteilt, und es wird für jeden Block durch nl -n rz
wo eine Zahl richtig angegeben wird (siehe nl --help
für weitere Details). Die Optionen --pipe
sagt parallel
, dass <stdin>
in mehrere Jobs aufgeteilt werden soll, und -- block
gibt die Größe der Blöcke an. Die Option -k
gibt an, dass die Reihenfolge beibehalten werden muss.
Ihre endgültige Ausgabe sollte ungefähr so aussehen
000001 1 <data>
000002 2 <data>
000003 3 <data>
000004 4 <data>
000005 5 <data>
...
000587 552409 <data>
000588 552410 <data>
000589 552411 <data>
000590 552412 <data>
000591 552413 <data>
Meine Originaldatei hatte 552.413 Zeilen. Die erste Spalte stellt die parallelen Jobs dar und die zweite Spalte stellt die ursprüngliche Zeilennummerierung dar, die in Blöcken an parallel
wurde. Sie sollten feststellen, dass die Reihenfolge in der zweiten Spalte (und der Rest der Datei) beibehalten wird.