Cloister → jednoduchá správa klastrov OTP

Takmer každá úspešná obchodná aplikácia sa skôr či neskôr dostane do fázy, keď je potrebné horizontálne škálovanie. V mnohých prípadoch stačí spustiť novú inštanciu a znížiť priemernú záťaž. Existujú však aj menej triviálne prípady, keď musíme zabezpečiť, aby sa rôzne uzly navzájom poznali a starostlivo rozdeľovali pracovnú záťaž.

Cloister → jednoduchá správa klastrov OTP

Šťastne sa stalo, že erlang, ktorý sme vybrali pre jeho príjemnú syntaxu a humbuk okolo, má vynikajúcu podporu pre distribuované systémy. V teórii to znie úplne triviálne:

Prenos správ medzi procesmi na rôznych uzloch, ako aj medzi odkazmi a monitormi je priehľadný […]

V praxi je všetko trochu zložitejšie. Distribuovaný erlang bol vyvinutý v čase, keď 'kontajner' znamenal obrovskú plechovku na prepravu a 'docker' bol len synonymom prístavného nákladníka. V IP4 bolo veľa nevyužitých adries, v sieťových prestojích - zvyčajne boli na vine potkany, ktoré prehryzli kábel, a priemerná doba bezporuchového chodu výrobných systémov sa merala v desaťročiach.

Teraz sme všetci nepredstaviteľne samostatní, zbalení a spúšťame distribuovaný erlang v prostredí, kde sa dynamické IP adresy prideľujú na základe veľkej náhody a uzly môžu prichádzať a odchádzať podľa želania ľavej päty plánovača. Aby sa predišlo hromade šablónového kódu v každom projekte, ktorý spúšťa distribuovaný erlang, na boj proti nepriateľskému prostrediu, potrebujeme pomoc.

Poznámka: viem, že existuje libcluster. Je naozaj skvelý, má viac ako tisíc hviezd, autor je známy v komunite a podobne. Ak vám stačia navrhnuté spôsoby, ako vytvoriť a udržiavať klaster pomocou tohto balíka - teším sa za vás. Mne, žiaľ, treba oveľa viac. Chcem riadiť konfiguráciu do detailov a nebyť divákom v divadle preformovania klastrov.

Požiadavky

Čo som potreboval osobne, bola knižnica, ktorá prevezme správu klastrov a bude mať nasledujúce vlastnosti:

  • priehľadná práca s pevne zakódovaným zoznamom uzlov aj s dynamickým objavovaním cez služby erlang;
  • plnohodnotný callback pri každej zmene topológie (uzol tam, uzol sem, nestabilita siete, rozdelenia);
  • priehľadné rozhranie na spustenie klastra s dlhými a krátkymi názvami, ako aj s :nonode@nohost;
  • podpora Dockeru priamo z krabice, bez potreby písať infraštruktúrny kód.

To znamená, že po tom, čo som testoval aplikáciu lokálne v :nonode@nohost, alebo v umele distribuovanom prostredí pomocou test_cluster_task, chcem jednoducho spustiť docker-compose up --scale my_app=3 a vidieť, ako vykonáva tri inštancie v Dockeri bez akýchkoľvek zmien kódu. Chcem, aby tiež závislé aplikácie, ako napríklad mnesia — keď sa topológia mení, aby sa klaster prestaval za kulisami bez akéhokoľvek dodatočného podnetu zo strany aplikácie.

Cloister nebol zamýšľaný ako knižnica, ktorá by dokázala všetko: od podpory klastra až po prípravu kávy. Nie je to strieborná guľka, ktorá by sa snažila pokryť všetky možné prípady, ani byť akademicky kompletným riešením v zmysle, ktorý teoretici z CS vkladajú do tohto výrazu. Táto knižnica má slúžiť na veľmi jasný cieľ, ale vykonávať svoj malý objem práce dokonale. Tento cieľ spočíva v zabezpečení úplnej transparentnosti medzi lokálnym vývojovým prostredím a distribuovaným elastickým prostredím, plným nepriateľských kontajnerov.

Vybratý prístup

Cloister sa má spustiť ako aplikácia, hoci skúsení používatelia môžu pracovať so zostavením a údržbou klastra ručne, priamo spustením Cloister.Manager v strome supervízorov cieľovej aplikácie.

Pri spustení ako aplikácia sa knižnica spolieha na config, odkiaľ načíta nasledujúce základné hodnoty:

config :cloister,
  otp_app: :my_app,
  sentry: :"cloister.local", # alebo ~w|n1@foo n2@bar|a
  consensus: 3,              # počet uzlov, ktoré sa berú do úvahy
                             #    klaster je online
  listener: MyApp.Listener   # listener, ktorý sa má zavolať, keď
                             #    sa kruh zmení

Parametre vyššie znamenajú doslovne nasledujúce: Cloister používa sa pre OTP aplikáciu :my_app, využíva erlang service discovery na pripojenie uzlov, minimálne troch, a MyApp.Listener modul (implementujúci @behaviour Cloister.Listener) je nastavený na prijímanie oznámení o zmenách topológie. Podrobné opisy celej konfigurácie nájdete v dokumenácie.

Pri tejto konfigurácii sa aplikácia Cloister bude spúšťa po etapách., odkladajúc proces spustenia hlavnej aplikácie do dosiahnutia konsenzu (tri uzly sú pripojené a prepojené, ako v uvedenom príklade.) To poskytuje hlavnej aplikácii možnosť predpokladať, že keď sa spustí, klaster je už dostupný. Pri každej zmene topológie (ich bude veľa, pretože uzly sa nespúšťajú úplne synchronne) sa spustí obslužná rutina MyApp.Listener.on_state_change/2. V väčšine prípadov vykonávame akciu, keď dostaneme správu o stave %Cloister.Monitor{status: :up}, čo znamená: „ahoj, klaster je zložený“.

V väčšine prípadov nastavenie consensus: 3 je optimálne, pretože aj keď očakávame, že sa pripojí viac uzlov, spätné volanie prejde cez status: :rehashing → status: :up na akomkoľvek novom pridanom alebo odstránenom uzle.

Pri spúšťaní v režime vývoja stačí len nastaviť consensus: 1 a Cloister s radosťou preskočí očakávanie zostavenia klastra, keď uvidí :nonode@nohost, alebo :node@host, alebo :node@host.domain — v závislosti od toho, ako bol uzol nastavený (:none | :shortnames | :longnames).

Správa distribuovaných aplikácií

Distribuované aplikácie nie sú vo vákuu a zvyčajne zahŕňajú aj rozdelené závislosti, ako mnesia. Ľahko ich spracovávame z rovnakého spätného volania on_state_change/2. Tu je napríklad podrobný popis, ako prekonfigurovať mnesia za behu v dokumenácie Cloister.

Hlavnou výhodou používania Cloister je to, že vykonáva všetky potrebné operácie pre prestavbu klastra po zmene topológie pod kapotou. Aplikácia sa jednoducho spúšťa v už pripravenom rozdelenom prostredí, so všetkými pripojenými uzlami, bez ohľadu na to, či poznáme IP adresy a teda aj mená uzlov vopred, alebo ak boli dynamicky priradené/zmenené. To si nevyžaduje žiadne špeciálne nastavenia konfigurácie Dockeru a z pohľadu vývojára aplikácií, nie je žiadny rozdiel medzi spustením v distribuovanom prostredí alebo lokálne na :nonode@nohost. Viac o tom si môžete prečítať v dokumenácie.

Napriek tomu, že zložitá správa zmien topológie je možná prostredníctvom vlastnej implementácie MyApp.Listener, vždy môžu existovať hraničné prípady, kedy sa tieto obmedzenia knižnice a predpojatý prístup k konfigurácii stanú kameňom úrazu pri implementácii. To je v poriadku, jednoducho si vezmite vyššie uvedené libcluster, ktorý je viac univerzálny, alebo dokonca spracujte klaster na nízkej úrovni sami. Cieľom tejto knižnice kódu nie je pokryť všetky možné scenáre, ale využiť najbežnejší scenár bez zbytočných bolestí a objemných kopírovaní a vkladaniu.

Poznámka: na tomto mieste v originále bola fráza „Happy clustering!“, a Yandex, ktorým prekladajú, (nebudem predsa listovať vo slovníkoch) mi navrhol variant „Šťastného zhlukovania!“. Lepšieho prekladu, asi najmä v súvislosti so súčasnou geopolitickou situáciou – si ani neviem predstaviť.

Zdroj: habr.com

Kúpte si spoľahlivý hosting pre webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Kúpte si spoľahlivý hosting pre webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster