
Jsme oddělení technologického rozvoje maloobchodní sítě. Jednou vedení zadalo úkol urychlit objemové výpočty použitím Apache Ignite ve spojení s MSSQL a ukázalo web s vynikajícími ilustracemi a příklady Java kódu. Na webu mě ihned zaujala. , jehož popis slibuje zázraky: nemusíte ručně nasazovat svůj Java nebo Scala kód na každý uzel v mřížce a znovu ho nasazovat při každé změně. Při práci se ukázalo, že Zero Deployment má specifika užívání, o který se chci podělit. Pod katem najdete úvahy a podrobnosti realizace.
1. Stanovení úkolu
Podstata úkolu je následující. Existuje adresář prodejních míst SalesPoint a adresář produktů Sku (Stock Keeping Unit). Prodejní místo má atribut „typObchodu“ se hodnotami „malý“ a „velký“. K každému prodejnímu místu se připojuje (nahrává z DB) sortiment (seznam produktů prodejního místa) a je dodávána informace, že od uvedeného data daný produkt
se vyřazuje ze sortimentu nebo je přidáván do sortimentu.
Je třeba uspořádat partišionovanou cache prodejních míst a uchovávat v ní informace o připojených produktech na měsíc dopředu. Kompatibilita s produkčním systémem vyžaduje, aby klientský uzel Ignite nahrál data, vypočítal agregát ve formátu (typObchodu, kódProduktu, den, počet_prodejních_míst) a vrátil ho zpět do DB.
2. Studium literatury
Zatím nemám zkušenosti, takže začínám od nuly. Tedy se seznamu publikací.
Článek z roku 2016 obsahuje odkaz na dokumentaci projektu Apache Ignite a zároveň kritiku nejasnosti této dokumentace. Přečetl jsem to několikrát, jasnost nenastává. Obracím se na oficiální tutoriál , který
optimisticky slibuje „Budeš připravený běžet během chvilky!“. Zkoumám nastavování proměnných prostředí, sleduji dvě videa Apache Ignite Essentials, která se pro moji konkrétní úlohu ukázala jako nepříliš užitečná. Úspěšně spouštím Ignite z příkazového řádku se standardním souborem „example-ignite.xml“, vytvářím první aplikaci pomocí Maven. Aplikace funguje a používá Zero Deployment, jaká krása!
Čtu dál, a tam příklad hned používá affinityKey (vytvořený dříve přes SQL dotaz), a ještě se používá záhadný BinaryObject:
IgniteCache people
= ignite.cache("Person").withKeepBinary(); Přečetl jsem : binární formát — něco jako reflexe, přístup k polím objektu podle názvu. Může číst hodnotu pole bez úplné deserializace objektu (úspora paměti). Ale proč je místo Person použit BinaryObject, vždyť existuje Zero Deployment? Proč se IgniteCache<Key,Person> překládá na IgniteCache<BinaryObject, BinaryObject>? Zatím není jasné.
Předělávám Compute Application podle svého případu. Primární klíč referenční tabulky prodejních míst v MSSQL je definován jako [id] [int] NOT NULL, vytvářím cache analogicky.
IgniteCache<Integer, SalesPoint> salesPointCache=ignite.cache("spCache")V xml-configu uvádím, že cache je partitioned.
<bean class="org.apache.ignite.configuration.CacheConfiguration">
<property name="name" value="spCache"/>
<property name="cacheMode" value="PARTITIONED"/>
</bean>Partitionace podle prodejních míst předpokládá, že požadovaný agregát bude vytvořen na každém uzlu clusteru pro existující záznamy salesPointCache, po čemž klientský uzel provede konečné souhrnné vyhodnocení.
Čtu tutoriál. , dělám podle analogy. Na každém uzlu clusteru spouštím IgniteRunnable(), zhruba takto:
@Override
public void run() {
SalesPoint sp=salesPointCache.get(spId);
sp.calculateSalesPointCount();
..
}Přidávám logiku agregace a exportu, spouštím na testovacím datovém souboru. Lokálně na vývojovém serveru to všechno funguje.
Spouštím dva testovací servery CentOs, uvádím IP adresy v default-config.xml, provádím na každém.
.\/bin\/ignite.sh config\/default-config.xmlOba uzly Ignite se spouští a vidí se navzájem. Uvádím požadované adresy v xml-configu klientské aplikace, ta se spouští, přidává třetí uzel do topologie a hned je zpět opět jen dva. V logu se zapisuje „ClassNotFoundException: model.SalesPoint“ na řádku
SalesPoint sp=salesPointCache.get(spId);StackOverflow říká, že příčinou chyby je — na serverech CentOs není uživatelská třída SalesPoint. To je katastrofa. Jak to tedy je s „you don’t have to manually deploy your Java code on each node“ a dále v textu? Nebo „your Java code“ — to se netýká SalesPoint?
Pravděpodobně jsem něco přehlédl — znovu začínám hledat, číst a znovu hledat. Po chvíli vyvstává pocit, že jsem přečetl všechno, co se tématu týká, nic nového už není. Zatímco jsem hledal, našel jsem několik zajímavých připomínek.
, Lead Architect at GridGain Systems, na StackOverflow, duben 2016:
Modelové třídy nejsou nasazeny paralelně, ale můžete použít sKeepBinary() příznak
na cache a dotazovat se na BinaryObjects. Tím se vyhnete deserializaci
na serverové straně a nezískáte ClassNotFoundException.Ještě jedno autoritativní názory: , ředitel správy produktu, GridGain Systems.
Článek na Habr odkazuje na tři články Denis Magda: , , Roky 2016-2017. V druhém článku Denis navrhuje spustit uzel clustera pomocí MaintenanceServiceNodeStartup.jar. Můžete také použít spuštění s xml konfigurací a příkazovým řádkem, ale v tomto případě musíte ručně umístit uživatelské třídy na každý nasazovaný uzel clustera:
To je vše. Spusťte (..) uzel pomocí souboru MaintenanceServiceNodeStartup nebo zadejte
maintenance-service-node-config.xml do skriptů ignite.sh / bat Apache Ignite.
Pokud dáváte přednost druhé možnosti, ujistěte se, že vytvoříte jar soubor, který bude obsahovat
všechny třídy z java/app/common a java/services/maintenance adresářů.
Jar musí být přidán do classpath každého uzlu, na kterém může být služba
nasazena.Opravu, to je ono. Tady je, ukázalo se, proč je tento tajemný binární formát!
3. SingleJar
Denis zaujímá první místo v mém osobním hodnocení, imo nejvíce užitečný tutoriál ze všech dostupných. Ve svém na GitHubu je kompletně připravený příklad nastavení uzlů clustera, který se kompiluje bez jakýchkoli dalších obtíží.
Dělám to podle vzoru a dostávám jediný jar soubor, který spouští "data node" nebo "client node" v závislosti na argumentu příkazového řádku. Sestavení se spustí a funguje. Zero Deployment je poražen.
Přechod od megabajtových testovacích dat k desítkám gigabajtů výrobních ukázal, že binární formát existuje z nějakého důvodu. Bylo potřeba optimalizovat spotřebu paměti na uzlech, a tady se BinaryObject ukázal jako velmi užitečný.
4. Závěry
První zmiňovaná výtka k nejasnosti dokumentace projektu Apache Ignite se ukázala jako oprávněná, od roku 2016 se toho moc nezměnilo. Nováčkovi není snadné sestavit fungující prototyp na základě webu a/nebo repozitáře.
Z výsledků práce vyvstává dojem, že Zero Deployment funguje, ale pouze na systémové úrovni. Přibližně tak: BinaryObject se používá k naučení vzdálených uzlů clustera pracovat s uživatelskými třídami; Zero Deployment je interní mechanismus
samotného Apache Ignite a šíří systémové objekty po clusteru.
Doufám, že moje zkušenost bude užitečná novým uživatelům Apache Ignite.
Zdroj: habr.com
