Apache Ignite Zero Deployment: Wirklich Null?

Apache Ignite Zero Deployment: Wirklich Null?

Wir sind die Technologieentwicklungsabteilung eines Einzelhandelsnetzwerks. Eines Tages stellte sich das Management die Aufgabe, umfangreiche Berechnungen durch den Einsatz von Apache Ignite in Verbindung mit MSSQL zu beschleunigen, und zeigte eine Website mit schönen Illustrationen und Beispielen für Java-Code. Mir gefiel die Seite sofort Keine Bereitstellung, dessen Beschreibung Wunder verspricht: Sie müssen Ihren Java- oder Scala-Code nicht manuell auf jedem Knoten im Grid bereitstellen und ihn bei jeder Änderung erneut bereitstellen. Im Laufe der Arbeit stellte sich heraus, dass Zero Deployment spezifische Verwendungsmöglichkeiten bietet, deren Funktionen ich mit Ihnen teilen möchte. Unterhalb des Ausschnitts finden Sie Gedanken und Details zur Umsetzung.

1. Erklärung des Problems

Der Kern des Problems ist wie folgt. Es gibt ein SalesPoint-Verzeichnis der Verkaufsstellen und ein Sku-Produktverzeichnis (Stock Keeping Unit). Die Verkaufsstelle verfügt über ein Attribut „Ladentyp“ mit den Werten „klein“ und „groß“. Mit jeder Verkaufsstelle wird ein Sortiment (Liste der Produkte der Verkaufsstelle) verknüpft (aus dem DBMS geladen) und es wird die Information bereitgestellt, dass das angegebene Produkt ab dem angegebenen Datum verfügbar ist
aus dem Sortiment ausgeschlossen oder dem Sortiment hinzugefügt werden.

Es ist erforderlich, einen partitionierten Cache der Verkaufsstellen zu organisieren und darin einen Monat im Voraus Informationen über verbundene Produkte zu speichern. Die Kompatibilität mit dem Kampfsystem erfordert, dass der Ignite-Clientknoten Daten lädt, ein Aggregat des Formulars (Geschäftstyp, Produktcode, Tag, Anzahl_der_Verkaufspunkte) berechnet und es zurück in das DBMS hochlädt.

2. Literaturstudium

Da ich noch keine Erfahrung habe, fange ich an, vom Herd aus zu tanzen. Das heißt, aus einer Rezension von Veröffentlichungen.

Artikel 2016 Einführung in Apache Ignite: Erste Schritte enthält einen Link zur Dokumentation des Apache Ignite-Projekts und gleichzeitig einen Vorwurf für die Unbestimmtheit dieser Dokumentation. Ich habe es ein paar Mal noch einmal gelesen, es stellt sich keine Klarheit ein. Ich verweise auf das offizielle Tutorial EinstiegDie
verspricht optimistisch: „Sie sind im Handumdrehen startklar!“ Ich bin dabei, die Einstellungen der Umgebungsvariablen herauszufinden und schaue mir zwei Apache Ignite Essentials-Videos an, aber sie waren für meine spezielle Aufgabe nicht sehr nützlich. Ich starte Ignite erfolgreich über die Befehlszeile mit der Standarddatei „example-ignite.xml“ und erstelle die erste Anwendung Computeranwendung mit Maven. Die Anwendung funktioniert und nutzt Zero Deployment, was für eine Schönheit!

Ich habe weitergelesen und dort verwendet das Beispiel sofort affinityKey (zuvor durch eine SQL-Abfrage erstellt) und sogar das mysteriöse BinaryObject:

IgniteCache<BinaryObject, BinaryObject> people 
        = ignite.cache("Person").withKeepBinary(); 

Lesen leicht: Binärformat – so etwas wie Reflektion, Zugriff auf die Felder eines Objekts über den Namen. Kann den Wert eines Felds lesen, ohne das Objekt vollständig zu deserialisieren (Speicher sparen). Aber warum wird BinaryObject anstelle von Person verwendet, da es Zero Deployment gibt? Warum IgniteCache an IgniteCache übertragen ? Es ist noch nicht klar.

Ich überarbeite die Compute-Anwendung entsprechend meinem Fall. Der Primärschlüssel des Verzeichnisses der Verkaufsstellen in MSSQL ist definiert als [id] [int] NOT NULL, ich erstelle analog einen Cache

IgniteCache<Integer, SalesPoint> salesPointCache=ignite.cache("spCache")

In der XML-Konfiguration gebe ich an, dass der Cache partitioniert ist

<bean class="org.apache.ignite.configuration.CacheConfiguration">
    <property name="name" value="spCache"/>
    <property name="cacheMode" value="PARTITIONED"/>
</bean>

Bei der Partitionierung nach Verkaufsstelle wird davon ausgegangen, dass das erforderliche Aggregat auf jedem Clusterknoten für die dort verfügbaren salesPointCache-Datensätze erstellt wird, woraufhin der Clientknoten die endgültige Summierung durchführt.

Ich lese das Tutorial Erste Ignite Compute-Anwendung, ich mache es analog. Auf jedem Clusterknoten führe ich IgniteRunnable() aus, etwa so:

  @Override
  public void run() {
    SalesPoint sp=salesPointCache.get(spId);
    sp.calculateSalesPointCount();
    ..
  }

Ich füge Aggregations- und Upload-Logik hinzu und führe sie auf einem Testdatensatz aus. Alles funktioniert lokal auf dem Entwicklungsserver.

Ich starte zwei CentOs-Testserver, gebe die IP-Adressen in default-config.xml an und führe sie auf jedem aus

./bin/ignite.sh config/default-config.xml

Beide Ignite-Knoten laufen und können sich gegenseitig sehen. Ich gebe die benötigten Adressen in der XML-Konfiguration der Client-Anwendung an, sie startet, fügt der Topologie einen dritten Knoten hinzu und sofort sind es wieder zwei Knoten. Das Protokoll zeigt „ClassNotFoundException: model.SalesPoint“ in der Zeile

SalesPoint sp=salesPointCache.get(spId);

Laut StackOverflow liegt der Grund für den Fehler darin, dass es auf CentOs-Servern keine benutzerdefinierte SalesPoint-Klasse gibt. Wir sind angekommen. Wie wäre es mit „Sie müssen Ihren Java-Code nicht manuell auf jedem Knoten bereitstellen“ und so weiter? Oder geht es bei „Ihrem Java-Code“ nicht um SalesPoint?

Wahrscheinlich habe ich etwas verpasst – ich beginne erneut zu suchen, zu lesen und erneut zu suchen. Nach einer Weile habe ich das Gefühl, alles zu dem Thema gelesen zu haben, es gibt nichts Neues mehr. Bei der Suche bin ich auf einige interessante Kommentare gestoßen.

Valentin Kulichenko, Leitender Architekt bei GridGain Systems, beantworten auf StackOverflow, April 2016:

Model classes are not peer deployed, but you can use withKeepBinary() flag
on the cache and query BinaryObjects. This way you will avoid deserialization
on the server side and will not get ClassNotFoundException.

Eine weitere maßgebliche Meinung: Denis Magda, Leiter Produktmanagement, GridGain Systems.

Artikel über Habré über Microservices verweist auf drei Artikel von Denis Magda: Microservices Teil I, Microservices Teil II, Microservices Teil III 2016-2017. Im zweiten Artikel schlägt Denis vor, einen Clusterknoten über MaintenanceServiceNodeStartup.jar zu starten. Sie können den Start auch mit der XML-Konfiguration und der Befehlszeile verwenden, müssen dann jedoch manuell benutzerdefinierte Klassen auf jedem bereitgestellten Clusterknoten einfügen:

That's it. Start (..)  node using MaintenanceServiceNodeStartup file or pass
maintenance-service-node-config.xml to Apache Ignite's ignite.sh/bat scripts.
If you prefer the latter then make sure to build a jar file that will contain
all the classes from java/app/common and java/services/maintenance directories.
The jar has to be added to the classpath of every node where the service
might be deployed.

Tatsächlich, das ist es. Hier stellt sich heraus, warum, dieses mysteriöse Binärformat!

3.SingleJar

Denis belegte in meiner persönlichen Bewertung den ersten Platz, meiner Meinung nach das nützlichste Tutorial von allen verfügbaren. In seinem MicroServicesExample Github enthält ein komplett fertiges Beispiel zum Einrichten von Clusterknoten, das ohne zusätzliches Squatting kompiliert werden kann.

Ich mache es genauso und erhalte eine einzelne JAR-Datei, die je nach Befehlszeilenargument „Datenknoten“ oder „Clientknoten“ startet. Die Montage startet und funktioniert. Zero Deployment wurde besiegt.

Der Übergang von Megabyte Testdaten zu Dutzenden Gigabyte Kampfdaten zeigte, dass das Binärformat aus einem bestimmten Grund existiert. Es war notwendig, den Speicherverbrauch auf Knoten zu optimieren, und hier erwies sich BinaryObject als sehr nützlich.

4. Schlussfolgerungen

Der erste Vorwurf, die Dokumentation des Apache Ignite-Projekts sei vage, erwies sich als berechtigt; seit 2016 hat sich wenig geändert. Für einen Anfänger ist es nicht einfach, einen funktionierenden Prototyp auf der Grundlage einer Website und/oder eines Repositorys zusammenzustellen.

Aufgrund der Ergebnisse der geleisteten Arbeit entstand der Eindruck, dass Zero Deployment funktioniert, allerdings nur auf Systemebene. Etwa so: BinaryObject wird verwendet, um Remote-Cluster-Knoten beizubringen, mit benutzerdefinierten Klassen zu arbeiten; Zero Deployment – ​​interner Mechanismus
Apache Ignite selbst und verteilt Systemobjekte im gesamten Cluster.

Ich hoffe, dass meine Erfahrung für neue Apache Ignite-Benutzer nützlich sein wird.

Source: habr.com

Kommentar hinzufügen