Apache Ignite Zero Deployment: wirklich Zero?

Apache Ignite Zero Deployment: wirklich Zero?

Wir sind die Abteilung für die Entwicklung von Technologien im Einzelhandel. Eines Tages gab das Management die Aufgabe, die rechnerischen Ressourcen durch den Einsatz von Apache Ignite in Verbindung mit MSSQL zu beschleunigen. Sie zeigten eine Website mit großartigen Illustrationen und Beispielen von Java-Code. Die Website gefiel sofort. Zero Deployment, dessen Beschreibung Wunder verspricht: Sie müssen Ihren Java- oder Scala-Code nicht manuell auf jedem Knoten im Grid bereitstellen und jedes Mal neu bereitstellen, wenn er sich ändert. Im Laufe der Arbeit stellte sich heraus, dass Zero Deployment spezifische Nutzungseigenschaften aufweist, mit denen ich meine Erfahrungen teilen möchte. Im Folgenden finden Sie Überlegungen und Details zur Umsetzung.

1. Aufgabenstellung

Die Essenz der Aufgabe ist wie folgt. Es gibt ein Verzeichnis der Verkaufsstellen SalesPoint und ein Verzeichnis der Produkte Sku (Stock Keeping Unit). Jede Verkaufsstelle hat das Attribut „typMагазина“ mit den Werten „klein“ und „groß“. Zu jeder Verkaufsstelle wird das Sortiment (Liste der Produkte der Verkaufsstelle) geladen (aus der Datenbank) und Informationen darüber bereitgestellt, dass ein bestimmtes Produkt ab dem angegebenen Datum aus dem Sortiment ausgeschlossen oder in das Sortiment aufgenommen wird.
wird aus dem Sortiment genommen oder zum Sortiment hinzugefügt.

Es ist erforderlich, einen partitionierten Cache für die Verkaufsstellen zu organisieren und Informationen über die angeschlossenen Produkte einen Monat im Voraus zu speichern. Die Kompatibilität mit dem Betriebstoß erfordert, dass der Client-Knoten von Ignite Daten lädt, eine Aggregation in der Form (Typ des Geschäfts, Produktcode, Tag, Anzahl der Verkaufsstellen) berechnet und diese wieder in die Datenbank exportiert.

2. Literaturrecherche

Ich habe noch keine Erfahrung, also beginne ich von Grund auf. Das heißt, mit einem Überblick über die Veröffentlichungen.

Artikel aus dem Jahr 2016 Einführung in Apache Ignite: Erste Schritte enthält einen Link zur Dokumentation des Apache Ignite-Projekts und gleichzeitig einen Vorwurf hinsichtlich der Unklarheit dieser Dokumentation. Ich habe es ein paar Mal durchgelesen, aber die Klarheit stellt sich nicht ein. Ich wende mich an das offizielle Tutorial getting-started, der
verspricht optimistisch: „Sie sind im Handumdrehen einsatzbereit!“. Ich arbeite an den Umgebungsvariablen, schaue mir zwei Videos zu Apache Ignite Essentials an, die für mein spezifisches Vorhaben nicht sehr hilfreich waren. Ich starte Ignite erfolgreich über die Kommandozeile mit der Standarddatei „example-ignite.xml“ und entwickle die erste Anwendung Compute Application mit Maven. Die Anwendung läuft und verwendet Zero Deployment, wie schön!

Ich lese weiter, und dort wird sofort das affinityKey verwendet (zuvor über einen SQL-Befehl erstellt), und es kommt noch das mysteriöse BinaryObject zum Einsatz:

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

Ich habe gelesen ein wenig: Binärformat – etwas wie Reflexion, Zugriff auf Felder des Objekts über den Namen. Es kann den Wert eines Feldes lesen, ohne das gesamte Objekt zu deserialisieren (Speichereinsparung). Aber warum wird anstelle von Person das BinaryObject verwendet, obwohl Zero Deployment vorhanden ist? Warum wird IgniteCache<Key, Person> in IgniteCache<BinaryObject, BinaryObject> übersetzt? Im Moment ist das unklar.

Ich passe die Compute Application an meinen Fall an. Der Primärschlüssel des Verkaufsstellenverzeichnisses in MSSQL ist als [id] [int] NOT NULL definiert, ich erstelle den Cache analog.

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>

Die Partitionierung nach Verkaufsstellen impliziert, dass das erforderliche Aggregat auf jedem Knoten des Clusters für die dort vorhandenen Datensätze salesPointCache aufgebaut wird, wonach der Clientknoten die Endsummierung durchführt.

Ich lese das Tutorial First Ignite Compute Application, ich mache es analog. Auf jedem Knoten des Clusters starte ich IgniteRunnable(), etwa so:

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

Ich füge Logik für die Aggregation und den Export hinzu und teste es mit einem Datensatz. Lokal auf dem Entwicklungsserver funktioniert alles einwandfrei.

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

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

Beide Ignite-Knoten starten und erkennen sich gegenseitig. Ich gebe die erforderlichen Adressen in der XML-Konfiguration der Client-Anwendung an, sie startet, fügt den dritten Knoten zur Topologie hinzu und sofort sind es wieder zwei Knoten. Im Log steht „ClassNotFoundException: model.SalesPoint“ in der Zeile

SalesPoint sp=salesPointCache.get(spId);

StackOverflow sagt, dass der Grund für den Fehler ist — auf den CentOS-Servern fehlt die Benutzerklasse SalesPoint. Klasse. Wie kann es sein, dass „you don’t have to manually deploy your Java code on each node“ und so weiter? Oder bezieht sich „your Java code“ nicht auf SalesPoint?

Wahrscheinlich habe ich etwas übersehen — ich fange wieder an zu suchen, zu lesen und weiter zu suchen. Nach einer Weile habe ich das Gefühl, dass ich alles zu diesem Thema gelesen habe, es gibt nichts Neues mehr. Während meiner Suche fand ich einige interessante Anmerkungen.

Valentin Kulichenko, Lead Architect bei GridGain Systems, Antwort auf StackOverflow, April 2016:

Modelklassen werden nicht parallel bereitgestellt, aber Sie können das Flag withKeepBinary() im Cache verwenden und BinaryObjects abfragen. Auf diese Weise vermeiden Sie die Deserialisierung auf der Serverseite und verhindern, dass die ClassNotFoundException auftritt.

Eine weitere autoritative Meinung: Denis Magda, Direktor des Produktmanagements, GridGain Systems.

Artikel auf Habr über Mikrodienste verweist auf drei Artikel von Denis Magda: Mikrodienste Teil I, Mikrodienste Teil II, Mikrodienste Teil III von 2016-2017. Im zweiten Artikel schlägt Denis vor, einen Clusterknoten über MaintenanceServiceNodeStartup.jar zu starten. Es kann auch mit XML-Konfiguration und Befehlszeile gestartet werden, aber dann müssen die benutzerdefinierten Klassen manuell auf jeden bereitgestellten Clusterknoten gelegt werden:

Das war's. Starten Sie den Knoten mithilfe der MaintenanceServiceNodeStartup-Datei oder übergeben Sie maintenance-service-node-config.xml an die ignite.sh/bat-Skripte von Apache Ignite. Wenn Sie Letzteres bevorzugen, stellen Sie sicher, dass Sie eine JAR-Datei erstellen, die alle Klassen aus den Verzeichnissen java/app/common und java/services/maintenance enthält. Die JAR muss dem Klassenpfad jedes Knotens hinzugefügt werden, auf dem der Dienst bereitgestellt werden könnte.

In der Tat, das war's. So ist dieser geheimnisvolle Binärformat also tatsächlich notwendig!

3. SingleJar

Denis hat in meinem persönlichen Ranking den ersten Platz belegt; meiner Meinung nach ist das das nützlichste Tutorial von allen verfügbaren. In seinem MicroServicesExample Auf GitHub finden Sie ein vollständig einsatzbereites Beispiel zur Konfiguration von Cluster-Knoten, das ohne zusätzliche Anpassungen kompiliert wird.

Ich mache es nach dem Vorbild und erhalte eine einzige jar-Datei, die je nach Kommandozeilenargument entweder den „Data Node“ oder den „Client Node“ startet. Der Build wird gestartet und funktioniert. Zero Deployment ist überwunden.

Der Übergang von Megabyte-Testdaten zu Dutzenden von Gigabyte Produktionsdaten hat gezeigt, dass das binäre Format einen sinnvollen Zweck hat. Es war notwendig, den Speicherverbrauch auf den Knoten zu optimieren, und hier erwies sich BinaryObject als sehr hilfreich.

4. Fazit

Die erste Kritik an der Unklarheit der Dokumentation des Apache Ignite-Projekts war berechtigt; seit 2016 hat sich nicht viel geändert. Es ist für Neulinge nicht einfach, einen funktionierenden Prototyp auf Basis der Webseite und/oder des Repositories zusammenzustellen.

Insgesamt entstand der Eindruck, dass Zero Deployment funktioniert, jedoch nur auf Systemebene. Ungefähr so: BinaryObject wird verwendet, um entfernte Cluster-Knoten dazu zu bringen, mit Benutzerklassen zu arbeiten; Zero Deployment ist ein interner Mechanismus von Apache Ignite und verbreitet systematische Objekte im Cluster.
der selbst von Apache Ignite und verbreitet systematische Objekte im Cluster.

Ich hoffe, meine Erfahrungen sind für neue Benutzer von Apache Ignite nützlich.

Quelle: habr.com

Kaufen Sie zuverlässiges Hosting für Websites mit DDoS-Schutz, VPS VDS-Server 🔥 Kaufen Sie zuverlässiges Hosting für Websites mit DDoS-Schutz, VPS VDS-Server | ProHoster