Come gestire le query di oltre 500 milioni di elementi


8

La struttura dei miei dati è la seguente:

date: <timestamp>
filter_a: <integer> -> range [0, 1000]
filter_b: <integer> -> range [0, 1000]
filter_c: <integer> -> range [0, 86400]
filter_d: <integer> -> range [0, 6]
group: <string>
second_group: <integer>
variable_a: <float>
variable_b: <float>
variable_c: <float>
a couple more no very important

Devo eseguire le seguenti query:

Primo:

  • Filtrare i dati di date, filter_a, filter_b, filter_ce altri

In secondo luogo, con i dati filtrati:

  • contare tutti i record
  • ottenere media di variable_a, variable_bevariable_c
  • ottenere la deviazione standard di variable_a, variable_bevariable_c
  • ottenere quartili di variable_a, variable_bevariable_c
  • raggruppare i dati per groupo second_groupe aggregare (Count, Avg, Std, ..)

Il numero di utenti del sistema è di circa 10 o 15, ma il numero di articoli è enorme, al momento è di 70 M ma sarà di 500 M in un paio di settimane e sarà di 1000 M in circa un anno.

Il numero di query è piccolo, non più di 10 utenti contemporaneamente, il mio problema è come gestire quelle query con questa enorme quantità di dati.

Cosa ho provato finora?

  • Ho iniziato con mongodb, all'inizio è stato veloce ma è diventato lento nel calcolo dei quartili con 10M +. È migliorato quando ho aggiunto gli indici, ma non ha aiutato molto quando ho dovuto interrogare tutti i dati. Ho iniziato a usare mongodb perché i dati erano molto dinamici, ma per fortuna il formato dei dati "non cambierà più".

  • Come filter_ae filter_bpotrebbe essere visto come un nodo, ho provato neo4j. Neo4j mi è piaciuto molto, ma il mio grafico aveva MOLTI bordi, quindi le query non erano molto veloci.

  • Infine, poiché il formato dei dati non cambierà ed è solo una raccolta / tabella, quindi non ha bisogno di unirsi in SQL, ho controllato postgresql. I miei test sono stati più veloci con postgresql, ma ho paura che non possa ridimensionarsi correttamente in futuro.

Di cosa ho bisogno?

  • Postgresql è una buona scelta per questo caso?
  • Esiste un altro tipo di database che potrei usare? qual è il migliore per questo caso?
  • Cos'altro potrei fare per migliorarlo?

modificare

  • Circa 1 milione di elementi vengono inseriti ogni giorno e "non devono cambiare" nel tempo.
  • La velocità di scrittura non è importante
  • Il difficile requisito è leggere / aggregare velocemente

Grazie!


1
Che ne dite di viste indicizzate in SQL Server / viste metastatizzate in Oracle? Questi sono un aggregato in esecuzione della tabella di base in modo che la tabella di base venga modificata anche l'indice viene modificato al volo. Quindi puoi sempre interrogare aggregati che sono già calcolati per te.
Ali Razeghi,

Le visualizzazioni indicizzate di @AliRazeghi sono una buona idea. Comunque prima voglio scegliere il miglior database / design prima di ottimizzare le query stesse
Andres

1
Per l'ottimizzazione puramente in Postgres, voglio dire che gli indici BRIN potrebbero aiutare qui, ma non ho fatto nulla a parte leggere su di loro. postgresql.org/docs/9.5/static/brin-intro.html
Erik Darling

1
Personalmente ho ereditato un DB di report multi-miliardario su un server OLTP senza molta memoria. Fortunatamente le porzioni più interrogate sono state le "ultime 3 settimane", ma le scansioni del tavolo non erano inaudite. Onestamente, utilizzando compressione, partizionamento, eliminazione delle partizioni, schema di partizionamento, ottimizzazioni della cache SAN e rimozione degli indici inutilizzati molto buoni, abbiamo ottenuto ottime prestazioni su MS SQL 2008 Ent. 1 miliardo non sarà troppo difficile per PGSQL. Quanto è grande ogni riga o approssimativamente quanto spazio occuperà ciascuna riga e quanti indici ci saranno per tabella o processo di input?
Ali Razeghi,

2
@Andres bene dipende da quale motore db è e quale sia la dimensione massima di ogni riga in modo che possiamo calcolare. Ad esempio PostgreSQL ha varchar e solo char, char è facile da calcolare, varchar dovremmo indovinare la lunghezza media. Se potessimo sapere che tipo di campo è (a meno che non sia Mongo o qualcosa che lo memorizza in un documento con il suo formato), approssimativamente quanti caratteri ci aspettiamo in ciascuno e # di indici con le colonne. La RAM da 8 GB suona come se fosse troppo bassa per estrarla in modo efficiente dalla memoria anche se quella RAM è condivisa con altre tabelle e risorse sul server.
Ali Razeghi,

Risposte:


5

Invece di fare affidamento su un database relazionale per eseguire questi calcoli statistici sui dati di serie temporali, suggerirei di spostare questo lavoro di matematica e post-elaborazione al di fuori del database in un'applicazione client.

Utilizzando un linguaggio di scripting come Python o Ruby, è possibile risolvere in modo incrementale il problema eseguendo una query per "blocchi" di dati in un periodo di tempo a larghezza fissa, calcolare un riepilogo statistico intermedio e quindi combinare i risultati su più blocchi, mentre si esegue il ciclo su tutta la storia. Alcune misure statistiche sono difficili da combinare tra blocchi, ma qualcosa come Avg () richiede solo sum () e count () per blocco, O (1) vs. O (blocco), quindi la fusione dei blocchi può ridimensionare bene.


Ho provato qualcosa del genere usando python / panda . il calcolo era più veloce (un paio di secondi) ma il recupero di tutti i dati era lento. Forse un migliore chunksizepotrebbe aiutare. +1
Andres,

1

Dal momento che i tuoi dati non cambiano, ed è solo aggiunto, li conserverei ovunque tu voglia; Amazon S3 per esempio, ma qualsiasi database a lettura veloce sarà ok. Nessun indice Il database / FS scelto dovrebbe avere l'opzione per leggere i dati in bucket: ad esempio, potresti avere un file al giorno con i tuoi record 1M.

Quindi userei Spark per fare il filtro / analisi. È basato su cluster, puoi adattarlo alle tue esigenze.


Sono d'accordo, ho già il mio set di dati separato al giorno. Stavo anche pensando a HDFS e HBase
Andres il

0

La risposta dipende dal modo in cui utilizzerai i dati dopo questo. Se per elaborare meglio usare Cassandra, se per analisi meglio usare Hive.


Ho capito che l'alveare non poteva essere la scelta migliore per real time. Ho sbagliato?
Andres,

1
Sì, HBase è per la lettura / scrittura in tempo reale. Ma anche Cassandra può fare lo stesso. Ma penso che HBase sia migliore.
Artemy Prototyping,

0

Questo tipo di situazione è ideale per l'archiviazione dei dati, utilizzando le tecniche perfezionate da Ralph Kimball e simili, su piattaforme come SQL Server (quella con cui ho più familiarità). Sono stati progettati specificatamente pensando a questo tipo di scenario: enormi quantità di record di dati relativamente statici, per i quali è necessario calcolare aggregati di questo tipo. Nola tecnica relazionale corrisponderà a un data warehousing correttamente implementato in applicazioni di questo tipo, anche se alcuni saranno sicuramente migliori di altri se la tua organizzazione semplicemente non può permettersi le licenze per i pacchetti software (come SQL Server Analysis Services) che li implementano. Esiste anche una curva di apprendimento per l'implementazione di linguaggi come MDX che sono fatti su misura per questo tipo di accesso ai dati. Se il data warehousing è un'opzione praticabile per la tua organizzazione, non perdere tempo a cercare una soluzione relazionale; questo non è un problema di database relazionale. Posso pubblicare alcuni riferimenti di base a Kimball ecc. E collegamenti a SSAS e MDX (scusate se non posso fare a meno di Oracle e altri concorrenti con cui non ho familiarità) la documentazione, se necessario. Spero che aiuti.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.