Quali sono le mie opzioni per archiviare e interrogare enormi quantità di dati in cui molti si ripetono?

StackOverflow https://stackoverflow.com/questions/416432

Domanda

Sto valutando le opzioni per un'archiviazione efficiente dei dati in Java. Il set di dati è un valore di data e ora con una chiave primaria denominata. per es.

Name: A|B|C:D
Value: 124
TimeStamp: 01/06/2009 08:24:39,223

Potrebbe essere un prezzo delle azioni in un dato momento, quindi, suppongo, si tratta di un modello di dati di serie storiche classico. Tuttavia, ho davvero bisogno di una soluzione RDBMS generica che funzionerà con qualsiasi ragionevole database compatibile JDBC in quanto vorrei utilizzare Hibernate. Di conseguenza, le estensioni di serie temporali a database come Oracle non sono in realtà un'opzione in quanto vorrei che l'implementatore fosse in grado di utilizzare il proprio database compatibile con JDBC / Hibernate.

La sfida qui è semplicemente l'enorme volume di dati che possono accumularsi in un breve periodo di tempo. Finora, le mie implementazioni sono focalizzate sulla definizione di pianificazioni periodiche di rollup ed eliminazione in cui i dati grezzi sono aggregati nelle tabelle DAY, WEEK, MONTH ecc., Ma il rovescio della medaglia è la perdita precoce di granularità e il leggero inconveniente delle discrepanze del periodo tra periodi memorizzati in diversi aggregati.

La sfida ha opzioni limitate poiché esiste un limite assoluto alla quantità di dati che possono essere compressi fisicamente mantenendo la granularità originale dei dati, e questo limite è aggravato dalla direttiva sull'uso di un database relazionale e da un JDBC generico uno a quello.

Prendendo in prestito un concetto nozionale dai classici algoritmi di compressione dei dati e sfruttando il fatto che molti valori consecutivi per la stessa chiave denominata possono essere identici, mi chiedo se c'è modo di ridurre senza soluzione di continuità il numero di record memorizzati mediante la fusione la ripetizione di valori in una riga logica e la memorizzazione di un contatore che indica, efficacemente, i successivi n record hanno lo stesso valore " ;. L'implementazione di questo sembra abbastanza semplice, ma il compromesso è che il modello di dati è ora orribilmente complicato da interrogare contro l'utilizzo di SQL standard, specialmente quando si utilizza qualsiasi tipo di funzioni SQL aggregate. Ciò riduce significativamente l'utilità dell'archivio dati poiché solo un codice personalizzato complesso può ripristinare i dati in un "decompresso" stato risultante in una discrepanza di impedenza con centinaia di strumenti che non saranno in grado di rendere correttamente questi dati.

Ho considerato la possibilità di definire tipi di ibernazione personalizzati che sostanzialmente avrebbero "capito" il set di dati compressi, eseguirne il backup e restituire i risultati della query con le righe sintetiche create dinamicamente. (Il database verrà letto solo da tutti i client ad eccezione del flusso di input strettamente controllato). Molti degli strumenti che avevo in mente si integreranno con Hibernate / POJOS oltre a JDBC non elaborato (ad es. JasperReports) Ma questo non risolve davvero il problema delle funzioni aggregate e probabilmente ha anche un sacco di altri problemi.

Quindi sono parzialmente costretto a rassegnarmi a possibilmente dover utilizzare un archivio dati più proprietario [possibilmente non-SQL] (eventuali suggerimenti apprezzati) e quindi concentrarmi sul compito forse meno complesso di scrivere un pseudo driver JDBC almeno facilitare l'integrazione con strumenti esterni.

Ho sentito il riferimento a qualcosa chiamato " file compresso bit " come meccanismo per ottenere questa compressione dei dati, ma non conosco alcun database che fornisca questo e l'ultima cosa che voglio fare (o che posso fare, davvero ....) è scrivere il mio database.

Qualche suggerimento o approfondimento?

È stato utile?

Soluzione

Vorrei esaminare un database orientato alla colonna . Sarebbe fantastico per questo tipo di applicazione

Altri suggerimenti

Hibernate (o qualsiasi soluzione JPA) è lo strumento sbagliato per questo lavoro.

JPA / Hibernate non è una soluzione leggera. Nelle applicazioni ad alto volume, il sovraccarico non è solo significativo ma proibitivo. Devi davvero esaminare soluzioni di griglia e cluster . Non ripeterò qui la panoramica delle varie tecnologie.

Ho molta esperienza nei sistemi di informazione sui mercati finanziari. Alcune delle cose che hai detto mi sono rimaste impresse:

  • Hai molti dati non elaborati;
  • Desideri applicare varie aggregazioni a tali dati (ad esempio riepiloghi giornalieri aperti / alti / bassi / chiusi);
  • L'alta disponibilità è probabilmente un problema (lo è sempre in questi tipi di sistemi); e
  • La bassa latenza è probabilmente un problema (idem).

Ora per le soluzioni di tipo griglia / cluster le divido liberamente in due categorie:

  1. Soluzioni basate su mappe come Coherence o Terracotta; e
  2. Soluzioni basate su Javaspaces come GigaSpaces.

Ho usato molto Coherence e la soluzione Map può essere carina ma può anche essere problematica. Le mappe di coerenza possono avere ascoltatori su di esse e puoi usare questo tipo di cose per fare cose come:

  • Avvisi sui prezzi di mercato (gli utenti potrebbero desiderare una notifica quando un prezzo raggiunge un certo livello);
  • Prezzi derivati ??(ad es. un sistema di prezzi delle opzioni negoziati in borsa vorrà riclassificare i prezzi quando un titolo sottostante modifica l'ultimo prezzo scambiato);
  • Un sistema di abbinamento / prenotazione potrebbe voler abbinare le notifiche commerciali ricevute ai fini della riconciliazione;
  • ecc.

Tutto ciò può essere fatto con gli ascoltatori, ma in Coherence per esempio gli ascoltatori devono essere economici, il che porta a cose come una Mappa che ha un ascoltatore che a scrivere qualcosa su un'altra Mappa e questo può incatenarsi per un po '. Inoltre, modificare la voce della cache può essere problematico (anche se ci sono meccanismi per affrontare anche quel tipo di problema; sto parlando di situazioni come disattivare un avviso sui prezzi di mercato in modo che non si attivi una seconda volta).

Ho trovato le soluzioni di griglia di tipo GigaSpaces molto più interessanti per questo tipo di applicazione. L'operazione di lettura (o lettura distruttiva) è una soluzione altamente elegante e scalabile ed è possibile ottenere aggiornamenti transazionali della griglia con prestazioni inferiori al millisecondo.

Considera le due architetture di accodamento classiche:

  • Richiesta / Risposta: un messaggio errato può bloccare la coda e mentre è possibile molti mittenti e ricevitori (per la scalabilità) il ridimensionamento del numero di pipe non è sempre semplice; e
  • Pubblica / Iscriviti: questo disaccoppia il mittente e il destinatario ma manca di scalabilità in quanto se hai più abbonati riceveranno ciascuno il messaggio (non necessariamente quello che vuoi dire con un sistema di prenotazione).

In GigaSpaces, una lettura distruttiva è come un sistema scalabile di pubblicazione / sottoscrizione e un'operazione di lettura è come il tradizionale modello di pubblicazione / sottoscrizione. C'è un'implementazione di Map e JMS costruita sopra la griglia e può fare l'ordinamento FIFO.

Ora, per quanto riguarda la persistenza, ti sento chiedere? La persistenza è una conseguenza della decisione di tutte le altre cose. Per questo tipo di applicazione, mi piace Persistence as a Service modello (ironicamente scritto su Hibernate ma si applica a qualsiasi cosa).

Fondamentalmente questo significa che i risultati del tuo archivio di date sono asincroni e funziona bene con l'esecuzione dei dati di riepilogo. Come puoi avere un servizio in ascolto delle notifiche commerciali e persistere solo quelle a cui è interessato (aggregando in memoria se necessario). Puoi fare i prezzi di apertura / massimo / minimo / chiusura in questo modo.

Per i dati ad alto volume non si vuole davvero scrivere tutto nel database. Non in modo sincrono comunque. Un negozio persistente più un data warehouse è probabilmente più il percorso che vuoi percorrere, ma dipende ancora da requisiti, volumi, ecc.

È un argomento complicato e lo faccio solo davvero. Spero che ti aiuti.

Probabilmente troverai interessante ascoltare Presentazione di Michael Stonebraker su Money: Tech . Colpisce una serie di cose di cui hai bisogno e illustra come i tre grandi elefanti (SQL Server, Oracle e DB2) non saranno mai in grado di soddisfare le esigenze dei tick tick (che sembra che tu stia costruendo). Scava oltre i negozi di colonne, che sono d'accordo è la giusta direzione. Discute anche di compressione e velocità, che sono entrambi problemi per te.

ecco alcuni altri link che potresti trovare interessanti:

Molti sistemi di gestione di database compatibili con JDBC (ad es. Oracle) forniscono la compressione nel motore di archiviazione fisico. Oracle, ad esempio, ha la nozione di "compresso" tabella senza sovraccarico di decompressione:

http: //www.ardentperf .com / wp-content / uploads / 2007/07 / avanzato di compressione-DATASHEET.pdf

Grazie per le risposte.

Cletus, apprezzo il contorno, ma uno dei compromessi che non posso fare è l'abbandono della flessibilità del DB e la compatibilità con JDBC / Hibernate per consentire l'uso di tutti gli strumenti disponibili. Inoltre, sebbene non lo abbia affermato chiaramente, non voglio costringere i miei utenti ad adottare una soluzione commerciale [possibilmente costosa]. Se hanno Database Database X, usali. Se a loro non importa, consigliamo Database Y open source del marchio. Fondamentalmente l'applicazione ha più facce, una delle quali è un repository per i dati in arrivo, ma un'altra faccia è una fonte di segnalazione e io davvero don non voglio entrare nel business della scrittura di generatori di rapporti.

Anche se non l'ho ancora testato, sono molto colpito da LucidDB . È un database orientato alle colonne e offre buone prestazioni delle query e una compressione dei dati apparentemente buona. Ha un driver JDBC anche se non esiste ancora un dialetto Hibernate, per quanto ne so. Supporta anche trasformazioni definite dall'utente che, in breve, penso che mi permetteranno di implementare senza soluzione di continuità la mia idea di comprimere valori ripetitivi e consecutivi in ??una "riga", ma espellerli in più "sintetici" righe al momento della query, tutte eseguite in modo invisibile al chiamante della query. Infine, supporta questa elegante funzionalità di tabelle esterne in cui altre tabelle di database di supporto JDBC possono essere fronteggiate in LucidDB. Penso che questo possa essere prezioso per fornire un certo livello di supporto per altri database.

Grazie per il puntatore, Javaman. Mi ha suddiviso in zone su LucidDB.

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