Apache Ignite Zero Deployment: Verkligen noll?

Apache Ignite Zero Deployment: Verkligen noll?

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 Noll distribution, vars beskrivning lovar mirakel: du behöver inte manuellt distribuera din Java- eller Scala-kod på varje nod i rutnätet och distribuera om den varje gång den ändras. Allt eftersom arbetet fortskred visade det sig att Zero Deployment har specifika användningsområden, vars funktioner jag vill dela med mig av. Under snittet finns tankar och genomförandedetaljer.

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 Vi presenterar Apache Ignite: First Steps innehåller en länk till dokumentationen för Apache Ignite-projektet och samtidigt en förebråelse för vagheten i denna dokumentation. Jag läser den igen ett par gånger, klarhet kommer inte. Jag hänvisar till den officiella handledningen komma igångSom
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 Beräkna applikation använder Maven. Applikationen fungerar och använder Zero Deployment, vilken skönhet!

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 немного: binärt format - något som reflektion, åtkomst till fälten i ett objekt med namn. Kan läsa värdet på ett fält utan att helt deserialisera objektet (spara minne). Men varför används BinaryObject istället för Person, eftersom det finns Zero Deployment? Varför IgniteCache överförs till IgniteCache ? Det är inte klart än.

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 Första Ignite Compute-applikationen, jag gör det analogt. På varje klusternod kör jag IgniteRunnable(), ungefär så här:

  @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.

Valentin Kulichenko, ledande arkitekt på GridGain Systems, ответ på 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.

En annan auktoritativ åsikt: Denis Magda, direktör för produktledning, GridGain Systems.

Artikel om Habré om mikrotjänster refererar till tre artiklar av Denis Magda: Mikrotjänster del I, Mikrotjänster del II, Mikrotjänster del III 2016-2017. I den andra artikeln föreslår Denis att du startar en klusternod via MaintenanceServiceNodeStartup.jar. Du kan också använda start med xml-konfiguration och kommandorad, men då måste du manuellt sätta anpassade klasser på varje distribuerad klusternod:

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 MicroServicesExempel Github innehåller ett helt färdigt exempel på att sätta upp klusternoder, som kompilerar utan ytterligare squatting.

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

Lägg en kommentar