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
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
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
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
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
@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.
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:
Artikel über Habré
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
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