Quasi tutte le applicazioni aziendali di successo prima o poi entrano in una fase in cui è necessario un ridimensionamento orizzontale. In molti casi, puoi semplicemente avviare una nuova istanza e ridurre il carico medio. Ma ci sono anche casi meno banali in cui dobbiamo garantire che i diversi nodi si conoscano e distribuiscano attentamente il carico di lavoro.
Si è rivelato così fortunato Erlang, che abbiamo scelto per la sua piacevole sintassi e per il clamore che lo circonda, ha un file di prima classe
Il passaggio dei messaggi tra processi su nodi diversi, nonché tra collegamenti e monitor, è trasparente […]
In pratica, tutto è un po’ più complicato. Distribuito Erlang è stato sviluppato quando "container" significava una grande scatola di ferro per la spedizione, e "docker" era semplicemente sinonimo di scaricatore di porto. IN IP4 c'erano molti indirizzi non occupati, le interruzioni della rete erano solitamente causate da topi che masticavano il cavo e il tempo di attività medio del sistema di produzione veniva misurato in decenni.
Ora siamo tutti incredibilmente autosufficienti, confezionati e distribuiti Erlang in un ambiente in cui gli indirizzi IP dinamici vengono distribuiti in base al principio di grande casualità e i nodi possono apparire e scomparire secondo il capriccio del tallone sinistro dello scheduler. Per evitare pile di codice standard in ogni progetto che esegue un file distribuito Erlang, per combattere l'ambiente ostile, è necessario aiuto.
Nota: Sono consapevole che esiste libcluster
Requisiti
Ciò di cui personalmente avevo bisogno era una libreria che assumesse la gestione del cluster e avesse le seguenti proprietà:
- lavoro trasparente con un elenco di nodi codificato e rilevamento dinamico attraverso i servizi Erlang;
- callback completamente funzionale per ogni modifica della topologia (nodo lì, nodo qui, instabilità della rete, divisioni);
- interfaccia trasparente per l'avvio di un cluster con nomi lunghi e brevi, come con
:nonode@nohost
; - Supporto Docker pronto all'uso, senza dover scrivere il codice dell'infrastruttura.
Quest'ultimo significa che dopo aver testato l'applicazione localmente in :nonode@nohost
o in un ambiente distribuito artificialmente utilizzando test_cluster_task
docker-compose up --scale my_app=3
e guarda come esegue tre istanze nella finestra mobile senza alcuna modifica al codice. Voglio anche applicazioni dipendenti come mnesia
- quando la topologia cambia, dietro le quinte ricostruiscono il cluster in tempo reale senza alcun ulteriore kick da parte dell'applicazione.
Chiostro non doveva essere una biblioteca capace di tutto, dal supporto di un cluster alla preparazione del caffè. Non si tratta di una soluzione miracolosa che mira a coprire tutti i casi possibili, o ad essere una soluzione accademicamente completa, nel senso che i teorici di CS mettere in questo termine. Questa libreria è progettata per avere uno scopo molto chiaro, ma svolge perfettamente il suo lavoro non troppo grande. Questo obiettivo sarà quello di fornire una completa trasparenza tra l’ambiente di sviluppo locale e un ambiente elastico distribuito pieno di contenitori ostili.
Approccio scelto
Chiostro è concepito per essere eseguito come un'applicazione, sebbene gli utenti avanzati possano lavorare manualmente con l'assemblaggio e la manutenzione del cluster eseguendo direttamente Cloister.Manager
nell'albero del supervisore dell'applicazione di destinazione.
Quando eseguita come applicazione, la libreria si basa su config
, da cui si leggono i seguenti valori fondamentali:
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
I parametri sopra indicati significano letteralmente quanto segue: Chiostro utilizzato per l'applicazione OTP :my_app
usi scoperta del servizio erlang per connettere i nodi, almeno tre, e MyApp.Listener
modulo (implementazione @behaviour Cloister.Listener
Con questa configurazione, l'applicazione Chiostro volontà MyApp.Listener.on_state_change/2
%Cloister.Monitor{status: :up}
, che significa: "Ciao, il cluster è assemblato".
Nella maggior parte dei casi, installazione consensus: 3
è ottimale perché anche se ci aspettiamo che più nodi si connettano, il callback andrà a buon fine status: :rehashing
→ status: :up
su qualsiasi nodo appena aggiunto o rimosso.
Quando si avvia in modalità sviluppo, è sufficiente impostare consensus: 1
и Chiostro salterà volentieri l'attesa per l'assemblaggio del cluster quando vedrà :nonode@nohost
O :node@host
O :[email protected]
- a seconda di come è stato configurato il nodo (:none | :shortnames | :longnames
).
Gestione delle applicazioni distribuite
Le applicazioni distribuite non nel vuoto di solito includono dipendenze distribuite, come mnesia
. Per noi è facile gestire la riconfigurazione dallo stesso callback on_state_change/2
. Ecco, ad esempio, una descrizione dettagliata di come riconfigurare mnesia
al volo
Il vantaggio principale dell'utilizzo Chiostro è che esegue tutte le operazioni necessarie per ricostruire il cluster dopo una modifica della topologia sotto il cappuccio. L'applicazione funziona semplicemente in un ambiente distribuito già predisposto, con tutti i nodi collegati, indipendentemente dal fatto che conosciamo in anticipo gli indirizzi IP e quindi i nomi dei nodi, oppure che siano stati assegnati/modificati dinamicamente. Ciò non richiede assolutamente alcuna impostazione speciale di configurazione della finestra mobile e dal punto di vista di uno sviluppatore di applicazioni non c'è differenza tra l'esecuzione in un ambiente distribuito o l'esecuzione in uno locale. :nonode@nohost
. Puoi leggere di più a riguardo in
Sebbene la gestione complessa delle modifiche alla topologia sia possibile tramite un'implementazione personalizzata MyApp.Listener
, potrebbero sempre esserci casi limite in cui le limitazioni della libreria e i pregiudizi di configurazione si rivelano i pilastri dell'implementazione. Va bene, prendi semplicemente quanto sopra libcluster
, che è più generico o addirittura gestire autonomamente il cluster di basso livello. L'obiettivo di questa libreria di codici non è coprire tutti gli scenari possibili, ma utilizzare lo scenario più comune senza inutili complicazioni e ingombranti operazioni di copia e incolla.
Nota: a questo punto nell'originale c'era la frase "Happy clustering!", e Yandex, con cui traduco (non devo sfogliare i dizionari da solo), mi ha offerto l'opzione "Happy clustering!" Forse è impossibile immaginare una traduzione migliore, soprattutto alla luce dell’attuale situazione geopolitica.
Fonte: habr.com