Cloister → jednostavno upravljanje OTP klasterom

Gotovo svaka uspješna poslovna aplikacija prije ili kasnije ulazi u fazu kada je potrebno horizontalno skaliranje. U mnogim slučajevima možete jednostavno pokrenuti novu instancu i smanjiti prosječno opterećenje. No, postoje i manje trivijalni slučajevi kada moramo osigurati da različite čvorove znaju jedni o drugima i pažljivo raspoređuju radno opterećenje.

Cloister → jednostavno upravljanje OTP klasterom

Uspješno se dogodilo da erlang, koji smo odabrali zbog lijepog sintaktičkog izraza i hypea oko njega, ima vrhunsku podršku za distribuirane sustave. U teoriji to zvuči trivijalno:

Prijenos poruka između procesa na različitim čvorovima, kao i između linkova i monitora, je transparentan […]

U praksi je sve malo složenije. Distribuirani erlang je razvijen kada je "kontejner" značio golemu željeznu kutiju za transport, a "docker" je bio samo sinonim za lučkog radnika. U IP4 je bilo mnogo neiskorištenih adresa, a mrežni prekidi su obično bili uzrokovani pacovima koji su pregrizli kabel, dok se prosječno vrijeme neprekidnog rada proizvodnog sustava mjerilo u desetljećima.

Sada smo svi neizmjerno samodostatni, zapakirani i pokrećemo distribuirani erlang u okruženju gdje se dinamičke IP adrese dodjeljuju prema principu velike slučajnosti, a čvorovi se mogu pojaviti i nestati prema želji lijeve pete planera. Kako bismo izbjegli hrpu šablonskog koda u svakom projektu koji pokreće distribuirani erlang, potrebna je pomoć za borbu protiv neprijateljskog okruženja.

Napomena: svjestan sam da postoji libcluster. To je stvarno super, ima više od tisuću zvjezdica, a autor je poznat u zajednici i sve to. Ako vam je dovoljno pristupa koje nudi ovaj paket za stvaranje i održavanje klastera - radujem se za vas. Nažalost, ja trebam daleko više. Želim upravljati podešavanjem u detalje i ne biti pasivni promatrač u kazalištu preoblikovanja klastera.

Zahtjevi

Ono što mi je osobno bilo potrebno jest biblioteka koja će preuzeti upravljanje klasterom i imati sljedeće značajke:

  • transparentan rad s čvrsto kodiranim popisom čvorova, kao i s dinamičkim otkrivanjem putem usluga erlang;
  • potpuni callback pri svakoj promjeni topologije (čvor ovamo, čvor onamo, nestabilnost mreže, podjele);
  • prozirno sučelje za pokretanje klastera s dugim i kratkim imenima, kao i s :nonode@nohost;
  • podrška za Docker iz kutije, bez potrebe za pisanjem infrastrukturnog koda.

To znači da, nakon što testiram aplikaciju lokalno u :nonode@nohost, ili u umjetno distribuiranom okruženju pomoću test_cluster_task, želim samo pokrenuti docker-compose up --scale my_app=3 i vidjeti kako izvorni kod pokreće tri instance unutar Dockera bez ikakvih promjena koda. Također želim da povezane aplikacije, poput mnesia — kada se topologija promijeni, u pozadini ponovo izgrade klaster uživo bez dodatnog poticaja od strane aplikacije.

Cloister nije zamišljen kao biblioteka sposobna za sve: od podrške klasteru do pravljenja kave. To nije srebrna metak koja teži obuhvatu svih mogućih slučajeva, niti je akademski potpuni okvir u smislu u kojem ga teoretičari iz CS shvaćaju. Ova biblioteka ima za cilj služiti vrlo jasno definiranoj svrsi, ali obavljati svoj mali opseg posla savršeno. Ta svrha će biti osiguravanje potpune transparentnosti između lokalnog razvojnog okruženja i distribuiranog elastičnog okruženja, punog neprijateljskih kontejnera.

Odabrani pristup

Cloister predviđa pokretanje kao aplikacija, iako iskusniji korisnici mogu raditi s izradom i održavanjem klastera ručno, pokretanjem Cloister.Manager u stablu nadzornika ciljne aplikacije.

Pri pokretanju kao aplikacije, biblioteka se oslanja na config, odakle čita sljedeće osnovne vrijednosti:

config :cloister,
  otp_app: :my_app,
  sentry: :"cloister.local", # ili ~w|n1@foo n2@bar|a
  consensus: 3,              # broj čvorova koje treba uzeti u obzir
                             #    klaster je aktivan
  listener: MyApp.Listener   # slušatelj koji će biti pozvan kada
                             #    prsten promijeni

Gore navedeni parametri znače doslovno sljedeće: Cloister koristi se za OTP aplikaciju :my_app, koristi erlang servisno otkrivanje za povezivanje čvorova, minimalno tri, i MyApp.Listener modul (implementira @behaviour Cloister.Listener) podešen je za primanje obavijesti o promjenama topologije. Detaljan opis potpune konfiguracije možete pronaći u dokumentaciju.

Uz ovu konfiguraciju, aplikacija Cloister bit će pokrenuta postupno, odgađajući proces pokretanja glavne aplikacije do postizanja konsenzusa (tri čvora su povezana i spojena, kao u danom primjeru.) Ovo omogućava glavnoj aplikaciji da pretpostavi da je klaster već dostupan kada se pokrene. Prilikom svake promjene topologije (njih će biti mnogo, jer čvorovi ne započinju potpuno sinkronizirano), pozvat će se obrada MyApp.Listener.on_state_change/2. U većini slučajeva izvršavamo akciju kada primimo poruku sa stanjem %Cloister.Monitor{status: :up}, što znači: „halo, klaster je sastavljen“.

U većini slučajeva, postavljanje consensus: 3 je optimalno, jer čak i ako očekujemo da će se povezati više čvorova, povratni poziv će prolaziti kroz status: :rehashing → status: :up na svakom novom dodanom ili uklonjenom čvoru.

Prilikom pokretanja u razvojnome modu, dovoljno je samo postaviti consensus: 1 i Cloister sretno će proći kroz čekanje na sastavljanje klastera, primijetivši :nonode@nohost, ili :node@host, ili :node@host.domain — ovisno o tome kako je čvor bio podešen (:none | :shortnames | :longnames).

Upravljanje distribuiranim aplikacijama

Distribuirane aplikacije obično ne postoje u vakuumu i uključuju distribuirane ovisnosti, poput mnesia. Lako ih možemo obraditi sponzorujući ih iz istog povratnog poziva on_state_change/2. Evo, na primjer, detaljan opis kako ih ponovno konfigurirati mnesia u letu u dokumentaciju Cloister.

Glavna prednost korištenja Cloister je u tome što izvodi sve potrebne operacije obnove klastera nakon promjene topologije ispod haube. Aplikacija se jednostavno pokreće u već pripremljenom distribuiranom okruženju, sa svim povezanim čvorovima, bez obzira znamo li unaprijed IP adrese i samim tim imena čvorova ili su dinamički dodijeljena/promijenjena. Ovo ne zahtijeva nikakva posebna podešavanja konfiguracije dockera i iz perspektive programera aplikacija, nema razlike između pokretanja u distribuiranom okruženju ili lokalno na :nonode@nohost. Više o tome možete pročitati u dokumentaciju.

Iako je složena obrada promjena topologije moguća putem vlastite implementacije MyApp.Listener, uvijek mogu postojati rubni slučajevi kada će ti ograničenja biblioteke i pristran pristup konfiguraciji postati kamen temeljac na putu implementacije. To je u redu, jednostavno preuzmite prethodno spomenuto libcluster, koji je univerzalniji, ili čak obradite klaster niskog nivoa sami. Cilj ove biblioteke koda nije obuhvatiti sve moguće scenarije, već koristiti najčešći scenarij bez nepotrebnih bolova i glomaznih kopija i umetanja.

Napomena: na ovom mestu u originalu je bila fraza „Happy clustering!“, a Yandex, koji prevodim (zar da pretražujem rečnike), predložio mi je opciju „Sretnog klasteriranja!“. Boljeg prevoda, verovatno, posebno u svetlu trenutne geopolitčke situacije — i ne može se zamisliti.

Izvor: habr.com

Kupite pouzdan hosting za web stranice s DDoS zaštitom, VPS VDS servere 🔥 Kupite pouzdan hosting za web stranice s DDoS zaštitom, VPS VDS servere | ProHoster