Ich habe versucht, das von mir verwendete Skript zu parallelisieren, aber bisher ist GNU Parallel sehr herausfordernd.
Ich habe 2 Dateien - eine mit Hosts, auf denen der Befehl ausgeführt werden soll, und eine mit Parametern für den Befehl. Unten ist beispieldaten:
$ cat workers.host
foo@192.168.0.7
bar@192.168.0.8
jerry@192.168.0.9
tom@192.168.0.21
$ cat paths
/usr/local/jar/x/y/ jarxy
/usr/local/jar/z/y/ jarzy
/usr/local/jar/y/y/ jaryy
/usr/local/far/x/y/ farxy
/usr/local/jaz/z/z/ jazzz
/usr/local/mu/txt/ana/ acc01
/usr/local/jbr/x/y/ accxy
Und um das zu verarbeiten, benutze ich folgendes Skript:
#!/bin/bash
echo "Run this on 192.168.130.10";
DATA=`date +%F`
DDAY=`date +%u`
DOMBAC='nice tar cpzf'
readarray -t hosts < workers.host
len=${#hosts[@]};
processed=0;
while read -r -a line; do
let hostnum=processed%len;
ssh ${hosts[$hostnum]} -i /root/.ssh/id_rsa "$DOMBAC - ${line[0]}" > "/data/backup/$DDAY/${line[1]}_${DATA}_FULL.tgz"
let processed+=1;
done < paths
Dies funktioniert gut, wird jedoch maschinenweise schrittweise abgearbeitet. Die Hosts sind ziemlich überlastet und das Netzwerk ist hier kein Problem. Deshalb wollte ich dies so weit wie möglich parallelisieren. Führen Sie zum Beispiel 4 Instanzen des Befehls tar auf jedem Host aus und leiten Sie die Ausgabe über ssh in eine ordnungsgemäß benannte Datei. Ich bin völlig verloren mit parallel --results
--sshloginfile
... Und was ich letztendlich erreichen möchte, ist, dass 4 Jobs auf jedem Host laufen, jeder mit unterschiedlichen Parametern (so dass zum Beispiel Host 2 nicht überschreibt, was Host 1 bereits getan hat). . Kann das in GNU Parallel gemacht werden?
parallel -j${JOBS} --link ./do_on_hosts.sh {1} {2} "$DATA" "$DDAY" :::: workers.host :::: to_backup.path
basiert auf zwei Dingen: und in do_on_hosts.sh:ssh $1 "${REMOTE_CMD} ${arr[0]}"> ${LOCAL_STORAGE_PATH}${DDAY}/${arr[1]}_${DATA}_FULL.tgz
Ich frage mich, wie das im Vergleich zu Deinem ist ... brauche eine weitere Runde, um es zu versuchen.Sie könnten parallel dazu verwenden, um dies zu erreichen, aber ich denke, es wäre übertrieben für das, was Sie erreichen möchten. Stattdessen würde ich einfach Hintergrundjobs verwenden, um diese Befehle (in der Nähe von) gleichzeitig auszuführen.
Um dies mit einem Minimum an Änderungen an Ihrem vorhandenen Skript zu erreichen, müssen wir lediglich jede ausgeführte Task im Hintergrund ausführen (verwenden Sie dazu den Operator &). Um verwaiste Prozesse zu verhindern, sollten wir sicherstellen, dass das Skript erst beendet wird, wenn alle Jobs abgeschlossen sind, was mit der integrierten Bash erledigt wird
wait
. Der Befehl jobs gibt eine Liste der ausgeführten Tasks aus (möglicherweise sind nicht alle Tasks vorhanden, einige sind je nach Ausführungszeit bereits beendet, bevor Sie diesen Punkt erreichen).Ich bin mir auch nicht sicher, warum Sie den Befehl nice ohne Argument verwenden. Ich glaube, dass er ohne Argument nur die relative Priorität der gestarteten Aufgabe ausgibt, was vermutlich Ihre Absicht sein könnte.
Hier ist eine modifizierte Version Ihres Skripts mit diesen Änderungen
quelle
nice
- ohne Argumente ändert sich die Freundlichkeit von 0 auf 10 :)