Apache Ignite Zero Deployment: davvero zero?

Apache Ignite Zero Deployment: davvero zero?

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 Distribuzione zero, la cui descrizione promette miracoli: non è necessario distribuire manualmente il codice Java o Scala su ciascun nodo della griglia e ridistribuirlo ogni volta che cambia. Man mano che il lavoro procedeva, si è scoperto che Zero Deployment ha usi specifici, di cui desidero condividere le caratteristiche. Sotto il taglio ci sono pensieri e dettagli di implementazione.

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 Presentazione di Apache Ignite: primi passi contiene un collegamento alla documentazione del progetto Apache Ignite e allo stesso tempo un rimprovero per la vaghezza di questa documentazione. L'ho riletto un paio di volte, la chiarezza non arriva. Mi riferisco al tutorial ufficiale iniziareChe
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 Applicazione di calcolo utilizzando Maven. L'applicazione funziona e utilizza Zero Deployment, che bellezza!

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 leggermente: formato binario - qualcosa come riflessione, accesso ai campi di un oggetto per nome. Può leggere il valore di un campo senza deserializzare completamente l'oggetto (risparmiando memoria). Ma perché viene utilizzato BinaryObject al posto di Person, dal momento che esiste Zero Deployment? Perché IgniteCache trasferito a IgniteCache ? Non è ancora chiaro.

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 Prima applicazione di elaborazione Ignite, lo faccio per analogia. Su ciascun nodo del cluster eseguo IgniteRunnable(), qualcosa del genere:

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

Valentin Kulichenko, Architetto capo presso GridGain Systems, risposta su StackOverflow, aprile 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.

Un'altra opinione autorevole: Denis Magda, Direttore della gestione del prodotto, GridGain Systems.

Articolo su Habré sui microservizi fa riferimento a tre articoli di Denis Magda: Microservizi Parte I, Microservizi Parte II, Microservizi Parte III 2016-2017. Nel secondo articolo, Denis suggerisce di avviare un nodo del cluster tramite MaintenanceServiceNodeStartup.jar. Puoi anche utilizzare launch con configurazione xml e riga di comando, ma poi devi inserire manualmente classi personalizzate su ciascun nodo del cluster distribuito:

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 Esempio di microservizi Github contiene un esempio completamente già pronto di impostazione dei nodi del cluster, che si compila senza ulteriori accovacciamenti.

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

Aggiungi un commento