Vi är teknikutvecklingsavdelningen för ett detaljhandelsnätverk. En dag satte ledningen i uppdrag att påskynda storskaliga beräkningar genom att använda Apache Ignite i kombination med MSSQL, och visade en webbplats med vackra illustrationer och exempel på Java-kod. Jag gillade sidan direkt
1. Redogörelse för problemet
Kärnan i problemet är följande. Det finns en SalesPoint-katalog över försäljningsställen och en produktkatalog för Sku (Stock Keeping Unit). Försäljningsstället har attributet "Store type" med värdena "small" och "large". Ett sortiment (lista över produkter från försäljningsstället) är kopplat till varje försäljningsställe (laddat från DBMS) och information ges att från det angivna datumet den angivna produkten
exkluderas ur sortimentet eller läggs till sortimentet.
Det är nödvändigt att organisera en uppdelad cache för försäljningsställen och lagra information om anslutna produkter i den en månad i förväg. Kompatibilitet med stridssystemet kräver att Ignite-klientnoden laddar data, beräknar ett aggregat av formuläret (butikstyp, produktkod, dag, antal_försäljningspoäng) och laddar upp det tillbaka till DBMS.
2. Litteraturstudie
Jag har ingen erfarenhet än, så jag börjar dansa från spisen. Det vill säga från en granskning av publikationer.
Artikel 2016
lovar optimistiskt "Du kommer att vara igång i en handvändning!" Jag håller på att ta reda på miljövariabelinställningarna, tittar på två Apache Ignite Essentials-videor, men de var inte särskilt användbara för min specifika uppgift. Jag startar framgångsrikt Ignite från kommandoraden med standardfilen "example-ignite.xml", och bygger det första programmet
Jag läste vidare, och där använder exemplet omedelbart affinityKey (skapat tidigare genom en SQL-fråga), och använder till och med det mystiska BinaryObject:
IgniteCache<BinaryObject, BinaryObject> people
= ignite.cache("Person").withKeepBinary();
läsa
Jag gör om Compute-applikationen för att passa mitt fall. Den primära nyckeln för katalogen över försäljningsställen i MSSQL definieras som [id] [int] INTE NULL, jag skapar en cache i analogi
IgniteCache<Integer, SalesPoint> salesPointCache=ignite.cache("spCache")
I xml-konfigurationen anger jag att cachen är partitionerad
<bean class="org.apache.ignite.configuration.CacheConfiguration">
<property name="name" value="spCache"/>
<property name="cacheMode" value="PARTITIONED"/>
</bean>
Partitionering efter försäljningsställe förutsätter att det nödvändiga aggregatet kommer att byggas på varje klusternod för de salesPointCache-poster som finns tillgängliga där, varefter klientnoden kommer att utföra den slutliga summeringen.
Jag läser handledningen
@Override
public void run() {
SalesPoint sp=salesPointCache.get(spId);
sp.calculateSalesPointCount();
..
}
Jag lägger till aggregerings- och uppladdningslogik och kör den på en testdatauppsättning. Allt fungerar lokalt på utvecklingsservern.
Jag startar två CentOs-testservrar, anger IP-adresserna i default-config.xml, kör på varje
./bin/ignite.sh config/default-config.xml
Båda Ignite-noderna är igång och kan se varandra. Jag anger de nödvändiga adresserna i xml-konfigurationen för klientapplikationen, den startar, lägger till en tredje nod till topologin och omedelbart finns det två noder igen. Loggen visar "ClassNotFoundException: model.SalesPoint" på raden
SalesPoint sp=salesPointCache.get(spId);
StackOverflow säger att orsaken till felet är att det inte finns någon anpassad SalesPoint-klass på CentOs servrar. Vi har kommit. Vad sägs om "du behöver inte manuellt distribuera din Java-kod på varje nod" och så vidare? Eller handlar "din Java-kod" inte om SalesPoint?
Jag har nog missat något – jag börjar söka igen, läser och söker igen. Efter ett tag får jag en känsla av att jag har läst allt om ämnet, det är inget nytt längre. Medan jag letade hittade jag några intressanta kommentarer.
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.
En annan auktoritativ åsikt:
Artikel om 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.
Ja, det är det. Här visar det sig, varför, detta mystiska binära format!
3.SingleJar
Denis tog första platsen i mitt personliga betyg, IMHO den mest användbara handledningen av alla tillgängliga. I hans
Jag gör det på samma sätt och får en enda jar-fil som startar "datanod" eller "klientnod" beroende på kommandoradsargumentet. Monteringen startar och fungerar. Zero Deployment har besegrats.
Övergången från megabyte testdata till tiotals gigabyte stridsdata visade att det binära formatet existerar av en anledning. Det var nödvändigt att optimera minnesförbrukningen på noder, och det var här BinaryObject visade sig vara mycket användbart.
4. Sammanfattningar
Den första förebråelsen som man stötte på om vagheten i Apache Ignite-projektets dokumentation visade sig vara rättvis; lite har förändrats sedan 2016. Det är inte lätt för en nybörjare att sätta ihop en fungerande prototyp baserat på en webbplats och/eller ett arkiv.
Baserat på resultatet av det utförda arbetet var intrycket att Zero Deployment fungerar, men bara på systemnivå. Något så här: BinaryObject används för att lära fjärrklusternoder att arbeta med anpassade klasser; Zero Deployment - intern mekanism
Apache Ignite sig själv och distribuerar systemobjekt i hela klustret.
Jag hoppas att min erfarenhet kommer att vara användbar för nya Apache Ignite-användare.
Källa: will.com