Domanda

Ho un'applicazione che è un mix di Java e C++ su Solaris.Gli aspetti Java del codice eseguono l'interfaccia utente Web e stabiliscono lo stato dei dispositivi con cui stiamo parlando, mentre il codice C++ esegue l'elaborazione in tempo reale dei dati provenienti dai dispositivi.La memoria condivisa viene utilizzata per passare informazioni sullo stato del dispositivo e sul contesto dal codice Java al codice C++.Il codice Java utilizza un database PostgreSQL per rendere persistente il proprio stato.

Stiamo riscontrando alcuni colli di bottiglia prestazionali piuttosto gravi e al momento l'unico modo per scalare è aumentare il numero di memoria e CPU.Siamo bloccati su un'unica scatola fisica a causa del design della memoria condivisa.


Il vero grande successo qui viene preso dal codice C++.L'interfaccia web è utilizzata in modo abbastanza leggero per configurare i dispositivi;dove facciamo davvero fatica è gestire i volumi di dati che i dispositivi forniscono una volta configurati.

Ogni dato che riceviamo dal dispositivo contiene un identificatore che rimanda al contesto del dispositivo e dobbiamo cercarlo.Al momento c'è una serie di oggetti di memoria condivisa che vengono gestiti dal codice Java/UI e a cui fa riferimento il codice C++, e questo è il collo di bottiglia.A causa di questa architettura non possiamo spostare la gestione dei dati C++ su un'altra macchina.Dobbiamo essere in grado di aumentare la scalabilità in modo che vari sottoinsiemi di dispositivi possano essere gestiti da macchine diverse, ma poi perdiamo la capacità di eseguire la ricerca del contesto e questo è il problema che sto cercando di risolvere:come scaricare l'elaborazione dei dati in tempo reale su altri box pur potendo fare riferimento al contesto del dispositivo.

Dovrei sottolineare che non abbiamo alcun controllo sul protocollo utilizzato dai dispositivi stessi e non vi è alcuna possibilità che la situazione cambi.


Sappiamo che dobbiamo allontanarci da questo per poter scalare aggiungendo più macchine al cluster, e sono nelle prime fasi di capire esattamente come lo faremo.

In questo momento sto considerando Terracotta come un modo per scalare il codice Java, ma non sono ancora riuscito a capire come scalare il C++ per adattarlo.

Oltre alla scalabilità delle prestazioni, dobbiamo considerare anche l'elevata disponibilità.L'applicazione deve essere disponibile praticamente per tutto il tempo, non assolutamente al 100%, il che non è conveniente, ma dobbiamo fare un lavoro ragionevole per sopravvivere a un'interruzione della macchina.

Se dovessi intraprendere il compito che mi è stato affidato, cosa faresti?

MODIFICARE:Sulla base dei dati forniti da @john channing, sto esaminando sia GigaSpaces che Gemstone.Oracle Coherence e IBM ObjectGrid sembrano essere solo Java.

È stato utile?

Soluzione

La prima cosa che farei è costruire un modello del sistema per mappare il flusso di dati e cercare di capire esattamente dove si trova il collo di bottiglia.Se puoi modellare il tuo sistema come a tubatura, allora dovresti essere in grado di utilizzare la teoria dei vincoli (la maggior parte della letteratura riguarda l'ottimizzazione dei processi aziendali ma si applica anche al software) per migliorare continuamente le prestazioni ed eliminare il collo di bottiglia.

Successivamente raccoglierei alcuni dati empirici concreti che caratterizzano accuratamente le prestazioni del tuo sistema.È una sorta di cliché che non sia possibile gestire ciò che non è possibile misurare, ma ho visto molte persone tentare di ottimizzare un sistema software basandosi su intuizioni e fallire miseramente.

Allora userei il Principio di Pareto (regola 80/20) scegliere il piccolo numero di cose che produrranno i maggiori guadagni e concentrarsi solo su quelle.

Per ridimensionare orizzontalmente un'applicazione Java, ho utilizzato Coerenza oracolare ampiamente.Anche se alcuni lo considerano molto costoso tabella hash distribuita, la funzionalità è molto più ricca e puoi, ad esempio, accedere direttamente ai dati nella cache da Codice C++ .

Altre alternative per ridimensionare orizzontalmente il tuo codice Java sarebbero Gigaspazi, Griglia di oggetti IBM O Pietra preziosa Gemfire.

Se il tuo codice C++ è senza stato e viene utilizzato esclusivamente per l'elaborazione dei numeri, potresti provare a distribuire il processo utilizzando Griglia del GHIACCIO che ha associazioni per tutte le lingue che stai utilizzando.

Altri suggerimenti

È necessario ridimensionarsi lateralmente e verso l'esterno.Forse qualcosa come a coda di messaggi potrebbe essere il backend tra il frontend e il crunch.

Andrew, (oltre a modellare come una pipeline, ecc.), misurare le cose è importante.Hai eseguito un profiler sul codice e hai ottenuto le metriche su dove viene spesa la maggior parte del tempo?

Per quanto riguarda il codice del database, quanto spesso cambia?Stai valutando la memorizzazione nella cache in questo momento?Presumo che tu abbia esaminato gli indici ecc. sui dati per accelerare il Db?

Che livelli di traffico hai sul front-end?Stai memorizzando nella cache le pagine web?(Non è troppo difficile dire di utilizzare un'API di tipo JMS per comunicare tra i componenti.È quindi possibile inserire il componente della pagina Web su una macchina (o più) e quindi inserire il codice di integrazione (c++) su un'altra e per molti prodotti JMS di solito ci sono API C++ native, ad es.Mi viene in mente ActiveMQ), ma aiuta davvero sapere quanto tempo è in Web (JSP?), C++, operazioni di database.

Il database memorizza dati aziendali o viene utilizzato anche per trasferire dati tra Java e C++?Dici che stai usando la memoria condivisa e non JNI?Quale livello di multi-threading esiste attualmente nell'APP?Descriveresti il ​​codice come di natura sincrona o asincrona?

Esiste una relazione fisica tra il codice Solaris e i dispositivi che devono essere sottoposti a manutenzione (ad es.fare in modo che tutti i dispositivi si registrino con il codice c++ oppure è possibile specificarlo).cioè.se dovessi mettere un bilanciatore del carico web sul frontend e mettere solo 2 macchine oggi, la relazione tra quali dispositivi sono gestiti da una scatola inizializzata in anticipo o in anticipo?

Quali sono i requisiti HA?cioè.indicare solo informazioni?È possibile eseguire l'HA solo a livello Web raggruppando i dati della sessione?

Il DB è in esecuzione su un'altra macchina?

Quanto è grande il DB?Hai ottimizzato le tue query, ad es.provare a utilizzare join interni/esterni espliciti a volte aiuta rispetto alle sottoquery nidificate (a volte).(guarda di nuovo le statistiche SQL).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top