Fast jede erfolgreiche Geschäftsanwendung tritt früher oder später in eine Phase ein, in der eine horizontale Skalierung erforderlich ist. In vielen Fällen können Sie einfach eine neue Instanz starten und den Lastdurchschnitt reduzieren. Es gibt aber auch weniger triviale Fälle, in denen wir sicherstellen müssen, dass verschiedene Knoten voneinander wissen und die Arbeitslast sorgfältig verteilen.
Es stellte sich heraus, dass es ein großes Glück war erlang erhalten, das wir wegen seiner angenehmen Syntax und dem Hype darum ausgewählt haben, ist erstklassig
Der Nachrichtenaustausch zwischen Prozessen auf verschiedenen Knoten sowie zwischen Links und Monitoren ist transparent […]
In der Praxis ist alles etwas komplizierter. Verteilt erlang erhalten wurde entwickelt, als „Container“ eine große Eisenkiste für die Schifffahrt bedeutete und „Hafenmann“ einfach ein Synonym für Hafenarbeiter war. IN IP4 Es gab viele unbesetzte Adressen, Netzwerkunterbrechungen wurden meist durch Ratten verursacht, die das Kabel durchfraßen, und die durchschnittliche Betriebszeit des Produktionssystems wurde in Jahrzehnten gemessen.
Jetzt sind wir alle unglaublich autark, verpackt und laufen verteilt erlang erhalten in einer Umgebung, in der dynamische IP-Adressen nach dem Prinzip großer Zufälligkeit vergeben werden und Knoten nach Lust und Laune des linken Fußes des Planers erscheinen und verschwinden können. Um zu vermeiden, dass sich in jedem Projekt, in dem ein verteilter Code ausgeführt wird, eine Menge Boilerplate-Code ansammelt erlang erhaltenUm die feindliche Umgebung zu bekämpfen, ist Hilfe erforderlich.
Beachten: Mir ist bewusst, dass es das gibt libcluster
Bedarf
Was ich persönlich brauchte, war eine Bibliothek, die die Verwaltung des Clusters übernimmt und über folgende Eigenschaften verfügt:
- transparente Arbeit sowohl mit einer hartcodierten Liste von Knoten als auch mit dynamischer Erkennung durch Dienste erlang erhalten;
- voll funktionsfähiger Rückruf für jede Topologieänderung (Knoten dort, Knoten hier, Netzwerkinstabilität, Teilungen);
- transparente Schnittstelle zum Starten eines Clusters mit langen und kurzen Namen, wie bei
:nonode@nohost
; - Docker-Unterstützung sofort einsatzbereit, ohne dass Infrastrukturcode geschrieben werden muss.
Letzteres bedeutet, dass ich die Anwendung lokal getestet habe :nonode@nohost
, oder in einer künstlich verteilten Umgebung unter Verwendung test_cluster_task
docker-compose up --scale my_app=3
und sehen Sie, wie es drei Instanzen in Docker ohne Codeänderungen ausführt. Ich möchte auch abhängige Anwendungen wie mnesia
- Wenn sich die Topologie ändert, wird der Cluster hinter den Kulissen live und ohne zusätzlichen Kick von der Anwendung neu aufgebaut.
Kloster war nicht als Bibliothek gedacht, die alles kann, von der Unterstützung eines Clusters bis zur Kaffeezubereitung. Es handelt sich nicht um eine Wunderwaffe, die darauf abzielt, alle möglichen Fälle abzudecken, oder um eine akademisch vollständige Lösung im Sinne der Theoretiker CS in diesen Begriff stecken. Diese Bibliothek soll einem ganz klaren Zweck dienen, ihre nicht allzu große Aufgabe aber perfekt erfüllen. Dieses Ziel besteht darin, vollständige Transparenz zwischen der lokalen Entwicklungsumgebung und einer verteilten elastischen Umgebung voller feindlicher Container bereitzustellen.
Gewählter Ansatz
Kloster soll als Anwendung ausgeführt werden, fortgeschrittene Benutzer können jedoch manuell mit der Zusammenstellung und Wartung des Clusters arbeiten, indem sie es direkt ausführen Cloister.Manager
im Supervisor-Baum der Zielanwendung.
Bei der Ausführung als Anwendung ist die Bibliothek darauf angewiesen config
, aus dem es die folgenden Grundwerte liest:
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
Die oben genannten Parameter bedeuten wörtlich Folgendes: Kloster Wird für OTP-Anwendungen verwendet :my_app
, Verwendet Erkennung von Erlang-Diensten Knoten zu verbinden, mindestens drei, und MyApp.Listener
Modul (Implementierung @behaviour Cloister.Listener
Mit dieser Konfiguration ist die Anwendung Kloster werden MyApp.Listener.on_state_change/2
%Cloister.Monitor{status: :up}
, was bedeutet: „Hallo, der Cluster ist zusammengestellt.“
In den meisten Fällen Installation consensus: 3
ist optimal, denn selbst wenn wir erwarten, dass sich mehr Knoten verbinden, wird der Rückruf durchgeführt status: :rehashing
→ status: :up
auf jedem neu hinzugefügten oder entfernten Knoten.
Wenn Sie im Entwicklungsmodus starten, müssen Sie nur noch Einstellungen vornehmen consensus: 1
и Kloster wird das Warten auf den Zusammenbau des Clusters gerne überspringen, wenn er es sieht :nonode@nohost
Oder :node@host
Oder :[email protected]
- abhängig davon, wie der Knoten konfiguriert wurde (:none | :shortnames | :longnames
).
Verteiltes Anwendungsmanagement
Verteilte Anwendungen, die sich nicht im luftleeren Raum befinden, umfassen normalerweise verteilte Abhängigkeiten, wie z mnesia
. Es ist für uns einfach, ihre Neukonfiguration über denselben Rückruf abzuwickeln on_state_change/2
. Hier finden Sie beispielsweise eine ausführliche Beschreibung zur Neukonfiguration mnesia
im Handumdrehen
Der Hauptvorteil der Verwendung Kloster besteht darin, dass es alle notwendigen Vorgänge ausführt, um den Cluster nach einer Topologieänderung neu aufzubauen unter der Haube. Die Anwendung läuft einfach in einer bereits vorbereiteten verteilten Umgebung, in der alle Knoten verbunden sind, unabhängig davon, ob wir die IP-Adressen und damit die Knotennamen im Voraus kennen oder ob sie dynamisch zugewiesen/geändert wurden. Dafür sind keinerlei spezielle Docker-Konfigurationseinstellungen erforderlich und aus Sicht eines Anwendungsentwicklers gibt es keinen Unterschied zwischen der Ausführung in einer verteilten oder der Ausführung in einer lokalen Umgebung. :nonode@nohost
. Mehr dazu können Sie hier lesen
Durch eine benutzerdefinierte Implementierung ist jedoch eine komplexe Handhabung von Topologieänderungen möglich MyApp.Listener
, kann es immer Randfälle geben, in denen sich diese Bibliothekseinschränkungen und Konfigurationsverzerrungen als Eckpfeiler der Implementierung erweisen. Es ist in Ordnung, nehmen Sie einfach das oben Gesagte libcluster
, was allgemeiner ist, oder verwalten Sie den Low-Level-Cluster sogar selbst. Das Ziel dieser Codebibliothek besteht nicht darin, jedes mögliche Szenario abzudecken, sondern das häufigste Szenario ohne unnötigen Aufwand und umständliches Kopieren und Einfügen zu verwenden.
Hinweis: An dieser Stelle im Original stand der Satz „Happy Clustering!“ und Yandex, mit dem ich übersetze (ich muss selbst keine Wörterbücher durchforsten), bot mir die Option „Happy Clustering!“ an. Eine bessere Übersetzung kann man sich vielleicht nicht vorstellen, insbesondere angesichts der aktuellen geopolitischen Lage.
Source: habr.com