
Wir sind die Abteilung für die Entwicklung von Technologien im Einzelhandel. Eines Tages stellte das Management die Aufgabe, die volumetrischen Berechnungen durch die Verwendung von Apache Ignite in Kombination mit MSSQL zu beschleunigen und zeigte eine Website mit hervorragenden Illustrationen und Beispielen für Java-Code. Die Website gefiel sofort. , dessen Beschreibung Wunder verspricht: you don’t have to manually deploy your Java or Scala code on each node in the grid and re-deploy it each time it changes. Im Verlauf der Arbeit stellte sich heraus, dass Zero Deployment spezifische Nutzungseigenschaften hat, denen ich näher eingehen möchte. Unter dem Cut Gedanken und Details zur Umsetzung.
1. Problemstellung
Der Kern der Aufgabe besteht darin. Es gibt ein Verzeichnis von Verkaufsstellen SalesPoint und ein Verzeichnis von Produkten Sku (Stock Keeping Unit). Die Verkaufsstelle hat ein Attribut "typMагазина" mit den Werten "klein" und "groß". Für jede Verkaufsstelle wird das Sortiment (Liste der Produkte der Verkaufsstelle) geladen und Informationen darüber bereitgestellt, dass ab dem angegebenen Datum das angegebene Produkt
aus dem Sortiment ausgeschlossen oder dem Sortiment hinzugefügt wird.
Es ist erforderlich, einen partitionierten Cache für die Verkaufsstellen zu organisieren und darin Informationen über die angeschlossenen Produkte für einen Monat im Voraus zu speichern. Die Kompatibilität mit dem produktiven System erfordert, dass der Client-Knoten von Ignite Daten lädt, Aggregationen der Art (typMагазина, кодТовара, Tag, Anzahl_verkaufsstellen) berechnet und diese zurück in die Datenbank überträgt.
2. Literaturstudie
Da ich bisher keine Erfahrung habe, beginne ich von Grund auf. Das heißt, mit einer Übersicht der Publikationen.
Ein Artikel aus dem Jahr 2016 enthält einen Link zur Dokumentation des Projekts Apache Ignite und gleichzeitig einen Vorwurf wegen Unklarheit dieser Dokumentation. Ich habe sie ein paar Mal gelesen, aber die Klarheit stellt sich nicht ein. Ich wende mich an das offizielle Tutorial , der
verspricht optimistisch: „You’ll be up and running in a jiffy!“. Ich beschäftige mich mit den Umgebungsvariablen und schaue mir zwei Videos zu Apache Ignite Essentials an, die sich als nicht sehr hilfreich für mein spezifisches Projekt erwiesen haben. Ich starte Ignite erfolgreich über die Kommandozeile mit der Standarddatei "example-ignite.xml" und erstelle die erste Anwendung. unter Verwendung von Maven. Die Anwendung funktioniert und nutzt Zero Deployment, was großartig ist!
Ich lese weiter und dort wird sofort ein Beispiel verwendet, das affinityKey (früher über einen SQL-Befehl erstellt) verwendet, und es wird auch ein mysteriöses BinaryObject angewendet:
IgniteCache people
= ignite.cache("Person").withKeepBinary(); Ich habe etwas gelesen. : binäres Format – etwas wie Reflexion, Zugriff auf die Felder eines Objekts nach Namen. Es kann den Wert eines Feldes ohne vollständige Deserialisierung des Objekts lesen (Speicherersparnis). Aber warum wird anstelle von Person BinaryObject verwendet, wo es doch Zero Deployment gibt? Warum wird IgniteCache<Key,Person> in IgniteCache<BinaryObject, BinaryObject> übersetzt? Momentan unklar.
Ich passe die Compute-Anwendung an meinen Fall an. Der Primärschlüssel des Verzeichnisses der Verkaufsstellen in MSSQL ist als [id] [int] NOT NULL definiert, ich erstelle einen Cache analog.
IgniteCache<Integer, SalesPoint> salesPointCache=ignite.cache("spCache")Im XML-Config 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 setzt voraus, dass das benötigte Aggregat auf jedem Knoten des Clusters für die dort vorhandenen Datensätze von salesPointCache erstellt wird, wonach der Client-Knoten die endgültige Summierung durchführt.
Ich lese das Tutorial. , ich mache es analog. Auf jedem Knoten des Clusters starte ich IgniteRunnable(), ungefähr so:
@Override
public void run() {
SalesPoint sp=salesPointCache.get(spId);
sp.calculateSalesPointCount();
..
}Ich füge die Aggregations- und Exportlogik hinzu und starte sie mit einem Testdatensatz. Lokal auf dem Entwicklungsserver funktioniert alles.
Ich starte zwei Testserver CentOs, gebe die IP-Adressen in default-config.xml an und führe auf jedem aus
.\/bin\/ignite.sh config\/default-config.xmlBeide Ignite-Knoten starten und sehen sich gegenseitig. Ich gebe die benötigten Adressen in der XML-Konfiguration der Client-Anwendung an, sie startet, fügt einen dritten Knoten zur Topologie hinzu und sofort gibt es wieder nur zwei Knoten. Im Log steht „ClassNotFoundException: model.SalesPoint“ in Zeile
SalesPoint sp=salesPointCache.get(spId);StackOverflow sagt, dass die Ursache des Fehlers darin liegt, dass auf den CentOs-Servern die Benutzerklasse SalesPoint nicht vorhanden ist. Das ist Pech. Wie kann es sein, dass „you don’t have to manually deploy your Java code on each node“ und weiter im Text? Oder ist „your Java code“ nicht über SalesPoint gemeint?
Wahrscheinlich habe ich etwas übersehen – ich beginne erneut zu suchen, zu lesen und wieder zu suchen. Nach einer Zeit habe ich das Gefühl, dass ich zum Thema alles gelesen habe, nichts Neues ist mehr dabei. Während ich suchte, fand ich einige interessante Anmerkungen.
, Lead Architect bei GridGain Systems, auf StackOverflow, April 2016:
Modelklassen werden nicht untereinander bereitgestellt, aber Sie können das withKeepBinary()-Flag
im Cache verwenden und BinaryObjects abfragen. So vermeiden Sie die Deserialisierung
auf der Serverseite und erhalten keine ClassNotFoundException.Eine weitere autoritative Meinung: , Director of Product Management, GridGain Systems.
Artikel auf Habré verweist auf drei Artikel von Denis Magda: , , 2016-2017 Jahre. Im zweiten Artikel schlägt Denis vor, einen Knoten des Clusters über MaintenanceServiceNodeStartup.jar zu starten. Es ist auch möglich, den Start mit einer XML-Konfiguration und der Kommandozeile zu verwenden, aber dann müssen die benutzerdefinierten Klassen jedes Mal manuell auf jeden bereitgestellten Clusterknoten gelegt werden:
Das ist es. Starten Sie (..) den Knoten unter Verwendung der MaintenanceServiceNodeStartup-Datei oder übergeben Sie maintenance-service-node-config.xml an die Apache Ignite ignite.sh/bat-Skripte. 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 zum Classpath jedes Knotens hinzugefügt werden, wo der Dienst möglicherweise bereitgestellt wird.In der Tat, das ist es. So, dafür gibt es also dieses mysteriöse Binärformat!
3. SingleJar
Denis hat in meinem persönlichen Ranking den ersten Platz belegt, meiner Meinung nach das nützlichste Tutorial unter allen verfügbaren. In seinem auf GitHub befindet sich ein vollständig funktionierendes Beispiel zur Konfiguration der Clusterknoten, das ohne zusätzliche Schwierigkeiten kompiliert werden kann.
Ich orientiere mich daran und erhalte eine einzige JAR-Datei, die entweder einen „Data Node“ oder einen „Client Node“ je nach Kommandozeilenargument startet. Der Build wird gestartet und funktioniert. Zero Deployment ist besiegt.
Der Übergang von Megabytes an Testdaten zu Dutzenden von Gigabytes an Produktionsdaten hat gezeigt, dass das Binärformat nicht umsonst existiert. Es war notwendig, den Speicherverbrauch auf den Knoten zu optimieren, und hier war BinaryObject sehr nützlich.
4. Fazit
Der erste vorgebrachte Vorwurf hinsichtlich der Unklarheit der Dokumentation des Apache Ignite-Projekts war berechtigt, seit 2016 hat sich nur wenig geändert. Es ist für Anfänger schwierig, einen funktionierenden Prototyp auf Grundlage der Website und/oder des Repositories zu erstellen.
Am Ende der durchgeführten Arbeiten entstand der Eindruck, dass Zero Deployment funktioniert, jedoch nur auf systemischer Ebene. Ungefähr so: BinaryObject wird verwendet, um entfernte Knoten des Clusters zu lehren, mit benutzerdefinierten Klassen zu arbeiten; Zero Deployment ist ein interner Mechanismus
von Apache Ignite selbst und verbreitet systemweite Objekte im Cluster.
Ich hoffe, meine Erfahrungen werden neuen Nutzern von Apache Ignite nützlich sein.
Quelle: habr.com
