Come gestire la rapida generazione di dati e la memorizzazione dei dati in modo efficiente

5

Sto lavorando a un progetto che genera enormi quantità di dati e li memorizza in un database SQL . Sto parlando di circa mille dischi al secondo. Quindi devo spingere quei dati in un database. Se faccio la generazione dei dati e il database spingo in sequenza, rallenterà la generazione dei dati che non è accettabile. Ho considerato di mantenere un buffer e due processi paralleli: uno scriverà i dati nel buffer e altri leggeranno i dati dal buffer e passeranno al database. Questa soluzione potrebbe funzionare ma il problema è dovuto alla latenza di scrittura nel database, il buffer diventa troppo grande e alla fine causa un'eccezione di limite di memoria. Anche scrivere su un file e quindi aggiornare il database dal file non sembra essere una soluzione molto buona. Dal punto di vista dell'ingegneria del software, quale altra soluzione posso prendere in considerazione.

Modifica per commenti:

  1. Scrivere in un file non sembra essere una buona soluzione dato che anche le dimensioni del file diventeranno troppo grandi. Sento che non è così che un gigante della tecnologia risolverà questo tipo di problemi.
  2. I dati vengono generati da alcuni calcoli. Il calcolo è critico nel tempo e prevediamo un calcolo al secondo. Quindi 1K di record al secondo.
posta user1120675 23.10.2016 - 07:38
fonte

4 risposte

4

Considera di non inserire nella tabella finale, ma in una tabella intermedia senza indici da mantenere o vincoli da validare. In questo modo le inserzioni sarebbero molto più veloci.

D'altra parte quella tabella sarebbe solo un buffer, devi ancora spostare quei record sul tavolo finale e troverai di nuovo il collo di bottiglia.

Mi sembra che dovrai utilizzare un buffer che viene scritto nel database quando viene raggiunta una determinata soglia. Quel buffer può essere memoria o un file. Ma alla fine il produttore dovrebbe rallentare. A meno che non si spenda bene in una configurazione ad alte prestazioni con un mucchio di RAM, dischi a stato solido, comunicazioni Fibre Channel e simili. Ciò ti farà guadagnare denaro.

    
risposta data 23.11.2016 - 11:02
fonte
3

A seconda di come la tecnologia ti piacerebbe andare. Sembra un caso per un ESB.

Apache Kafka sembra essere adatto a te. (LinkedIn, il creatore, vanta 2 milioni di scritture / sec su un'istanza.)

Se vuoi implementarlo tu stesso, dovresti probabilmente cercare nella cache di una memoria (memcache / redis?) e spingerlo alla rinfusa (magari uno script lua sull'interprete lua redis incorporato) come altri hanno sottolineato.

Per compensare il buffering aggiuntivo, dovrai negoziare con le prestazioni non elaborate. Ancora dovresti considerare i picchi, il carico massimo, ecc.

Volevo davvero commentare, ma i miei rappresentanti sono troppo bassi per questo.

Spero che ti aiuti in qualsiasi modo. :)

    
risposta data 24.10.2016 - 07:16
fonte
1

Utilizza un buffer non (solo) come metodo di controllo del flusso, ma come uno strumento per rendere più veloce l'operazione di archiviazione.

Lo storage, e in particolare i database, sono considerevolmente più efficienti quando gestiscono grandi quantità di dati contemporaneamente. Cioè, salvare migliaia di righe richiederà più tempo del salvataggio di 1 riga, ma non di un migliaio di volte più lungo - più come cento volte o 10 volte o anche meno (a seconda del DB, dei dati, dell'hardware ecc.). Ciò significa che il salvataggio di queste migliaia di righe come un mucchio sarà molto più rapido rispetto al salvataggio di uno alla volta.

Un buffer può aiutarti a farlo. Lasciate che il buffer cresca abbastanza - diciamo, a un migliaio di record - e quindi scrivete questi mille record contemporaneamente usando le funzionalità del database per inserire più righe contemporaneamente (con i database SQL di solito sta lavorando in una transazione e usando un'istruzione preparata). Dovresti anche attivare una spinta periodica al database anche quando non ci sono abbastanza record, in modo che il database rimanga sufficientemente aggiornato quando il flusso di dati sembra essere basso.

Se questo non è abbastanza veloce, un buffer può anche aiutare a parallelizzare l'operazione di inserimento del database. Se la velocità è così critica e raggiungi un limite che è inaccettabilmente lento, potresti voler investire denaro nell'hardware. Ottenere hardware più veloce non è sempre possibile, ma puoi sempre acquistare più macchine e mettere più core e interfacce di rete sulle tue macchine.

Ciò significa che se si desidera investire nell'hardware per rendere più veloce la spinta verso il database, è possibile eseguire più processi, distribuiti su più core e interfacce di rete, che leggono dal buffer e scrivono nel database in parallelo. L'overhead di sincronizzazione dovrebbe essere trascurabile se stai scrivendo (e leggendo dal buffer) in grossi volumi.

Se scrivere su un server di messaggi in coda sulla rete intranet è molto più veloce della scrittura sul database - in particolare, abbastanza veloce per le proprie esigenze - è possibile avere più server che leggono dallo stesso server di messaggi e scrivono nel database.

Se il database stesso è troppo lento, è possibile verificare se supporta il ridimensionamento su più server. Quindi ogni processo che legge dal buffer può scrivere su un server di database diverso, fungendo da bilanciamento del carico.

    
risposta data 23.11.2016 - 14:47
fonte
-1

Utilizza un pattern consumer del produttore in modo che non venga elaborato in modo sequenziale. Se la coda diventa troppo lunga, devi rallentare il produttore.

Lavorare sulla velocità dell'inserto. Per le file di piccole dimensioni è possibile ottenere fino a 1000 / secondo.

    
risposta data 24.10.2016 - 09:47
fonte

Leggi altre domande sui tag