Pytanie Pisząc równoległe ramy programistyczne, co przeoczyłem?


Wyjaśnienie: Zgodnie z niektórymi komentarzami, powinienem wyjaśnić, że ma to być proste ramy umożliwiające wykonanie programów, które są naturalnie równolegle (tak zwane żenująco równoległe programy). Nie jest i nigdy nie będzie rozwiązaniem dla zadań wymagających komunikacji lub synchronizacji pomiędzy procesami.

Szukałem w Pythonie prostego, opartego na procesach, równoległego środowiska programistycznego, które może wykonywać funkcje na wielu procesorach w klastrze, przy czym głównym kryterium jest to, że musi on wykonywać niezmodyfikowany kod Pythona. Najbliższe, jakie znalazłem, było Równoległy Python, ale pp robi całkiem fajne rzeczy, które mogą spowodować, że kod nie zostanie wykonany we właściwym kontekście (z odpowiednimi modułami zaimportowanymi itp.).

W końcu zmęczyłem się szukaniem, więc postanowiłem napisać własną. To, co wymyśliłem, jest całkiem proste. Problem polega na tym, że nie jestem pewien, czy to, co wymyśliłem, jest proste, ponieważ nie potrafiłem wymyślić wielu rzeczy. Oto, co robi mój program:

  • Mam serwer zadań, który przekazuje zadania do węzłów w klastrze.
  • Zadania są przekazywane serwerom nasłuchującym na węzłach za pomocą słownika, który wygląda następująco:

    {
    'moduleName':'some_module', 
    'funcName':'someFunction', 
    'localVars': {'someVar':someVal,...}, 
    'globalVars':{'someOtherVar':someOtherVal,...}, 
    'modulePath':'/a/path/to/a/directory', 
    'customPathHasPriority':aBoolean, 
    'args':(arg1,arg2,...), 
    'kwargs':{'kw1':val1, 'kw2':val2,...}
    }
    
  • moduleName i funcName są obowiązkowe, a pozostałe są opcjonalne.

  • Serwer węzłowy wykonuje ten słownik i wykonuje:

    sys.path.append(modulePath)
    globals()[moduleName]=__import__(moduleName, localVars, globalVars)
    returnVal = globals()[moduleName].__dict__[funcName](*args, **kwargs)
    
  • Po otrzymaniu wartości zwracanej serwer wysyła ją z powrotem do serwera zadań, który umieszcza go w kolejce wątków.

  • Po zwrocie ostatniego zadania serwer zadań zapisuje dane wyjściowe do pliku i kończy pracę.

Jestem pewien, że istnieją pewne niedociągnięcia, które należy opracować, ale czy jest coś oczywistego w tym podejściu? Na pierwszy rzut oka wygląda to na solidne, wymagające tylko tego, aby węzły miały dostęp do systemów plików zawierających plik .py i zależności. Za pomocą __import__ ma tę zaletę, że kod w module jest uruchamiany automatycznie, a więc funkcja powinna być wykonywana we właściwym kontekście.

Wszelkie sugestie lub krytyka będą bardzo mile widziane.

EDYTOWAĆ: Powinienem wspomnieć, że mam działający bit kodu, ale serwer i serwer zadań muszą jeszcze zostać napisane.


16
2017-11-01 22:40


pochodzenie


To jest bardzo ambitne. Czy możesz zmienić to w pytanie? - Rafe Kettler
Lepszy? <15 znaków> - Chinmay Kanchi
@Katriealex: Nie, pp zdecydowanie nie robi tego, co chcę. Spędziłem tygodnie, próbując zepsuć mój program do paradygmatu pp i ciągle wpadając na bug po błędzie. pp ma kilka bardzo dziwnych problemów. Na przykład kilka błędów z import instrukcje występują głęboko w bibliotekach numpy bez wyraźnego powodu. Myślę, że problem polega na tym, że pp próbuje wykonać funkcję w "czystym" środowisku i oczekuje, że wyraźnie określisz wszystkie moduły, od których twój kod jest zależny, jaki kod instalacyjny musi zostać wywołany itd. Pisanie trywialnych programów z pp jest łatwe piszę te niebiańskie ciężko. - Chinmay Kanchi
Nie jestem pewien, co to będzie za miejsce, ale czy mógłbyś wyjaśnić, dlaczego pp nie robi tego, czego chcesz? Jestem zdezorientowany twoim komentarzem; czy pp działa inaczej niż to, czego oczekujesz, czy nie działa tak, jak jest reklamowane? Teraz dławi mnie jakiś kod pp, chciałbym usłyszeć więcej o jego problemach i o tym, jak to działa. Edycja: wiem, jakie było właściwe miejsce; inne pytanie! Zadam to teraz. - Thomas
Serwer zadań (w twoim podejściu, a także w dzbanku) może stać się wąskim gardłem, jeśli istnieje wiele węzłów klastra. - Sven Marnach


Odpowiedzi:


Napisałem coś, co prawdopodobnie zaspokoi Twoje potrzeby: dzbanek. Jeśli to nie rozwiąże twoich problemów, obiecuję ci, że naprawię wszystkie znalezione błędy.

Architektura jest nieco inna: pracownicy wszyscy uruchamiają ten sam kod, ale skutecznie generują podobny słownik i pytają centralnego backendu "czy to zostało uruchomione?". Jeśli nie, uruchamiają go (jest też mechanizm blokujący). Backend może być po prostu systemem plików, jeśli korzystasz z systemu NFS.


8
2017-11-01 23:42



Wygląda to bardzo interesująco. Rzucę okiem i dam ci znać, jak to działa! - Chinmay Kanchi
Niestety, ponieważ dzban kontroluje uruchamianie pracowników, nie jest to dla mnie dobre rozwiązanie. Klaster, którego przede wszystkim używam, używa Sun GridEngine do planowania zadań i nie mogę pozwolić, aby procesy były inicjowane poza harmonogramem SGE. - Chinmay Kanchi
To powinno działać. Po prostu uruchamiasz zadania "dzbanek do wykonania" za pomocą programu do planowania SGE (to jest konfiguracja, której używam osobiście!). Działa nawet wtedy, gdy zadania zaczynają się w różnym czasie. - luispedro
W porządku, musiałem źle zrozumieć dokumentację. Nie miałem czasu, aby zwrócić na siebie uwagę, na którą zasługuje, pracowałem nad czymś innym ... - Chinmay Kanchi
Przepraszam za bounty, ale założyłem, że jeśli nie było lepszej odpowiedzi, trafiłoby do ciebie. Tak było kiedyś. I tak przyjmuję twoją odpowiedź ... - Chinmay Kanchi


Ja sam majstrowałem przy manipulowaniu partiami na moich komputerach, a moim największym problemem był fakt, że niektóre rzeczy nie dają się łatwo lub natywnie zbierać i transmitować w sieci.

na przykład: powierzchnie pygame nie marszczą się. te muszę przekonwertować na ciągi, zapisując je w obiektach StringIO, a następnie przesyłając je przez sieć.

Jeśli dane, które przekazujesz (np. Twoje argumenty) mogą być przesyłane bez strachu, nie powinieneś tego robić że wiele problemów z danymi sieciowymi.

Przychodzi mi na myśl kolejna rzecz: co planujesz zrobić, gdy komputer nagle "znika" podczas wykonywania zadania? podczas zwracania danych? masz plan ponownego wysyłania zadań?


5
2017-11-01 23:03



Tak, zastanawiałem się nad podstawowym odpytywaniem każdego węzła co każde "x" sekund i jeśli węzeł nie odpowie na kolejne "y" kolejne ankiety, aby wysłać zadanie do pierwszego węzła, który się zakończył lub alternatywnie odradzać nowy proces serwera inny węzeł (alternatywa do podjęcia zostanie określona przez użytkownika). Potrzebuję również rozsądnego sposobu obsługi błędów i / lub wyjątków, które występują w węzłach. - Chinmay Kanchi
Jak radzić sobie z argumentami "nie do podrobienia" to dobre pytanie, a podejrzewam, że nie ma ogólnej odpowiedzi. Dobrym pomysłem może być napisanie programu obsługi podstawowej, który po prostu odpryskuje argumenty, ale pozwala na jego podklasę dla specjalnych przypadków. - Chinmay Kanchi