Claustre → gestió simple del clúster OTP

Gairebé totes les aplicacions empresarials d'èxit, tard o d'hora, entren en una fase on es requereix una escala horitzontal. En molts casos, simplement podeu iniciar una nova instància i reduir la càrrega mitjana. Però també hi ha casos menys trivials en què hem d'assegurar-nos que els diferents nodes es coneixen i distribuïm acuradament la càrrega de treball.

Claustre → gestió simple del clúster OTP

Va resultar tan afortunat que erlang, que vam triar per la seva agradable sintaxi i el bombo al seu voltant, té un primer nivell suport per a sistemes distribuïts. En teoria, això sona completament trivial:

El pas de missatges entre processos de diferents nodes, així com entre enllaços i monitors, és transparent […]

A la pràctica, tot és una mica més complicat. Distribuït erlang es va desenvolupar quan "contenidor" significava una gran caixa de ferro per a l'enviament, i "docker" era simplement un sinònim de estibador. EN IP4 hi havia moltes adreces desocupades, les interrupcions de la xarxa solen ser causades per rates mastegant el cable i el temps mitjà d'activitat del sistema de producció es va mesurar en dècades.

Ara tots som increïblement autosuficients, empaquetats i distribuïts erlang en un entorn on les adreces IP dinàmiques es distribueixen segons el principi de gran aleatorietat, i els nodes poden aparèixer i desaparèixer al caprici del taló esquerre del planificador. Per evitar munts de codi normal en tots els projectes que s'executen un distribuït erlang, per combatre l'entorn hostil, cal ajuda.

Nota: Sóc conscient que n'hi ha libcluster. És molt xulo, té més de mil estrelles, l'autor és famós a la comunitat, i tot això. Si els mètodes que ofereix aquest paquet per crear i mantenir un clúster us són suficients, estic content per vosaltres. Malauradament, necessito molt més. Vull controlar la configuració en detall i no ser un espectador extern en el teatre de la reorganització del clúster.

Requisits

El que personalment necessitava era una biblioteca que es fes càrrec de la gestió del clúster i tingués les propietats següents:

  • treball transparent tant amb una llista codificada de nodes com amb descobriment dinàmic mitjançant serveis erlang;
  • Devolució de trucada totalment funcional per a cada canvi de topologia (node ​​allà, node aquí, inestabilitat de la xarxa, divisions);
  • interfície transparent per llançar un clúster amb noms llargs i curts, com amb :nonode@nohost;
  • Suport de Docker des de la caixa, sense haver d'escriure codi d'infraestructura.

Això últim significa que després de provar l'aplicació localment :nonode@nohost, o en un entorn distribuït artificialment utilitzant test_cluster_task, només vull córrer docker-compose up --scale my_app=3 i mireu com executa tres instàncies a Docker sense cap canvi de codi. També vull aplicacions dependents com mnesia - quan la topologia canvia, darrere de les escenes reconstrueixen el clúster en directe sense cap mena addicional de l'aplicació.

Claustre no pretenia ser una biblioteca capaç de tot, des de donar suport a un clúster fins a fer cafè. No és una bala de plata que pretén cobrir tots els casos possibles, ni ser una solució acadèmica completa en el sentit que els teòrics de CS posat en aquest terme. Aquesta biblioteca està dissenyada per complir un propòsit molt clar, però fer la seva feina no massa gran a la perfecció. Aquest objectiu serà proporcionar una transparència total entre l'entorn de desenvolupament local i un entorn elàstic distribuït ple de contenidors hostils.

Enfocament escollit

Claustre està pensat per executar-se com una aplicació, encara que els usuaris avançats poden treballar amb el muntatge i el manteniment del clúster manualment executant-los directament. Cloister.Manager a l'arbre del supervisor de l'aplicació de destinació.

Quan s'executa com a aplicació, la biblioteca es basa config, del qual es llegeixen els valors bàsics següents:

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

Els paràmetres anteriors signifiquen literalment el següent: Claustre utilitzat per a l'aplicació OTP :my_app, usos descobriment del servei d'erlang per connectar nodes, almenys tres, i MyApp.Listener mòdul (implementació @behaviour Cloister.Listener) està configurat per rebre notificacions sobre canvis de topologia. Es pot trobar una descripció detallada de la configuració completa a documentació.

Amb aquesta configuració, l'aplicació Claustre voluntat llançament per etapes, retardant el procés d'inici de l'aplicació principal fins que s'arribi al consens (tres nodes estan connectats i connectats, com a l'exemple anterior). Això dóna a l'aplicació principal l'oportunitat d'assumir que quan s'inicia, el clúster ja està disponible. Sempre que canviï la topologia (n'hi haurà molts, perquè els nodes no s'inicien completament de manera sincrònica), es cridarà el controlador. MyApp.Listener.on_state_change/2. La majoria de vegades realitzem una acció quan rebem un missatge d'estat %Cloister.Monitor{status: :up}, que significa: "Hola, el clúster està muntat".

En la majoria dels casos, instal·lació consensus: 3 és òptim perquè encara que esperem que es connectin més nodes, la devolució de trucada passarà status: :rehashingstatus: :up a qualsevol node nou afegit o eliminat.

Quan comenceu en mode de desenvolupament, només heu de configurar consensus: 1 и Claustre feliçment saltarà l'espera del muntatge del clúster quan ho vegi :nonode@nohostO :node@hostO :[email protected] - depenent de com es va configurar el node (:none | :shortnames | :longnames).

Gestió d'aplicacions distribuïdes

Les aplicacions distribuïdes que no estan al buit solen incloure dependències distribuïdes, com ara mnesia. És fàcil per a nosaltres gestionar la seva reconfiguració des de la mateixa devolució de trucada on_state_change/2. Aquí, per exemple, hi ha una descripció detallada de com tornar a configurar mnesia sobre la marxa documentació Claustre.

El principal avantatge d'utilitzar Claustre és que realitza totes les operacions necessàries per reconstruir el clúster després d'un canvi de topologia sota el capó. L'aplicació simplement s'executa en un entorn distribuït ja preparat, amb tots els nodes connectats, independentment de si coneixem les adreces IP i, per tant, els noms dels nodes per endavant, o si s'han assignat/canviat dinàmicament. Això no requereix absolutament cap configuració especial de configuració de Docker i, des del punt de vista d'un desenvolupador d'aplicacions, no hi ha diferència entre executar-se en un entorn distribuït o executar-se en un de local. :nonode@nohost. Podeu llegir més sobre això a documentació.

Tot i que la gestió complexa dels canvis de topologia és possible mitjançant una implementació personalitzada MyApp.Listener, sempre hi pot haver casos extrems en què aquestes limitacions de biblioteca i biaixos de configuració resulten ser els pilars de la implementació. Està bé, només cal agafar l'anterior libcluster, que és de propòsit més general, o fins i tot manejar el clúster de baix nivell tu mateix. L'objectiu d'aquesta biblioteca de codi no és cobrir tots els escenaris possibles, sinó utilitzar l'escenari més comú sense dolor innecessari i còpia i enganxa feixuc.

Nota: en aquest punt de l'original hi havia la frase "Happy clustering!", i Yandex, amb la qual tradueixo (no he de passar jo mateix per diccionaris), em va oferir l'opció "Happy clustering!" Potser és impossible imaginar una millor traducció, sobretot a la vista de la situació geopolítica actual.

Font: www.habr.com

Afegeix comentari