Programowanie równoległe w Erlangu, część 2

09.11.2010 - Marek Materzok
TrudnośćTrudność

Programowanie rozproszone

Potrafimy już uruchamiać równolegle pracujące procesy na jednym komputerze. Czasem jednak dobrze jest, aby różne procesy jednego programu pracowały na różnych komputerach - na przykład dlatego, że pojedynczy komputer nie ma wystarczającej wydajności, albo jeśli potrzebne zasoby (pliki, urządzenia...) znajdują się na różnych komputerach. Dzięki temu, że procesy w Erlangu nie współdzielą pamięci, w języku tym możliwe jest komunikowanie się ze zdalnym procesem tak samo wygodnie, jak z procesem lokalnym.

Na początek przygotujmy środowisko pracy. Przyjmijmy, że posiadamy dwa komputery, nazywające się kerulen i sungari, z prawidłowo skonfigurowanymi nazwami w DNS albo wpisanymi do pliku hosts. Uruchommy na obydwu komputerach interpreter za pomocą polecenia:

erl -sname test -setcookie abcdef

Opcja -sname ustala nazwę, pod jaką będzie funkcjonować w sieci właśnie uruchamiana instancja interpretera. Na jednym komputerze może pracować i komunikować się ze sobą kilka różnych instancji interpretera o różnych nazwach. (Istnieje również opcja -name, która różni się tylko tym, że identyfikatorem komputera staje się pełna nazwa komputera w DNS, np. kerulen.test.pl, zamiast kerulen.) Natomiast opcja -setcookie ustala ciasteczko - ciąg znaków, który musi być identyczny na wszystkich komunikujących się komputerach. Jest to prosta forma zabezpieczenia przed wdarciem się agresora do sieci komunikujących się interpreterów.

Na komputerze kerulen interpreter zgłosi się na przykład tak:

$ erl -sname test -setcookie abcdef
Erlang R13B02 (erts-5.7.3) [source] [rq:1] [async-threads:0] [hipe] 
[kernel-poll:false]

Eshell V5.7.3  (abort with ^G)
(test@kerulen)1>

Natomiast na sungari odpowie następująco:

$ erl -sname test -setcookie abcdef
Erlang R13B02 (erts-5.7.3) [source] [rq:1] [async-threads:0] [hipe] 
[kernel-poll:false]

Eshell V5.7.3  (abort with ^G)
(test@sungari)1> 

Jak widać, w prompcie interpretera pojawił się jego identyfikator sieciowy, składający się z dwóch członów - nazwy interpretera podanej przez -sname i skróconej nazwy komputera. Identyfikatory te będą przydatne na przykład do określenia, na którym interpreterze chcemy wykonać nowy proces. Również mając dany identyfikator już pracującego procesu Pid, możemy dowiedzieć się, na którym interpreterze on pracuje, wywołując funkcję node(Pid). Funkcja node() zaś zwraca identyfikator interpretera, na którym pracuje aktualnie wykonywany proces.

Na początek sprawdźmy, czy interpretery komunikują się ze sobą. W tym celu użyjemy funkcji net_adm:ping:

(test@kerulen)1> net_adm:ping(test@sungari).
pong
(test@kerulen)2> 

Wartość pong oznacza, że wskazany interpreter odpowiedział na komunikat testowy. W przypadku błędu komunikacji wynikiem będzie pang; jeśli Twój interpreter odpowiedział pang, najprawdopodobniej jest to wynikiem nieprawidłowej konfiguracji sieci.

Nowy proces na innym komputerze można uruchomić za pomocą dwuargumentowej odmiany spawn (i spawn_link): pierwszym argumentem jest wtedy identyfikator interpretera, na którym chcemy uruchomić nowy proces. Spróbujmy. Wykonajmy następujące polecenie na komputerze kerulen:

(test@kerulen)2> Pid = spawn(test@sungari, fun() -> io:write(node()) end).
test@sungari<5700.45.0>
(test@kerulen)3> node(Pid).
test@sungari
(test@kerulen)4>

Udało się! Nowo utworzony proces, wypisując nazwę swojego interpretera, wypisał test@sungari. Również funkcja node(Pid) odpowiedziała, że nowo utworzony proces znajduje się na sungari. Uruchomiliśmy proces na innym komputerze bez najmniejszego kłopotu!

Z procesem na zdalnym komputerze komunikujemy się dokładnie tak samo, jak z procesami lokalnymi: za pomocą instrukcji ! i receive, tak samo działa również obsługa błędów. Oczywiście ze względu na możliwość występowania problemów z połączeniem nie ma gwarancji, że wysłane komunikaty dotrą do zdalnego procesu, jednakże istnieje gwarancja, że jeśli dotrą, to w tej samej kolejności, w jakiej zostały wysłane. Dzięki temu programy działające w sposób rozproszony pisze się w Erlangu praktycznie tak samo, jak zwykłe programy równoległe.

Podsumowanie

Omówione w tym artykule cechy Erlanga - sprawna obsługa błędów, wymiana kodu w trakcie pracy programu i łatwe rozproszenie - nie są tylko ciekawostkami; dzięki nim możliwe jest łatwe budowanie programów skalowalnych, odpornych na awarie i o wysokim współczynniku dostępności, co w wielu zastosowaniach jest nie bez znaczenia. Języka Erlang użyto z powodzeniem do oprogramowania przełączników sieciowych (Ericsson AXD301), elementów sieci telefonii komórkowej (system GPRS Ericssona, SMS w T-Mobile), serwerów internetowych (m.in. ejabberd, serwer protokołu XMPP). Znaczenie języka Erlang, lub przynajmniej opisanych tu technik programowania, będzie prawdopodobnie rosnąć, w związku z czym czas poświęcony bliższemu zaznajomieniu z Erlangiem na pewno nie będzie stracony.

0
Twoja ocena: Brak

Copyright © 2008-2010 Wrocławski Portal Informatyczny

design: rafalpolito.com