Siamo il dipartimento di sviluppo tecnologico di una rete di vendita al dettaglio. Un giorno, la direzione si è posta il compito di accelerare i calcoli su larga scala utilizzando Apache Ignite insieme a MSSQL e ha mostrato un sito Web con bellissime illustrazioni ed esempi di codice Java. Il sito mi è subito piaciuto
1. Dichiarazione del problema
L'essenza del problema è la seguente. È presente una directory dei punti vendita SalesPoint e una directory dei prodotti Sku (Stock Keeping Unit). Il punto vendita ha un attributo “Tipo di negozio” con i valori “piccolo” e “grande”. Ad ogni punto vendita (caricato dal DBMS) è collegato un assortimento (elenco dei prodotti del punto vendita) e viene fornita l'informazione che dalla data specificata il prodotto specificato
esclusi dall'assortimento o aggiunti all'assortimento.
È necessario organizzare una cache partizionata di punti vendita e archiviare in essa le informazioni sui prodotti collegati con un mese di anticipo. La compatibilità con il sistema di combattimento richiede che il nodo client Ignite carichi i dati, calcoli un aggregato del modulo (tipo di negozio, codice prodotto, giorno, numero_di_punti_di_vendita) e lo carichi nuovamente nel DBMS.
2. Studio della letteratura
Non ho ancora alcuna esperienza, quindi sto iniziando a ballare dai fornelli. Cioè, da una revisione delle pubblicazioni.
Articolo del 2016
promette ottimisticamente "Sarai operativo in un batter d'occhio!" Sto cercando di capire le impostazioni delle variabili d'ambiente, guardando due video di Apache Ignite Essentials, ma non sono stati molto utili per il mio compito specifico. Lancio con successo Ignite dalla riga di comando con il file standard “example-ignite.xml”, costruendo la prima applicazione
Ho letto oltre, e lì l'esempio utilizza immediatamente affinityKey (creato in precedenza tramite una query SQL) e utilizza persino il misterioso BinaryObject:
IgniteCache<BinaryObject, BinaryObject> people
= ignite.cache("Person").withKeepBinary();
Leggere
Sto rifacendo l'applicazione di calcolo per adattarla al mio caso. La chiave primaria della directory dei punti vendita in MSSQL è definita come [id] [int] NOT NULL, creo una cache per analogia
IgniteCache<Integer, SalesPoint> salesPointCache=ignite.cache("spCache")
Nella configurazione xml indico che la cache è partizionata
<bean class="org.apache.ignite.configuration.CacheConfiguration">
<property name="name" value="spCache"/>
<property name="cacheMode" value="PARTITIONED"/>
</bean>
Il partizionamento per punto vendita presuppone che l'aggregato richiesto verrà creato su ciascun nodo del cluster per i record salesPointCache ivi disponibili, dopodiché il nodo client eseguirà la somma finale.
Sto leggendo il tutorial
@Override
public void run() {
SalesPoint sp=salesPointCache.get(spId);
sp.calculateSalesPointCount();
..
}
Aggiungo la logica di aggregazione e caricamento e la eseguo su un set di dati di prova. Tutto funziona localmente sul server di sviluppo.
Lancio due server di test CentOs, specifico gli indirizzi IP in default-config.xml ed eseguo su ciascuno
./bin/ignite.sh config/default-config.xml
Entrambi i nodi Ignite sono in esecuzione e possono vedersi. Specifico gli indirizzi richiesti nella configurazione xml dell'applicazione client, si avvia, aggiunge un terzo nodo alla topologia e immediatamente ci sono di nuovo due nodi. Il registro mostra "ClassNotFoundException: model.SalesPoint" nella riga
SalesPoint sp=salesPointCache.get(spId);
StackOverflow afferma che il motivo dell'errore è che non esiste una classe SalesPoint personalizzata sui server CentOs. Siamo arrivati. Che ne dici di "non è necessario distribuire manualmente il codice Java su ciascun nodo" e così via? Oppure il "tuo codice Java" non riguarda SalesPoint?
Probabilmente mi sono perso qualcosa: ricomincio a cercare, leggere e cercare di nuovo. Dopo un po' ho la sensazione di aver letto tutto sull'argomento, che non ci sia più nulla di nuovo. Mentre cercavo ho trovato alcuni commenti interessanti.
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.
Un'altra opinione autorevole:
Articolo su 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.
In effetti, questo è tutto. Ecco perché, questo misterioso formato binario!
3.Vaso singolo
Denis si è classificato al primo posto nella mia classifica personale, IMHO il tutorial più utile tra tutti quelli disponibili. Nel suo
Lo faccio allo stesso modo e ottengo un singolo file jar che avvia "nodo dati" o "nodo client" a seconda dell'argomento della riga di comando. L'assemblea parte e funziona. Lo Zero Deployment è stato sconfitto.
Il passaggio da megabyte di dati di test a decine di gigabyte di dati di combattimento ha dimostrato che il formato binario esiste per un motivo. Era necessario ottimizzare il consumo di memoria sui nodi, ed è qui che BinaryObject si è rivelato molto utile.
4. risultati
Il primo rimprovero riscontrato riguardo alla vaghezza della documentazione del progetto Apache Ignite si è rivelato giusto; poco è cambiato dal 2016. Non è facile per un principiante assemblare un prototipo funzionante basato su un sito web e/o un repository.
In base ai risultati del lavoro svolto, l’impressione è stata che Zero Deployment funzioni, ma solo a livello di sistema. Qualcosa del genere: BinaryObject viene utilizzato per insegnare ai nodi del cluster remoti a lavorare con classi personalizzate; Zero Deployment: meccanismo interno
Apache Ignite stesso e distribuisce gli oggetti di sistema in tutto il cluster.
Spero che la mia esperienza possa essere utile ai nuovi utenti di Apache Ignite.
Fonte: habr.com