Cloister → jednoduchá správa klastra OTP

Takmer každá úspešná obchodná aplikácia skôr či neskôr vstúpi do fázy, kedy je potrebné horizontálne škálovanie. V mnohých prípadoch môžete jednoducho spustiť novú inštanciu a znížiť priemernú záťaž. Ale existujú aj menej triviálne prípady, kedy musíme zabezpečiť, aby o sebe rôzne uzly vedeli a starostlivo rozložiť záťaž.

Cloister → jednoduchá správa klastra OTP

Ukázalo sa, že je to také šťastie Erlang, ktorý sme zvolili pre jeho príjemnú syntax a humbuk okolo neho, má prvotriedne podpora distribuovaných systémov. Teoreticky to znie úplne triviálne:

Prenos správ medzi procesmi na rôznych uzloch, ako aj medzi prepojeniami a monitormi je transparentný […]

V praxi je všetko trochu komplikovanejšie. Distribuované Erlang bol vyvinutý, keď „kontajner“ znamenal veľkú železnú krabicu na prepravu a „doker“ bol jednoducho synonymom pre pobrežného robotníka. IN IP4 bolo veľa neobsadených adries, výpadky siete boli zvyčajne spôsobené prežúvaním kábla potkanmi a priemerná doba prevádzky produkčného systému sa merala v desaťročiach.

Teraz sme všetci neuveriteľne sebestační, zabalení a fungujeme distribuovane Erlang v prostredí, kde sa dynamické IP adresy rozdávajú na princípe veľkej náhodnosti a uzly sa môžu objavovať a miznúť podľa rozmaru ľavej päty plánovača. Aby sa predišlo hromadám štandardných kódov v každom projekte, ktorý beží distribuované Erlangna boj s nepriateľským prostredím je potrebná pomoc.

Poznámka: Som si vedomý, že existuje libcluster. Je to fakt super, má to vyše tisíc hviezdičiek, autor je známy v komunite a tak ďalej. Ak vám stačia metódy, ktoré ponúka tento balík na vytvorenie a údržbu klastra, som za vás rád. Žiaľ, potrebujem oveľa viac. Chcem podrobne kontrolovať nastavenie a nebyť vonkajším divákom v divadle reorganizácie klastra.

Požiadavky

Osobne som potreboval knižnicu, ktorá by prevzala správu klastra a mala by nasledujúce vlastnosti:

  • transparentná práca s pevne zakódovaným zoznamom uzlov a dynamickým zisťovaním prostredníctvom služieb Erlang;
  • plne funkčné spätné volanie pre každú zmenu topológie (uzol tam, uzol tu, nestabilita siete, rozdelenia);
  • transparentné rozhranie na spustenie klastra s dlhými a krátkymi názvami, ako napr :nonode@nohost;
  • Podpora dockeru hneď po vybalení bez toho, aby ste museli písať kód infraštruktúry.

To druhé znamená, že potom, čo som aplikáciu otestoval lokálne v :nonode@nohost, alebo v umelo distribuovanom prostredí pomocou test_cluster_task, chcem len bežať docker-compose up --scale my_app=3 a uvidíte, ako vykoná tri inštancie v dockeri bez akýchkoľvek zmien kódu. Chcem tiež závislé aplikácie ako mnesia - keď sa zmení topológia, v zákulisí prebudujú klaster naživo bez akéhokoľvek ďalšieho kopu z aplikácie.

kláštor nebolo zamýšľané ako knižnica schopná všetkého od podpory klastra po prípravu kávy. Nie je to strieborná guľka, ktorá má za cieľ pokryť všetky možné prípady, alebo byť akademicky úplným riešením v zmysle, že teoretici z CS zaradiť do tohto termínu. Táto knižnica je navrhnutá tak, aby slúžila veľmi jasnému účelu, ale svoju nie príliš veľkú prácu plnila dokonale. Týmto cieľom bude poskytnúť úplnú transparentnosť medzi lokálnym vývojovým prostredím a distribuovaným elastickým prostredím plným nepriateľských kontajnerov.

Zvolený prístup

kláštor je určený na spustenie ako aplikácia, aj keď pokročilí používatelia môžu pracovať s montážou a údržbou klastra manuálne priamym spustením Cloister.Manager v strome dohľadu cieľovej aplikácie.

Pri spustení ako aplikácia sa knižnica spolieha na config, z ktorého načíta tieto základné hodnoty:

config :cloister,
  otp_app: :my_app,
  sentry: :"cloister.local", # or ~w|n1@foo n2@bar|a
  consensus: 3,              # number of nodes to consider
                             #    the cluster is up
  listener: MyApp.Listener   # listener to be called when
                             #    the ring has changed

Vyššie uvedené parametre znamenajú doslova nasledovné: kláštor používa sa na aplikáciu OTP :my_app, používa objavenie služby erlang na pripojenie uzlov, aspoň tri, a MyApp.Listener modul (implementácia @behaviour Cloister.Listener) je nakonfigurovaný na prijímanie upozornení o zmenách topológie. Podrobný popis kompletnej konfigurácie nájdete v dokumentáciu.

Pri tejto konfigurácii aplikácia kláštor vôle spustenie po etapách, čím sa oneskorí proces spustenia hlavnej aplikácie, kým sa nedosiahne konsenzus (sú spojené a prepojené tri uzly, ako v príklade vyššie.) To dáva hlavnej aplikácii príležitosť predpokladať, že keď sa spustí, klaster je už dostupný. Vždy, keď sa zmení topológia (bude ich veľa, pretože uzly sa nespúšťajú úplne synchrónne), zavolá sa handler MyApp.Listener.on_state_change/2. Väčšinu času vykonáme akciu, keď dostaneme správu o stave %Cloister.Monitor{status: :up}, čo znamená: „Dobrý deň, klaster je zostavený.“

Vo väčšine prípadov inštalácia consensus: 3 je optimálny, pretože aj keď očakávame pripojenie viacerých uzlov, spätné volanie prebehne status: :rehashingstatus: :up na akomkoľvek novo pridanom alebo odstránenom uzle.

Pri spustení vo vývojovom režime stačí nastaviť consensus: 1 и kláštor s radosťou preskočí čakanie na montáž klastra, keď uvidí :nonode@nohostAlebo :node@hostAlebo :[email protected] - v závislosti od toho, ako bol uzol nakonfigurovaný (:none | :shortnames | :longnames).

Správa distribuovaných aplikácií

Distribuované aplikácie nie vo vákuu zvyčajne zahŕňajú distribuované závislosti, ako napr mnesia. Je pre nás ľahké zvládnuť ich rekonfiguráciu z rovnakého spätného volania on_state_change/2. Tu je napríklad podrobný popis spôsobu prekonfigurovania mnesia za letu dokumentáciu kláštor.

Hlavná výhoda použitia kláštor spočíva v tom, že vykoná všetky potrebné operácie na prebudovanie klastra po zmene topológie pod kapotou. Aplikácia jednoducho beží v už pripravenom distribuovanom prostredí, so všetkými pripojenými uzlami bez ohľadu na to, či vopred poznáme IP adresy a teda názvy uzlov, alebo boli dynamicky priradené/zmenené. Nevyžaduje si to absolútne žiadne špeciálne konfiguračné nastavenia dockera a z pohľadu vývojára aplikácie nie je rozdiel medzi spustením v distribuovanom prostredí alebo spustením v lokálnom prostredí. :nonode@nohost. Viac si o tom môžete prečítať v dokumentáciu.

Aj keď komplexné spracovanie zmien topológie je možné prostredníctvom vlastnej implementácie MyApp.ListenerVždy sa môžu vyskytnúť okrajové prípady, keď sa tieto obmedzenia knižnice a odchýlky v konfigurácii ukážu ako základné kamene implementácie. To je v poriadku, vezmite si vyššie uvedené libcluster, ktorý je všeobecnejší, alebo dokonca sami zvládnete klaster nízkej úrovne. Cieľom tejto knižnice kódu nie je pokryť všetky možné scenáre, ale použiť najbežnejší scenár bez zbytočnej bolesti a ťažkopádneho kopírovania a vkladania.

Poznámka: v tomto bode originálu bola fráza „Happy clustering!“ a Yandex, pomocou ktorého prekladám (nemusím sám prechádzať slovníky), mi ponúkol možnosť „Happy clustering!“ Lepší preklad si snáď ani nemožno predstaviť, najmä vzhľadom na súčasnú geopolitickú situáciu.

Zdroj: hab.com

Pridať komentár