Jak równolegle uruchamiać skrypty na zdalnym komputerze?

16

Mogę ssh na zdalnej maszynie, która ma 64 rdzenie. Powiedzmy, że muszę uruchomić 640 skryptów powłoki równolegle na tym komputerze. Jak mam to zrobic?

Widzę podział 640 skryptów na 64 grupy, każdy po 10 skryptów. Jak miałbym następnie uruchomić każdą z tych grup równolegle , tj. Jedną grupę na każdym z dostępnych rdzeni.

Czy skrypt formularza

    ./script_A &
    ./script_B &
    ./script_C &
    ...

gdzie script_Aodpowiada pierwszej grupie, script_Bdrugiej grupie itp., wystarczy?

Skrypty w obrębie jednej grupy działające na jednym rdzeniu mogą działać sekwencyjnie, ale chcę, aby grupy działały równolegle na wszystkich rdzeniach.

Tomek
źródło
Nie ma gwarancji, że zostaną one równomiernie rozmieszczone przez rdzenie. Spójrz na ten wątek. stackoverflow.com/questions/13583146/…
Rui F Ribeiro

Odpowiedzi:

24

To wygląda jak zadanie dla GNU równoległego:

parallel bash -c ::: script_*

Zaletą jest to, że nie musisz grupować skryptów według rdzeni, parallelzrobi to za Ciebie.

Oczywiście, jeśli nie chcesz opiekować się sesją SSH podczas działania skryptów, powinieneś użyć nohuplubscreen

Dmitrij Grigoriew
źródło
To dobra odpowiedź i akceptuję ją, ponieważ w ogólnym przypadku zadziałałoby to dobrze. Niestety dla mnie osobiście nie mam uprawnień administratora do zdalnego komputera, więc nie mogę zainstalować parallelpakietu. Dzięki`
Tom
10
Nie musisz instalować równolegle globalnie: powinieneś być w stanie uruchomić kopię z własnego katalogu domowego.
dhag
bash -cmogą być niepotrzebne: parallel ::: ./script*. W przypadku skryptu 640 prawdopodobnie są one bardzo podobne (np. Różni się tylko argumentem). W tym celu rozważ bezpośrednie użycie GNU Parallel, aby ustawić te argumenty i użyć jednego skryptu.
Ole Tange
Jak zainstalować GNU równolegle na zdalnym komputerze?
Tom
@Tom Co zmienia się przez fakt, że korzystasz ze zdalnego komputera? Po prostu pobierz odpowiedni pakiet z gnu.org/software/parallel i zainstaluj.
Dmitrij Grigoriew
5

Będzie to działać tak długo, jak nie będziesz musiał monitorować wyników i nic ci nie będzie, pozostawiając otwartą sesję ssh tak długo, jak długo będą działać skrypty. Jeśli jedno z tych nie jest prawdą, polecam używanie screenwielu kart. Możesz zrobić coś takiego

screen
for script in script_A script_B script_C; do
  screen -t "$script" ./$script
done;
David King
źródło
Monitorowanie wyników, które mnie nie dotyczą - nie chciałbym pozostawić otwartej sesji ssh. Co z używaniem nohup? Zapobiegnie to zatrzymaniu skryptów, jeśli sesja zostanie zakończona. Nie? Spojrzę również na twoją rekomendację ekranową. Dzięki!'
Tom
nohupprawdopodobnie by działał, jestem po prostu bardziej zaznajomiony z screennim i ma o wiele więcej funkcji, które mogą, ale nie muszą być przydatne.
David King,
2

Aby rozpocząć i zarządzać dużą liczbą zadań skryptowych, będziesz potrzebować pewnego rodzaju oprogramowania zarządzającego do kontrolowania wykorzystania zasobów (procesor, pamięć, priorytet), sprawdzania statusu zadania (czekanie, zawieszanie, uruchamianie, zakończenie).

Silnik Grid jest zbudowany dla tego, na przykład, Sun Grid Engine ( http://wiki.gridengine.info/wiki/index.php/Main_Page ) lub Open Grid Scheduler ( http://gridscheduler.sourceforge.net/ ). Potrzebujesz administratora, aby zainstalować odpowiednie oprogramowanie, zanim zaczniesz. Administrator może to zrobić, zamiast widzieć setki procesów uruchomionych na komputerze i nie mieć nad nimi kontroli.

Zasadniczo administrator określa, ile gniazd można podzielić na maszynę, a następnie przesyłasz zadanie do kolejki i określasz liczbę miejsc, które zadanie ma zużyć, silnik sieci monitoruje ogólne użycie systemu i uruchamia zadanie zgodnie z zasady kolejkowania zdefiniowane przez administratora. np. nie więcej niż x zadań może być uruchomionych w tym samym czasie itp. pozostałe zadania będą w kolejce w stanie oczekiwania i zostaną zwolnione po zakończeniu wcześniejszych zadań.

użytkownik2912207
źródło
0

Robiłem to już przy wielu okazjach i zwykle po prostu rzucałem własny skrypt, aby wykonać zadanie z kontrolą zadań. Ogólnie, jeśli masz nazwy wszystkich skryptów, które chcesz uruchomić w pliku, rozwiązanie wygląda następująco:

#!/bin/bash
scripts=$(cat scriptfiles.txt)
declare -i NUM=0
declare -i MAX_PROCS=30
for script in "$scripts"
do
  NUM=$((NUM+1))
  ssh remote.host.ip "${script}" > ${script}.log 2>&1 &
  if [ $NUM -ge $MAX_PROCS ];then
    echo "Waiting for $NUM processes to finish."
    wait
    NUM=0
  fi
done
echo "Waiting for final $NUM processes to finish."
wait
exit

To brutalna siła, ale skuteczna. Ponadto nie potrzebujesz żadnego dodatkowego oprogramowania, takiego jak równoległe, dodawanego do swoich systemów.

Dużym problemem jest to, że polecenie czekania będzie czekać na zakończenie najwolniejszego skryptu, co może zmarnować czas. Stworzyłem skrypty, które radzą sobie z tą sytuacją, ale stają się bardziej złożone, jak możesz sobie wyobrazić. Jeśli wszystkie skrypty działają w tym samym czasie, działa to dobrze.

Innym problemem może być dostrojenie MAX_PROCS w celu ustalenia najlepszej wydajności.

Oczywiście liczba połączeń ssh może być niewygodna. W takim przypadku po prostu przenieś ten skrypt do zdalnego hosta i zmień wiersz „ssh ...”, aby bezpośrednio uruchomić skrypty.

OldTimer
źródło