Problem z aplikacją klient-serwer i gniazdami

0

Mam aplikację, która przetwarza pewne dane, jednak ze względu na wykładniczą złożoność zaimplementowanych w nim algorytmów program działa długo - dla "dużych" danych nawet kilka dni). W związku z powyższym zacząłem pisać aplikację, która wykonywałaby obliczenia w sposób rozproszony, gdyż algorytmy te dają się zrównoleglić. Jednak napotkałem tu kilka problemów.

Aplkacja ta ma działać teraz tak, że użytkownik, w programie będącym klientem, wczytuje dane, ustawia parametry algorytmu oraz wybiera sam algorytm do przetwarzania tych danych. Następnie wysyła te wszystkie informacje do serwera, do którego podłączone są inne komputery wykonujące obliczenia (workery). Po otrzymaniu danych serwer dzieli je i przesyła odpowiednie porcje do workerów, zbiera wyniki i odsyła do klienta.

Napisałem już kilka prostych programików z użyciem komponentów Indy (TIdTCPClient, TIdTCPServer), tesujących pewne mechanizmy, typu klient coś wysyła, a serwer mu odpowiada, itp. Jednak nadal nie wiem jak zrobić następujące rzeczy:

Problem 1.
Czy komponenty, które wybrałem do realizacji tego zadania są odpowiednie? Czy lepsze byłyby jakieś inne?

Problem 2.
Gdy klient wyśle do serwera informacje o zadaniu do wykonania i niezbędne dane, ma czekać na odpowiedź serwera, która może nadejść po kilku godzinach. Czy dobrym rozwiązaniem jest zapamiętać klienta (jego IP i port na którym będzie nasłuchiwał), rozłączyć się i ponownie połączyć gdy wyniki będą już gotowe, czy też lepiej trzymać to połączenie z jakiś względów?

Problem 3.
Jeśli z jakiś względów chciałbym trzymać połączenie klienta z serwerem, to jak to zrobić? Obecnie zdecydowałem się na taki wariant, że gdy klient łączy się z serwerem, to kod zawierający co ma odpowiedzieć serwer jest w metodzie obsługującej zdarzenie OnExecute komponentu TIdTCPServer. Co się dzieje, gdy ta metoda skończy się wykonywać, (bo w jej trakcie uruchomię np. nowy wątek)? Czy tracę wtedy możliwość skomunikowania się z klientem? A jak nie to jak coś ponownie do niego wysłać?

Problem 4.
Co z komputerami które wykonują zlecone zadania. Czy po zgłoszeniu się do serwera ma on trzymać każde z połączeń przez cały czas pracy, i dopiero wysyłać im coś jak będzie dla nich gotowe zadanie? Czy jest jakiś lepszy sposób?
Jeśli nie, to czy przy kilkudziesięciu workerach nie wystąpi jakiś problem? Czy po stworzeniu po jednym wątku przez serwer dla każdego z połączeń nie zwolni to znacznie jego pracy (nie mówiąc już o przesyłaniu czegokolwiek)? Jaka jest optymalna (ze względów wydajnościowych) maksymalna liczba połączeń?

Problem 5.
Byłbym wdzięczny za polecenie jakiejś literatury lub stron opisujących te problemy, bo na razie na takie niestety nie natrafiłem - większość zawiera banalne przykłady typu jak połączyć dwa komputery.

0
ArtP napisał(a)

Problem 1.
Czy komponenty, które wybrałem do realizacji tego zadania są odpowiednie? Czy lepsze byłyby jakieś inne?

Ja bym wybrał Synapse (dodatek VisualSynapse opakowuje Synapse w komponenty) - jest przenośny na wszystko na czym działa ObjectPascal, masz pełne źródła a free i z tego co sam zauważyłem masz dużo większ kontrolę nad tym co się dzieje

Problem 2.
Gdy klient wyśle do serwera informacje o zadaniu do wykonania i niezbędne dane, ma czekać na odpowiedź serwera, która może nadejść po kilku godzinach. Czy dobrym rozwiązaniem jest zapamiętać klienta (jego IP i port na którym będzie nasłuchiwał), rozłączyć się i ponownie połączyć gdy wyniki będą już gotowe, czy też lepiej trzymać to połączenie z jakiś względów?

ja bym wybrał bramkę nr 3 :) - ani jedno ani drugie. Adres klienta może się zmienić i co wtedy? Utrzymywanie długich połączeń też nie jest dobre, a jak klient się przeresetuje albo straci połączenie w inny sposób to co wtedy? Ja bym ustawił jakiś czas - np. co 10 minut klient łączył by się z serwerem i "pytał" czy są już dane dla niego.

Problem 3.
Jeśli z jakiś względów chciałbym trzymać połączenie klienta z serwerem, to jak to zrobić? Obecnie zdecydowałem się na taki wariant, że gdy klient łączy się z serwerem, to kod zawierający co ma odpowiedzieć serwer jest w metodzie obsługującej zdarzenie OnExecute komponentu TIdTCPServer. Co się dzieje, gdy ta metoda skończy się wykonywać, (bo w jej trakcie uruchomię np. nowy wątek)? Czy tracę wtedy możliwość skomunikowania się z klientem? A jak nie to jak coś ponownie do niego wysłać?

patrz pkt 2

Problem 4.
Co z komputerami które wykonują zlecone zadania. Czy po zgłoszeniu się do serwera ma on trzymać każde z połączeń przez cały czas pracy, i dopiero wysyłać im coś jak będzie dla nich gotowe zadanie? Czy jest jakiś lepszy sposób?
Jeśli nie, to czy przy kilkudziesięciu workerach nie wystąpi jakiś problem? Czy po stworzeniu po jednym wątku przez serwer dla każdego z połączeń nie zwolni to znacznie jego pracy (nie mówiąc już o przesyłaniu czegokolwiek)? Jaka jest optymalna (ze względów wydajnościowych) maksymalna liczba połączeń?

patrz pkt. 2

Problem 5.
Byłbym wdzięczny za polecenie jakiejś literatury lub stron opisujących te problemy, bo na razie na takie niestety nie natrafiłem - większość zawiera banalne przykłady typu jak połączyć dwa komputery.

jeśli jeszcze nie byłeś to polecam http://klepisko.eu.org/~bartek/bgnet/

1 użytkowników online, w tym zalogowanych: 0, gości: 1