Apache Ignite Zero Deployment: virkelig Zero?

Apache Ignite Zero Deployment: virkelig Zero?

Vi er teknologieudviklingsafdelingen for detailnetværket. En dag gav ledelsen os opgaven at accelerere de store beregninger ved at bruge Apache Ignite sammen med MSSQL og viste en hjemmeside med fantastiske illustrationer og eksempler på Java-kode. Jeg kunne straks lide hjemmesiden. Zero Deployment, som lover mirakler: du behøver ikke manuelt at implementere din Java- eller Scala-kode på hver node i nettet og genimplementere den hver gang, den ændres. Undervejs viste det sig, at Zero Deployment har sine egne specifikationer, som jeg gerne vil dele. Læs videre for mine tanker og detaljer om implementeringen.

1. Problemformulering

Essensen af opgaven er som følger. Der er en database over salgssteder (SalesPoint) og en database over produkter (Sku - Stock Keeping Unit). Salgsstedet har en attribut "typeButik" med værdierne "lille" og "stor". Hvert salgssted får tilknyttet (indlæst fra databasen) et sortiment (listen over produkter for salgsstedet) og information om, at et bestemt produkt fra en given dato
udelukkes fra sortimentet eller føjes til sortimentet.

Det kræves, at der organiseres en partitioneret cache for salgsstederne og opbevares information om de tilknyttede produkter en måned frem. Kompatibilitet med produktionssystemet kræver, at Ignite-klientnoden indlæser data, beregner et aggregat af typen (typeButik, produktkode, dag, antal_salgssteder) og uploader det tilbage til databasen.

2. Litteraturstudie

Jeg har endnu ingen erfaring, så jeg starter fra bunden. Det vil sige med en gennemgang af publikationerne.

Artiklen fra 2016 Introduktion til Apache Ignite: første skridt indeholder et link til dokumentationen for projektet Apache Ignite og samtidig en kritik af uklarheden i denne dokumentation. Jeg har læst det igennem et par gange, men klarheden kommer ikke. Jeg vender mig til den officielle tutorial getting-started, som
som optimistisk lover "Du vil være oppe at køre på ingen tid!". Jeg sætter mig ind i indstillingen af miljøvariabler, ser to videoer af Apache Ignite Essentials; for min specifikke opgave viste de sig ikke at være meget nyttige. Jeg får succes med at starte Ignite fra kommandolinjen med den standardfil "example-ignite.xml", og bygger mit første program Compute Application ved hjælp af Maven. Programmet fungerer og bruger Zero Deployment, hvor er det smukt!

Jeg læser videre, og der bruges straks affinityKey (som blev oprettet tidligere via en SQL-forespørgsel), og der anvendes også den mystiske BinaryObject:

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

Jeg har læst lidt: binært format — noget som ligner reflektion, adgang til objektfelter ved navn. Kan læse værdien af et felt uden fuld deserialisering af objektet (besparelse af hukommelse). Men hvorfor bruges BinaryObject i stedet for Person, når der findes Zero Deployment? Hvorfor oversættes IgniteCache<Key,Person> til IgniteCache<BinaryObject, BinaryObject>? Det er stadig uklart.

Jeg tilpasser Compute Application til mit tilfælde. Den primære nøgle for opgavelisten i MSSQL er defineret som [id] [int] NOT NULL, jeg opretter cache på samme måde.

IgniteCache<Integer, SalesPoint> salesPointCache=ignite.cache("spCache")

I xml-konfigurationen angiver jeg, at cachen er partitioneret.

<bean class="org.apache.ignite.configuration.CacheConfiguration">
    <property name="name" value="spCache"/>
    <property name="cacheMode" value="PARTITIONED"/>
<\/bean>

Partitionering baseret på salgspunkter antyder, at den nødvendige aggregering vil blive bygget på hver node i klyngen for de eksisterende poster i salesPointCache, hvorefter klientnoden vil udføre den samlede opsummering.

Jeg læser tutorial. Første Ignite Compute Application., jeg gør det på samme måde. På hver node i klyngen kører jeg IgniteRunnable(), cirka sådan her:

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

Jeg tilføjer logik til aggregering og eksport, kører den på et testdatasæt. Lokalt på udviklingsserveren fungerer alt.

Jeg starter to testservere CentOs, angiver IP-adresser i default-config.xml og udfører på hver.

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

Begge Ignite-noder startes og ser hinanden. Jeg angiver de nødvendige adresser i xml-konfigurationen for klientapplikationen, den startes, tilføjer den tredje node til topologien og straks bliver der igen to noder. I loggen står der «ClassNotFoundException: model.SalesPoint» i linje

SalesPoint sp=salesPointCache.get(spId);

StackOverflow siger, at årsagen til fejlen er, at den brugerdefinerede klasse SalesPoint ikke er til stede på CentOs-serverne. Vi er færdige. Hvad med «you don’t have to manually deploy your Java code on each node» og videre? Eller er «your Java code» ikke om SalesPoint?

Måske har jeg overset noget — jeg begynder igen at søge, læse og igen søge. Efter et stykke tid får jeg en fornemmelse af, at jeg har læst alt om emnet, der er ikke noget nyt. Mens jeg søgte, fandt jeg flere interessante bemærkninger.

Valentin Kulichenko, Lead Architect at GridGain Systems, @cassowary714 på StackOverflow, april 2016:

Modelklasser er ikke peer-deployet, men du kan bruge withKeepBinary() flaget
på cachen og forespørge BinaryObjects. På denne måde undgår du deserialisering
på serversiden og får ikke ClassNotFoundException.

Endnu en autoritativ mening: Denis Magda, Director of Product Management, GridGain Systems.

Artikel på Habré om mikrotjenester. Henviser til tre artikler af Denis Magda: Microservices Del I, Microservices Del II, Microservices Del III 2016-2017. I den anden artikel foreslår Denis at starte en cluster node via MaintenanceServiceNodeStartup.jar. Du kan også bruge opstart med xml-konfiguration og kommandolinje, men så skal du manuelt lægge brugerdefinerede klasser på hver enkelt node, der distribueres:

Det er det. Start (..) node ved at bruge MaintenanceServiceNodeStartup-filen eller giv maintenance-service-node-config.xml til Apache Ignites ignite.sh/bat scripts. Hvis du foretrækker det sidste, så sørg for at bygge en jar-fil, der indeholder alle klasser fra java/app/common og java/services/maintenance mapperne. Jaren skal tilføjes til classpath'en på hver node, hvor tjenesten måtte blive distribueret.

Faktisk, det er det. Her er han, tilsyneladende, grunden til denne mystiske binære format!

3. SingleJar

Denis indtager førstepladsen i min personlige rangordning, imo det mest nyttige tutorial af alle tilgængelige. I hans MicroServicesExample på GitHub findes et helt klart eksempel på opsætning af cluster noder, som kompileres uden yderligere problemer.

Jeg følger opskriften og får en enkelt jar-fil, der starter enten en "data node" eller "client node" alt efter kommandolinjeargumentet. Bygningen startes og fungerer. Zero Deployment er besejret.

Overgangen fra megabyte testdata til titusinder af gigabyte produktionsdata har vist, at det binære format har sin berettigelse. Det var nødvendigt at optimere hukommelsesforbruget på noderne, og her viste BinaryObject sig at være meget nyttig.

4. Konklusioner

Den første kritik af dokumentationens uklarhed i Apache Ignite projektet viste sig at være berettiget, der har ikke ændret sig meget siden 2016. Det er ikke nemt for en nybegynder at samle en fungerende prototype ud fra hjemmesiden og/eller repositoriet.

Som et resultat af det udførte arbejde har jeg fået indtrykket af, at Zero Deployment fungerer, men kun på systemniveau. Cirka sådan: BinaryObject bruges til at lære de fjerne noder i clustret at arbejde med brugerdefinerede klasser; Zero Deployment er en intern mekanisme
af selve Apache Ignite og distribuerer systemobjekter i clustret.

Jeg håber, at min erfaring vil være nyttig for nye brugere af Apache Ignite.

Kilde: habr.com

Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere 🔥 Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere | ProHoster