Cloister → jednoduchá správa clusteru OTP

Téměř každá úspěšná obchodní aplikace dříve nebo později vstoupí do fáze, kdy je vyžadováno horizontální škálování. V mnoha případech můžete jednoduše spustit novou instanci a snížit průměrnou zátěž. Existují ale i méně triviální případy, kdy potřebujeme zajistit, aby o sobě různé uzly věděly, a pečlivě rozdělit zátěž.

Cloister → jednoduchá správa clusteru OTP

Ukázalo se to tak šťastně získané, který jsme zvolili pro jeho příjemnou syntaxi a humbuk kolem něj, má prvotřídní podpora distribuovaných systémů. Teoreticky to zní úplně triviálně:

Předávání zpráv mezi procesy na různých uzlech, stejně jako mezi linkami a monitory, je transparentní […]

V praxi je vše trochu složitější. Distribuováno získané byl vyvinut, když „kontejner“ znamenal velkou železnou bednu pro přepravu a „docker“ byl jednoduše synonymem pro pobřežního dělníka. V IP4 bylo mnoho neobsazených adres, výpadky sítě byly obvykle způsobeny krysami, které přežvykovaly kabel, a průměrná doba provozuschopnosti produkčního systému se měřila v desetiletích.

Nyní jsme všichni neuvěřitelně soběstační, zabalení a fungujeme distribuovaně získané v prostředí, kde se dynamické IP adresy rozdávají na principu velké náhodnosti a uzly se mohou objevovat a mizet podle rozmaru levé paty plánovače. Abychom se vyhnuli hromadám standardního kódu v každém projektu běžícím distribuci získanépro boj s nepřátelským prostředím je nutná pomoc.

Poznámka: Jsem si vědom, že existuje libcluster. Je to fakt super, má to přes tisíc hvězdiček, autor je známý v komunitě a tak. Pokud vám metody, které tento balíček nabízí pro vytvoření a údržbu clusteru, stačí, jsem za vás rád. Bohužel potřebuji mnohem víc. Chci podrobně kontrolovat nastavení a nebýt vnějškem v divadle reorganizace klastrů.

Požadavky

Osobně jsem potřeboval knihovnu, která by převzala správu clusteru a měla by následující vlastnosti:

  • transparentní práce s pevně zakódovaným seznamem uzlů a dynamickým zjišťováním prostřednictvím služeb získané;
  • plně funkční zpětné volání pro každou změnu topologie (uzel tam, uzel zde, nestabilita sítě, rozdělení);
  • transparentní rozhraní pro spouštění clusteru s dlouhými a krátkými názvy, jako např :nonode@nohost;
  • Podpora dockeru ihned po vybalení, aniž byste museli psát kód infrastruktury.

To druhé znamená, že poté, co jsem aplikaci otestoval lokálně v :nonode@nohost, nebo v uměle distribuovaném prostředí pomocí test_cluster_task, chci jen běžet docker-compose up --scale my_app=3 a podívejte se, jak provádí tři instance v dockeru bez jakýchkoli změn kódu. Chci také závislé aplikace jako mnesia - když se změní topologie, v zákulisí znovu sestaví cluster naživo bez jakéhokoli dalšího kopání z aplikace.

Klášter nebylo zamýšleno jako knihovna schopná všeho od podpory klastru po přípravu kávy. Není to stříbrná kulka, která si klade za cíl pokrýt všechny možné případy, nebo být akademicky kompletním řešením v tom smyslu, že teoretici z CS zařadit do tohoto termínu. Tato knihovna je navržena tak, aby sloužila velmi jasnému účelu, ale svou nepříliš velkou práci plnila dokonale. Tímto cílem bude poskytnout úplnou transparentnost mezi místním vývojovým prostředím a distribuovaným elastickým prostředím plným nepřátelských kontejnerů.

Zvolený přístup

Klášter je určen ke spuštění jako aplikace, i když pokročilí uživatelé mohou pracovat se sestavováním a údržbou clusteru ručně přímým spuštěním Cloister.Manager ve stromu supervizora cílové aplikace.

Při spuštění jako aplikace se knihovna spoléhá na config, ze kterého vyčte tyto 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

Výše uvedené parametry znamenají doslova následující: Klášter používá se pro aplikaci OTP :my_app, používá objev služby erlang pro připojení uzlů, alespoň tři, a MyApp.Listener modul (implementace @behaviour Cloister.Listener) je nakonfigurován pro příjem upozornění o změnách topologie. Podrobný popis kompletní konfigurace naleznete v dokumentace.

S touto konfigurací aplikace Klášter vůle spuštění po etapách, což zpožďuje proces spouštění hlavní aplikace, dokud není dosaženo konsensu (tři uzly jsou připojeny a připojeny, jako ve výše uvedeném příkladu.) To dává hlavní aplikaci příležitost předpokládat, že když se spustí, cluster je již dostupný. Kdykoli se změní topologie (bude jich mnoho, protože uzly nezačínají zcela synchronně), bude zavolán handler MyApp.Listener.on_state_change/2. Většinu času provádíme akci, když obdržíme stavovou zprávu %Cloister.Monitor{status: :up}, což znamená: „Dobrý den, cluster je sestaven.“

Ve většině případů instalace consensus: 3 je optimální, protože i když očekáváme, že se připojí více uzlů, zpětné volání projde status: :rehashingstatus: :up na každém nově přidaném nebo odebraném uzlu.

Při spuštění ve vývojovém režimu stačí nastavit consensus: 1 и Klášter s radostí přeskočí čekání na sestavení clusteru, až uvidí :nonode@nohostNebo :node@hostNebo :[email protected] - podle toho, jak byl uzel nakonfigurován (:none | :shortnames | :longnames).

Distribuovaná správa aplikací

Distribuované aplikace, které nejsou ve vakuu, obvykle zahrnují distribuované závislosti, jako je např mnesia. Je pro nás snadné zvládnout jejich rekonfiguraci ze stejného zpětného volání on_state_change/2. Zde je například podrobný popis způsobu překonfigurování mnesia za letu dokumentace Klášter.

Hlavní výhoda použití Klášter spočívá v tom, že po změně topologie provede všechny nezbytné operace k opětovnému sestavení clusteru pod kapotou. Aplikace jednoduše běží v již připraveném distribuovaném prostředí, se všemi připojenými uzly, bez ohledu na to, zda předem známe IP adresy a tedy názvy uzlů, nebo byly dynamicky přiděleny/změněny. To nevyžaduje absolutně žádná speciální nastavení konfigurace dockeru a z pohledu vývojáře aplikace není rozdíl mezi spuštěním v distribuovaném prostředí nebo spuštěním v lokálním. :nonode@nohost. Více si o tom můžete přečíst v dokumentace.

I když komplexní zpracování změn topologie je možné prostřednictvím vlastní implementace MyApp.ListenerVždy se mohou vyskytnout okrajové případy, kdy se tato omezení knihovny a zkreslení konfigurace ukáží jako základní kameny implementace. To je v pořádku, vezměte si výše uvedené libcluster, což je obecnější účel, nebo dokonce sami zvládnete nízkoúrovňový cluster. Cílem této knihovny kódu není pokrýt všechny možné scénáře, ale použít nejběžnější scénář bez zbytečné bolesti a těžkopádného kopírování a vkládání.

Poznámka: v tomto bodě originálu byla fráze „Happy clustering!“ a Yandex, pomocí kterého překládám (nemusím sám procházet slovníky), mi nabídl možnost „Happy clustering!“ Lepší překlad si snad ani nelze představit, zvláště ve světle současné geopolitické situace.

Zdroj: www.habr.com

Přidat komentář