0Pricing
DevOps Bootcamp · Lektion

Workloads mit GNU parallel orchestrieren

Verteilen Sie große Eingabemengen mit GNU parallel und Job-Slots auf mehrere Kerne und steuern Sie dabei die Ergebnisreihenfolge.

Workloads mit GNU parallel orchestrieren ist eine kostenlose DevOps Bootcamp-Lektion auf CoddyKit. Dies ist Lektion 3 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des DevOps Bootcamp-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der DevOps Bootcamp-Kurs umfasst insgesamt 4 Lektionen.

Was ist GNU parallel und warum sollten Sie es verwenden?

GNU parallel ist ein Shell-Tool, mit dem Sie Jobs parallel auf einem oder mehreren Rechnern ausführen können. Statt eine große Liste von Elementen in einer for-Schleife nacheinander zu verarbeiten, verteilt parallel die Arbeit gleichzeitig auf alle verfügbaren CPU-Kerne.

  • Geschwindigkeit: Eine Aufgabe, die sequenziell 8 Minuten dauert, kann auf einem Rechner mit 8 Kernen in etwa 1 Minute abgeschlossen werden.
  • Einfachheit: Das Tool akzeptiert Eingaben von stdin, aus Dateien oder aus Argumentlisten – eine manuelle Prozessverwaltung ist nicht erforderlich.
  • Sicherheit: Die Ausgaben verschiedener Jobs bleiben getrennt; Ergebnisse werden niemals miteinander vermischt.

Installieren Sie das Tool mit sudo apt install parallel (Debian/Ubuntu) oder brew install parallel (macOS). Überprüfen Sie die Installation mit parallel --version.

Ihr erster parallel-Befehl

Die einfachste Form von parallel liest Elemente von stdin und führt für jedes Element einen Befehl aus. Der Platzhalter {} steht für das aktuelle Eingabeelement.

Das folgende Beispiel komprimiert fünf Protokolldateien gleichzeitig mit gzip. Ohne parallel würde jede Datei nacheinander komprimiert. Mit parallel werden bis zu N Dateien gleichzeitig komprimiert, wobei N der Anzahl der CPU-Kerne entspricht.

#!/usr/bin/env bash
# Create sample files first
for i in 1 2 3 4 5; do
  dd if=/dev/urandom bs=1M count=2 of="log_${i}.txt" 2>/dev/null
done

# Compress all of them in parallel
ls log_*.txt | parallel gzip {}

echo "Done. Compressed files:"
ls log_*.txt.gz

Job-Slots mit -j steuern

Standardmäßig führt parallel einen Job pro CPU-Kern aus. Sie können dieses Verhalten mit dem Schalter -j (oder --jobs) überschreiben.

  • -j 4 – genau 4 Jobs gleichzeitig ausführen
  • -j 0 – so viele Jobs ausführen, wie Eingaben vorhanden sind (mit Vorsicht verwenden!)
  • -j 200% – doppelt so viele Jobs wie CPU-Kerne ausführen (nützlich für I/O-bound-Arbeiten)
  • -j 50% – nur die Hälfte der verfügbaren Kerne verwenden

Für CPU-bound-Aufgaben ist -j $(nproc) oft optimal. Bei Netzwerk- oder Festplatten-I/O-Aufgaben können Sie die Anzahl der Kerne problemlos überschreiten, da die Jobs die meiste Zeit warten.

#!/usr/bin/env bash
# Show how many cores are available
echo "CPU cores: $(nproc)"

# Run 8 sleep jobs but limit to 3 at a time
# -j 3 means at most 3 jobs run simultaneously
seq 1 8 | parallel -j 3 'echo "Starting job {}"; sleep 1; echo "Done job {}"'

echo "All jobs finished."

Eingaben aus Dateien und Argumenten lesen

parallel ist flexibel, was die Quelle seiner Eingabeliste betrifft. Sie sind nicht auf die Weiterleitung von stdin beschränkt.

  • Aus einer Datei: parallel -a urls.txt wget {}
  • Inline-Argumentliste: parallel echo ::: apple banana cherry
  • Mehrere Argumentquellen (kartesisches Produkt): parallel echo {1}-{2} ::: a b c ::: 1 2 – erzeugt a-1, a-2, b-1, b-2, c-1, c-2
  • Explizit von stdin: cat list.txt | parallel -j4 process {}

Das Trennzeichen ::: weist parallel an, die folgenden Werte als Argumentquelle zu verwenden, statt von stdin zu lesen.

#!/usr/bin/env bash
# Inline list with :::
parallel echo 'Hello from {}' ::: Alice Bob Carol Dave

echo '---'

# Cartesian product: combine two lists
# Generates: dev-v1, dev-v2, prod-v1, prod-v2
parallel echo 'Deploy {1} to env {2}' ::: v1 v2 ::: dev prod

Platzhalter: Eingabetoken bearbeiten

parallel stellt mehrere Platzhalterersetzungen bereit, mit denen Sie automatisch Teile der Eingabezeichenfolge extrahieren können – besonders nützlich bei Eingaben in Form von Dateipfaden.

  • {} – das vollständige Eingabeelement
  • {.} – Eingabe ohne Dateiendung (report.csv → report)
  • {/} – nur der Basisname (entfernt den Verzeichnispfad)
  • {//} – nur der Verzeichnispfad
  • {/.} – Basisname ohne Dateiendung

Damit sind keine Aufrufe von basename / dirname innerhalb des Job-Befehls erforderlich, wodurch Pipelines übersichtlicher und schneller werden.

#!/usr/bin/env bash
# Demonstrate placeholder substitutions
parallel --dry-run 'convert {} -resize 800x600 {.}_thumb.jpg' \
  ::: /photos/vacation/beach.png /photos/work/team.png

# {.}  strips extension: /photos/vacation/beach
# Result command shown (--dry-run does NOT execute):
#  convert /photos/vacation/beach.png -resize 800x600 /photos/vacation/beach_thumb.jpg
#  convert /photos/work/team.png      -resize 800x600 /photos/work/team_thumb.jpg
echo 'No files were changed (dry run)'

Ausgabe mit --keep-order geordnet halten

Wenn Jobs unterschiedlich lange brauchen, erscheint ihre stdout-Ausgabe in der Reihenfolge, in der sie beendet werden. Dadurch können Protokolle schwer lesbar und nachgelagerte Auswertungen unzuverlässig werden.

Zwei Schalter steuern die Reihenfolge der Ausgabe:

  • --keep-order (-k) – gibt die Ausgabe jedes Jobs in derselben Reihenfolge wie die Eingaben aus, selbst wenn ein später gestarteter Job zuerst beendet wird. Die Ausgabe wird gepuffert, bis die vorherigen Jobs abgeschlossen sind.
  • --line-buffer – ein Mittelweg: Gibt vollständige Zeilen aus, sobald sie eintreffen, ohne auf den Abschluss des Jobs zu warten, mischt aber niemals halbfertige Zeilen.

Verwenden Sie -k, wenn der nachgelagerte Verbraucher Ergebnisse in Eingabereihenfolge erwartet (z. B. beim Erstellen eines sortierten Berichts). Lassen Sie den Schalter weg, wenn die Reihenfolge keine Rolle spielt und Sie Ergebnisse möglichst schnell sehen möchten.

#!/usr/bin/env bash
# Without -k: output order is unpredictable
echo '--- Without --keep-order ---'
seq 5 1 1 | parallel 'sleep 0.$((RANDOM % 5)); echo "Result for {}"'

echo

# With -k: output always appears as 5, 4, 3, 2, 1
echo '--- With --keep-order (-k) ---'
seq 5 1 1 | parallel -k 'sleep 0.$((RANDOM % 5)); echo "Result for {}"'

Ausgabe gruppieren, um Vermischungen zu vermeiden

Selbst bei geordneter Ausgabe können sich die Zeilen eines Jobs, der mehrere Zeilen ausgibt, mit den Zeilen eines anderen gleichzeitig laufenden Jobs vermischen. parallel löst dieses Problem automatisch, indem es die vollständige stdout- und stderr-Ausgabe jedes Jobs puffert und sie nach Abschluss des Jobs als einen einzigen atomaren Block ausgibt.

Dieses Verhalten ist standardmäßig aktiviert. Mit --ungroup können Sie es deaktivieren, wenn Sie eine Live-Streaming-Ausgabe benötigen (z. B. bei lang laufenden Jobs mit Fortschrittsanzeigen). Dann kann es jedoch wieder zu Vermischungen kommen.

  • Standard: Die Ausgabe wird pro Job gruppiert — sicher für die Verarbeitung durch Parser.
  • --ungroup: Die Ausgabe wird live gestreamt — geeignet für die interaktive Überwachung.
  • --line-buffer: Kompromiss — Zeilen werden niemals aufgeteilt, aber Jobs können sich an Zeilengrenzen vermischen.

Argumente innerhalb von Shell-Funktionen übergeben

Manchmal besteht die zu parallelisierende Arbeit aus mehr als einem einzelnen Befehl — es handelt sich um eine mehrstufige Shell-Funktion. Sie können eine Funktion mit export -f in Kombination mit env_parallel an parallel übergeben oder bash -c direkt aufrufen.

Der sicherste portable Ansatz für komplexe Jobs ist das Muster bash -c '...'. Der Platzhalter {} wird als $1 übergeben, wenn der Aufruf mit _ {} endet.

#!/usr/bin/env bash
# Define a multi-step processing function
process_item() {
  local item="$1"
  echo "[START] $item"
  # Simulate two steps
  sleep 0.2
  local result=$(echo "$item" | tr '[:lower:]' '[:upper:]')
  echo "[END]   $item -> $result"
}

export -f process_item

# Run the function in parallel for each input
echo 'alpha beta gamma delta epsilon' | tr ' ' '\n' \
  | parallel -j 3 process_item {}

Drosselung und Wiederholungen mit --delay und --retries

Wenn Sie externe Dienste (APIs, Remote-Server, Datenbanken) parallel ansprechen, benötigen Sie häufig eine Ratenbegrenzung und Fehlertoleranz.

  • --delay N — wartet N Sekunden zwischen dem Start jedes neuen Jobs (Dezimalwerte wie 0.5 sind zulässig). Verhindert, dass ein Dienst überlastet wird.
  • --retries N — wenn ein Job mit einem Status ungleich null beendet wird, wird er bis zu N-mal wiederholt, bevor der Vorgang abgebrochen wird. Jeder Wiederholungsversuch zählt als neuer Job-Slot.
  • --timeout N — beendet einen Job, wenn er länger als N Sekunden läuft. Zusammen mit --retries lassen sich hängende Jobs damit kontrolliert behandeln.

Beispiel: 50 URLs mit höchstens 4 gleichzeitigen Verbindungen herunterladen, mit einer Verzögerung von 0,5 s zwischen den Starts und 3 Wiederholungsversuchen bei Fehlern.

#!/usr/bin/env bash
# Simulate downloading URLs with throttling and retries
# (using echo instead of curl so this is self-contained)

download_url() {
  local url="$1"
  # Randomly fail ~30% of the time to demo --retries
  if (( RANDOM % 10 < 3 )); then
    echo "FAIL: $url" >&2
    return 1
  fi
  echo "OK:   $url downloaded"
}

export -f download_url

printf 'https://example.com/file%d\n' $(seq 1 10) \
  | parallel -j 4 --delay 0.2 --retries 3 download_url {}

echo 'All downloads attempted.'

Arbeit mit --sshloginfile auf Remote-Hosts verteilen

parallel kann Jobs transparent über SSH auf Remote-Rechner verteilen und wird so zu einem schlanken Cluster-Rechenwerkzeug, für das keine spezielle Cluster-Software erforderlich ist.

  • --sshlogin user@host — Jobs auf einem bestimmten Remote-Host ausführen.
  • --sshloginfile machines.txt — eine Liste von Hosts aus einer Datei einlesen (einer pro Zeile). Verwenden Sie : als speziellen Eintrag, um zusätzlich den lokalen Rechner zu verwenden.
  • --transfer — die Eingabedatei vor der Verarbeitung auf den Remote-Host kopieren.
  • --return {} — die Ergebnisdatei nach Abschluss des Jobs zurückkopieren.
  • --cleanup — übertragene Dateien nach dem Abruf auf dem Remote-Host löschen.

Auf dem Remote-Host muss parallel installiert und eine SSH-Schlüsselauthentifizierung ohne Passwortabfragen eingerichtet sein.

Fortschrittsanzeige und Protokollierung

Bei lang laufenden Arbeitslasten ist es unerlässlich, den Fortschritt zu überwachen und Fehler nachträglich zu analysieren.

  • --progress — gibt eine laufend aktualisierte Zusammenfassung aus, die zeigt, wie viele Jobs gerade ausgeführt werden, abgeschlossen sind und noch ausstehen.
  • --eta — schätzt anhand der bisherigen durchschnittlichen Jobdauer die verbleibende Zeit bis zum Abschluss.
  • --joblog results.log — schreibt eine durch Tabulatoren getrennte Protokolldatei mit einer Zeile pro abgeschlossenem Job, einschließlich Exit-Code, Laufzeit und ausgeführtem Befehl. Für die Analyse von Fehlern äußerst wertvoll.
  • --resume --joblog results.log — überspringt Jobs, die bereits mit Exit-Code 0 in der Protokolldatei aufgeführt sind. Wenn ein Batch-Lauf unterbrochen wird, können Sie ihn fortsetzen, ohne erfolgreiche Arbeiten erneut auszuführen.

Die Kombination aus --joblog und --resume ist eine der leistungsfähigsten Funktionen von GNU parallel für robuste Produktions-Pipelines.

#!/usr/bin/env bash
LOGFILE="/tmp/parallel_demo_$$.log"

# Run jobs and record results to a log
seq 1 12 | parallel \
  --jobs 4 \
  --progress \
  --joblog "$LOGFILE" \
  'sleep 0.1; echo "Processed item {}"'

echo
echo '=== Job Log (first 5 entries) ==='
head -6 "$LOGFILE"

# Show only failed jobs (exit value != 0)
echo '=== Failed jobs ==='
awk 'NR>1 && $7 != 0 { print $0 }' "$LOGFILE" || echo '(none)'

rm -f "$LOGFILE"

Wissenscheck: Optionen für Job-Slots

Testen Sie Ihr Verständnis dafür, wie parallel die Nebenläufigkeit steuert.

Lektionsrückblick: Arbeitslasten mit GNU parallel orchestrieren

Sie haben die wichtigsten Werkzeuge kennengelernt, um große Eingabemengen mit GNU parallel auf CPU-Kerne zu verteilen. Das sollten Sie mitnehmen:

  • Grundlegende Verwendung: Leiten Sie eine Liste mit parallel command {} weiter — {} wird durch jedes Eingabeelement ersetzt.
  • Job-Slots (-j): Steuern Sie die Nebenläufigkeit präzise — verwenden Sie die Anzahl der Kerne für CPU-intensive Arbeit und höhere Prozentsätze für I/O-intensive Arbeit.
  • Platzhalter ({.}, {/}, {//}, {/.}) extrahieren Pfadbestandteile sauber, ohne zusätzliche Befehle.
  • Ausgabesteuerung: -k bewahrt die Eingabereihenfolge; die standardmäßige Gruppierung verhindert vermischte Zeilen; --ungroup ermöglicht Live-Streaming.
  • Robustheit: --retries, --timeout und --delay machen parallele Pipelines widerstandsfähig gegenüber fehleranfälligen Jobs und Ratenbegrenzungen.
  • Nachvollziehbarkeit: --joblog protokolliert das Ergebnis jedes Jobs; mit --resume können Sie nach einer Unterbrechung an der bisherigen Stelle fortfahren.
  • Horizontale Skalierung: --sshloginfile verteilt Jobs ohne zusätzlichen Cluster-Overhead über SSH auf Remote-Rechner.

Wenn Sie diese Optionen beherrschen, wird parallel zu einem produktionsreifen Orchestrator für Arbeitslasten, der direkt in Ihre Shell integriert ist.

Häufig gestellte Fragen

Ist die Lektion „Workloads mit GNU parallel orchestrieren“ kostenlos?

Ja — der vollständige Text von „Workloads mit GNU parallel orchestrieren“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des DevOps Bootcamp-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der DevOps Bootcamp-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „Workloads mit GNU parallel orchestrieren“?

Verteilen Sie große Eingabemengen mit GNU parallel und Job-Slots auf mehrere Kerne und steuern Sie dabei die Ergebnisreihenfolge. Du übst DevOps Bootcamp mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um DevOps Bootcamp zu starten?

Keine Vorkenntnisse erforderlich. DevOps Bootcamp auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 3 von 4.

Wie lange dauert die Lektion „Workloads mit GNU parallel orchestrieren“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser DevOps Bootcamp-Lektion Code schreiben und ausführen?

Ja. Jede DevOps Bootcamp-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. Skripte profilieren und unnötige Subshells vermeiden
  2. Parallelisierung mit xargs -P und Hintergrundjobs
  3. Workloads mit GNU parallel orchestrieren
  4. Streaming-Pipelines und Named Pipes für hohen Durchsatz
← Zurück zu DevOps Bootcamp