Parallelisieren von Remote-Tar und Ausgabe von ssh-Pipe

599
Johnny_Bit

Ich habe versucht, das von mir verwendete Skript zu parallelisieren, aber GNU Parallel ist bisher sehr anspruchsvoll.

Ich habe 2 Dateien - eine, die Hosts enthält, auf denen der Befehl ausgeführt werden soll, und eine zweite, die Parameter für den Befehl hat. Unten sehen Sie 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, verwende 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 $ -i /root/.ssh/id_rsa "$DOMBAC - $" > "/data/backup/$DDAY/$_$_FULL.tgz"  let processed+=1; done < paths 

Dies funktioniert gut, jedoch wird Schritt für Schritt von Maschine zu Maschine verarbeitet. Die Hosts sind ziemlich überlastet und das Netzwerk ist hier kein Problem, daher wollte ich dies so weit wie möglich parallelisieren. Führen Sie zum Beispiel vier Instanzen des Befehls tar auf jedem Host aus und leiten Sie die Ausgabe über ssh in eine ordnungsgemäß benannte Datei. Ich habe mich mit Parallelen völlig verirrt --results --sshloginfile... Und letztendlich versuche ich, vier Jobs auf jedem Host auszuführen, jeder mit unterschiedlichen Parametern (so dass Host 2 beispielsweise nicht überschreibt, was Host 1 bereits getan hat). . Kann dies in GNU Parallel gemacht werden?

1

2 Antworten auf die Frage

1
Ole Tange

Zuerst müssen Sie wissen, wie Sie mehrere Argumente aus einer einzigen Eingabezeile extrahieren:

cat paths | parallel --colsep ' ' echo == 

(Ich stelle fest, dass einige der aus generiert werden können. Wenn dies immer der Fall ist, möchten Sie vielleicht {= =} betrachten; dies ist jedoch eine Geschichte für eine andere Frage.)

Um Jobs remote auszuführen, verwenden Sie -S:

cat paths | parallel --colsep ' ' -S server echo == 

So steuern Sie, wie viele Jobs auf einem Remote-Server ausgeführt werden -j:

cat paths | parallel --colsep ' ' -j4 -S server echo == 

Die lokal gespeicherte Ausgabe --return --cleanupkann verwendet werden:

cat paths | parallel --return --cleanup --colsep ' ' -j4 -S server echo == '>' 

Da Sie die Ausgabe lokal in einem anderen Verzeichnis speichern möchten, müssen Sie den Trick /./ verwenden:

cat paths | parallel --return my/local/dir/./ --cleanup --colsep ' ' -j4 -S server echo == '>' 

Um einen speziellen sshBefehl zu verwenden, verwenden Sie --ssh:

parallel --ssh "ssh -i $HOME/.ssh/id_rsa.pub -lroot" --return --cleanup --colsep ' ' -j4 -S server echo == '>' 

Verwenden Sie --slffür die Ausführung auf mehreren Servern anstelle von -S:

parallel --slf hosts.txt --ssh "ssh -i $HOME/.ssh/id_rsa.pub -lroot" --return --cleanup --colsep ' ' -j4 echo == '>' 

Ihr Befehl könnte also insgesamt so aussehen:

parallel --slf hosts.txt --ssh "ssh -i $HOME/.ssh/id_rsa.pub -lroot" --return /data/backup/$DDAY/./_$_FULL.tgz --cleanup --colsep ' ' -j4 "$DOMBAC - > _$_FULL.tgz" 
Stack Overflow-Kommentare eignen sich nicht für die gemeinsame Nutzung von Code und Diskussionen;) Wie auch immer - ich muss Ihre Lösung ausprobieren. Meine jetzige (grobe) hängt von zwei Dingen ab: `parallel -j $ --link ./do_on_hosts.sh " $ DATA "" $ DDAY ":::: workers.host :: :: to_backup.path` und in do_on_hosts.sh: `ssh $ 1" $ $ "> $ $ / $ _ $ _FULL.tgz` Ich frage mich, wie das mit Ihrer vergleichbar ist ... Sie brauchen eine weitere Runde, um es auszuprobieren. Johnny_Bit vor 7 Jahren 0
0
Argonauts

Sie könnten parallel dazu verwenden, aber ich denke, es wäre übertrieben für das, was Sie zu erreichen versuchen. 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 Sie lediglich die einzelnen Aufgaben während der Ausführung im Hintergrund ausführen (mit dem Operator & dazu). Um verwaiste Prozesse zu verhindern, sollten Sie sicherstellen, dass das Skript nicht beendet wird, bis alle Jobs abgeschlossen sind wait. Dies wird mit dem bash Builtin ausgeführt . Der Befehl jobs gibt eine Liste der ausgeführten Tasks aus (möglicherweise nicht alle, möglicherweise sind einige bereits erledigt, bevor Sie diese Stelle je nach Ausführungszeit erreichen).

Ich bin mir auch nicht sicher, warum Sie den Befehl nice ohne Argument verwenden. Ich glaube, ohne Argument wird nur die relative Priorität der gestarteten Task gedruckt, die Ihrer Meinung nach Ihre Absicht sein könnte.

Hier ist eine modifizierte Version Ihres Skripts mit diesen Änderungen

#!/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 $ -i /root/.ssh/id_rsa "$DOMBAC - $" > "/data/backup/$DDAY/$_$_FULL.tgz" &  let processed+=1; done < paths jobs wait 
Hallo! Ich habe es geschafft, dies mithilfe von gnu parallel zu parallelisieren. Allerdings muss ich warten, um sicherzustellen, dass meine Lösung ordnungsgemäß funktioniert. Im Kommentar zur vorgeschlagenen Lösung - nun, ich brauche eigentlich GNU Parallel - sonst würden Worker-Hosts mit Aufgaben gespammt und könnten nicht fertig werden. Stellen Sie sich vor, die Hosts-Datei hat eher 4-8 Einträge, Pfade 10-20 Tausend Pfade. Was "nett" ist - ohne Argumente ändert sich die Freundlichkeit von 0 bis 10 :) Johnny_Bit vor 7 Jahren 0
Ich habe auf der Manpage nach http://man7.org/linux/man-pages/man1/nice.1.html gesucht Argonauts vor 7 Jahren 0
Veröffentlichen Sie Ihre Lösung mithilfe von parallelen Möglichkeiten, wenn dies möglich ist, sodass jemand, der danach sucht, sie findet Argonauts vor 7 Jahren 0