Cloister → management simplu cluster OTP

Aproape fiecare aplicație de afaceri de succes intră mai devreme sau mai târziu într-o fază în care este necesară scalarea orizontală. În multe cazuri, puteți pur și simplu să porniți o nouă instanță și să reduceți media de încărcare. Dar există și cazuri mai puțin banale în care trebuie să ne asigurăm că diferitele noduri se cunosc unul despre celălalt și că distribuim cu atenție volumul de lucru.

Cloister → management simplu cluster OTP

S-a dovedit atât de norocos încât erlang, pe care l-am ales pentru sintaxa plăcută și hype-ul din jurul său, are o clasă de primă clasă suport pentru sisteme distribuite. În teorie, acest lucru sună complet banal:

Trecerea mesajelor între procese pe diferite noduri, precum și între legături și monitoare, este transparentă […]

În practică, totul este puțin mai complicat. Distribuit erlang a fost dezvoltat atunci când „container” însemna o cutie mare de fier pentru transport maritim, iar „docker” era pur și simplu un sinonim pentru longshoreman. ÎN IP4 erau multe adrese neocupate, întreruperile de rețea erau cauzate de obicei de șobolanii care mestecau cablul, iar timpul mediu de funcționare al sistemului de producție a fost măsurat în decenii.

Acum suntem cu toții incredibil de autosuficienți, ambalate și difuzați erlang într-un mediu în care adresele IP dinamice sunt distribuite pe principiul aleatoriei mari, iar nodurile pot apărea și dispărea după pofta călcâiului stâng al planificatorului. Pentru a evita grămezile de cod standard în fiecare proiect care rulează o distribuție erlang, pentru combaterea mediului ostil este nevoie de ajutor.

Nota: Sunt conștient că există libcluster. E chiar tare, are peste o mie de stele, autorul este celebru în comunitate și toate astea. Dacă metodele oferite de acest pachet pentru crearea și întreținerea unui cluster sunt suficiente pentru tine, mă bucur pentru tine. Din păcate, am nevoie de mult mai mult. Vreau să controlez configurația în detaliu și să nu fiu un spectator extern în teatrul de reorganizare a clusterelor.

Cerințe

Ceea ce aveam personal era o bibliotecă care să preia gestionarea clusterului și să aibă următoarele proprietăți:

  • lucru transparent atât cu o listă de noduri codificată, cât și cu descoperire dinamică prin servicii erlang;
  • callback complet funcțional pentru fiecare schimbare de topologie (nodul de acolo, nodul de aici, instabilitatea rețelei, împărțiri);
  • interfață transparentă pentru lansarea unui cluster cu nume lungi și scurte, ca și cu :nonode@nohost;
  • Asistență Docker din cutie, fără a fi nevoie să scrieți cod de infrastructură.

Aceasta din urmă înseamnă că după ce am testat aplicația local în :nonode@nohost, sau într-un mediu distribuit artificial folosind test_cluster_task, vreau doar să fug docker-compose up --scale my_app=3 și vedeți cum execută trei instanțe în docker fără modificări de cod. Vreau și aplicații dependente ca mnesia - când topologia se schimbă, în culise reconstruiesc cluster-ul live fără nicio lovitură suplimentară din partea aplicației.

Mănăstire nu a fost intenționat să fie o bibliotecă capabilă de orice, de la susținerea unui grup până la prepararea cafelei. Nu este un glonț de argint care își propune să acopere toate cazurile posibile, sau să fie o soluție completă din punct de vedere academic în sensul în care teoreticienii din CS pus în acest termen. Această bibliotecă este concepută pentru a servi unui scop foarte clar, dar își face treaba nu prea mare perfect. Acest obiectiv va fi acela de a oferi o transparență completă între mediul de dezvoltare locală și un mediu elastic distribuit și plin de containere ostile.

Abordarea aleasă

Mănăstire este destinat să fie rulat ca o aplicație, deși utilizatorii avansați pot lucra cu asamblarea și întreținerea clusterului manual, rulând direct Cloister.Manager în arborele de supraveghere al aplicației țintă.

Când se rulează ca aplicație, biblioteca se bazează pe config, din care se citesc următoarele valori de bază:

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

Parametrii de mai sus înseamnă literalmente următoarele: Mănăstire utilizat pentru aplicația OTP :my_app, foloseste descoperirea serviciului erlang pentru a conecta noduri, cel puțin trei, și MyApp.Listener modul (implementare @behaviour Cloister.Listener) este configurat să primească notificări despre modificările topologiei. O descriere detaliată a configurației complete poate fi găsită în documentație.

Cu această configurație, aplicația Mănăstire voință lansare în etape, întârzierea procesului de pornire a aplicației principale până când se ajunge la consens (trei noduri sunt conectate și conectate, ca în exemplul de mai sus.) Acest lucru oferă aplicației principale posibilitatea de a presupune că atunci când pornește, clusterul este deja disponibil. Ori de câte ori topologia se schimbă (vor fi multe, deoarece nodurile nu pornesc complet sincron), handlerul va fi apelat MyApp.Listener.on_state_change/2. De cele mai multe ori efectuăm o acțiune atunci când primim un mesaj de stare %Cloister.Monitor{status: :up}, ceea ce înseamnă: „Bună ziua, clusterul este asamblat”.

În cele mai multe cazuri, instalarea consensus: 3 este optim pentru că, chiar dacă ne așteptăm să se conecteze mai multe noduri, callback-ul va trece status: :rehashingstatus: :up pe orice nod nou adăugat sau eliminat.

Când porniți în modul de dezvoltare, trebuie doar să setați consensus: 1 и Mănăstire va omite cu bucurie așteptarea asamblarii clusterului când va vedea :nonode@nohostSau :node@hostSau :[email protected] - în funcție de modul în care a fost configurat nodul (:none | :shortnames | :longnames).

Managementul aplicațiilor distribuite

Aplicațiile distribuite care nu sunt în vid includ de obicei dependențe distribuite, cum ar fi mnesia. Ne este ușor să gestionăm reconfigurarea lor din același apel invers on_state_change/2. Iată, de exemplu, o descriere detaliată a modului de reconfigurare mnesia în zbor înăuntru documentație Mănăstire.

Principalul avantaj al folosirii Mănăstire este că efectuează toate operațiunile necesare pentru a reconstrui clusterul după o schimbare de topologie sub capotă. Aplicația rulează pur și simplu într-un mediu distribuit deja pregătit, cu toate nodurile conectate, indiferent dacă știm în prealabil adresele IP și, prin urmare, numele nodurilor, sau acestea au fost alocate/modificate dinamic. Acest lucru nu necesită absolut nicio setări speciale de configurare pentru docker și din punctul de vedere al dezvoltatorului de aplicații, nu există nicio diferență între rularea într-un mediu distribuit sau rularea într-unul local. :nonode@nohost. Puteți citi mai multe despre asta în documentație.

Deși gestionarea complexă a modificărilor de topologie este posibilă printr-o implementare personalizată MyApp.Listener, pot exista întotdeauna cazuri de margine în care aceste limitări ale bibliotecii și prejudecăți de configurare se dovedesc a fi pietrele de temelie ale implementării. Este în regulă, doar luați cele de mai sus libcluster, care are un scop mai general, sau chiar gestionați singur clusterul de nivel scăzut. Scopul acestei biblioteci de coduri nu este acela de a acoperi fiecare scenariu posibil, ci de a utiliza cel mai comun scenariu fără dureri inutile și copiere-lipire greoaie.

Nota: în acest moment în original exista expresia „Happy clustering!”, iar Yandex, cu care traduc (nu trebuie să trec eu prin dicționare), mi-a oferit opțiunea „Happy clustering!” Este poate imposibil de imaginat o traducere mai bună, mai ales în lumina situației geopolitice actuale.

Sursa: www.habr.com

Adauga un comentariu