Scansione di un miliardo di righe in un database ultraveloce

9

Sfondo

Un database locale contiene circa 1,3 miliardi di righe univoche. Ogni riga è indirettamente associata a una specifica latitudine e longitudine (posizione). Ogni riga ha un timbro data.

Usa caso

Il problema è il seguente:

  1. L'utente imposta una data di inizio / fine e un intervallo di valori (ad es. da 100 a 105).
  2. Il sistema raccoglie tutte le righe che corrispondono alla data specificata, raggruppate per posizione.
  3. Il sistema esegue determina le posizioni che, durante tali date, hanno una probabilità statistica di rientrare nell'intervallo di valori specificato.
  4. Il sistema visualizza tutte le posizioni corrispondenti all'utente.

Questo è un problema di velocità e scala.

Domanda

Qual è l'architettura di soluzione meno costosa che si possa immaginare per consentire a un sistema di questo tipo di recuperare i risultati per gli utenti in meno di cinque secondi?

Sistema corrente

L'ambiente è attualmente:

  • PostgreSQL 8.4 (l'aggiornamento è possibile, il cambio di database non è un'opzione)
  • R e PL / R
  • XFS
  • WD VelociRaptor
  • 8 GB di RAM (Corsair G.Skill; 1,3 GHz)
  • Quad core GenuineIntel 7 (2,8 GHz)
  • Ubuntu 10.10

Gli aggiornamenti hardware sono accettabili.

Aggiornamento - Struttura del database

I miliardi di righe si trovano in una tabella simile a:

id | taken | location_id | category | value1 | value2 | value3
  • id - Chiave primaria
  • preso - Data assegnata alla riga
  • location_id - Riferimento alla latitudine / longitudine
  • categoria - Una descrizione dei dati
  • value1 .. 3 - Gli altri valori che l'utente può interrogare

La colonna taken è in genere date consecutive per location_id , a volte ogni posizione contiene dati dal 1800 al 2010 (circa 77.000 date, molte delle quali duplicate in quanto ogni posizione contiene dati nello stesso intervallo di date).

Esistono sette categorie e le tabelle sono già divise per categoria (utilizzando tabelle secondarie). Ogni categoria contiene ~ 190 milioni di righe. Nel prossimo futuro, il numero di righe per categoria supererà il miliardo.

Ci sono circa 20.000 località e 70.000 città. Le posizioni sono correlate alla città per latitudine e longitudine. Assegnare ogni posizione a una città specifica significa trovare i confini della città, che non è un compito banale.

Idee

Alcune idee che ho incluso:

  • Trova un servizio cloud per ospitare il database.
  • Crea una striscia raid SSD (ottimo video).
  • Crea una tabella che amalgami tutte le località per città (pre-calcolo).

Grazie!

    
posta Dave Jarvis 25.05.2011 - 04:43
fonte

8 risposte

12

La cosa più importante è sapere con certezza dove si trova il collo di bottiglia per un determinato numero di richieste rappresentative, poiché non è possibile cambiare database.

Se esegui scansioni complete della tabella, hai bisogno di indici appropriati.

Se aspetti I / O hai bisogno di più memoria per il caching (Jeff Atwood ha recentemente affermato che i sistemi a 24 Gb erano raggiungibili sui sistemi desktop).

Se aspetti sulla CPU, devi verificare se i tuoi calcoli possono essere ottimizzati.

Ciò richiede un cappello DBA a punta e un cappello del sistema operativo, ma vale la pena di assicurarti di abbaiare nell'albero giusto.

    
risposta data 25.05.2011 - 08:07
fonte
4

Che ne dici di partizionare la tabella in più pezzi situati su diversi host in base al timbro data? Questo è scalabile orizzontalmente e, se hai un numero sufficiente di caselle, puoi scrivere un piccolo motore di aggregazione in cima a queste impostazioni.

Se vedi che il timbro della data sta cambiando troppo, puoi partizionare in base alle posizioni, di nuovo scalabile orizzontalmente. (Si spera che non aggiungano molte altre latitudini / longitudini!)

    
risposta data 25.05.2011 - 04:51
fonte
4

Lo scenario peggiore è che l'intervallo di date copre tutte le date nel tuo database.

Stai cercando di leggere 1,3 miliardi di record e di fare una sorta di analisi su ogni record rispetto ai valori inseriti, su una macchina fisica, in meno di 5 secondi. Il risultato può essere in tutte le località o nessuno - non si sa nulla in anticipo.

Dati questi parametri direi probabilmente impossibile.

Guarda il tuo disco fisso: la velocità massima sostenuta è inferiore a 150 MB / s. La lettura di 1,3 miliardi di record richiederà più di 5 secondi. Dal punto di vista della CPU, non sarai in grado di eseguire alcun tipo di analisi statistica su 1,3 miliardi di record in 5 secondi.

La tua unica speranza (tm :-)) è trovare una sorta di funzione di ricerca in base ai valori immessi dall'utente che restringeranno la ricerca verso il basso (di pochi ordini di grandezza). È possibile calcolare questa funzione di ricerca offline. Senza saperne di più sui criteri di corrispondenza esatti, non penso che nessuno possa dirti come farlo, ma un esempio potrebbe essere quello di suddividere l'intervallo di valori in un intervallo discreto e creare una ricerca che fornisca tutti i record in quell'intervallo. Finché l'intervallo è abbastanza piccolo, puoi fare un vero lavoro al suo interno, ad es. eliminazione di voci che non corrispondono al valore inserito dall'utente. Fondamentalmente scambia spazio per tempo.

Potrebbe essere possibile conservare tutti i record (o almeno la parte importante) in memoria. Probabilmente non in 8 GB. Ciò eliminerà almeno la porzione di I / O del disco anche se anche la larghezza di banda della memoria potrebbe essere insufficiente per eseguire la scansione di tutto in 5 secondi. In ogni caso, questa è un'altra tecnica per accelerare questo tipo di applicazioni (combinarle con il mio precedente suggerimento).

Hai menzionato l'utilizzo di un servizio cloud. Sì, se paghi abbastanza CPU e I / O muscoli e dividi il tuo database su molti server puoi forzarlo / dividerlo e conquistarlo.

    
risposta data 25.05.2011 - 08:28
fonte
2

Ho in secondo luogo il commento di rwong alla domanda: PostgreSQL offre tipi di indici e strumenti appropriati (indici GIST, indici GIN, Postgis, tipi geometrici) in modo tale che i dati relativi a datetime e datetime debbano essere ricercabili secondo questi criteri senza molti problemi .

Se le tue query su questi criteri richiedono pochi secondi, probabilmente significa che non vengono utilizzati tali indici. Puoi confermare di aver esaminato questi dati come appropriato?

    
risposta data 25.05.2011 - 08:50
fonte
1

Dato che usi PostgreSQL e dati di latitudine / longitudine, dovresti assolutamente usare PostGIS, in questo modo puoi aggiungere un indice spaziale GiST al tuo database per velocizzare le cose.

Ho una tabella simile (con 350k righe) con una configurazione molto più piccola della tua (2 core e appena 2 GB di RAM), ma le ricerche richiedono meno di un secondo.

    
risposta data 25.05.2011 - 10:33
fonte
0

Forse potresti rompere un modello relazionale come ha fatto Essbase con la loro architettura OLAP: Essbase Wikipedia

Quello che intendo è creare una tabella per città, finendo così con 1000+ tabelle. Non un tavolo come te suggerito, ma molti. Indicizza ogni tabella per data e luogo. Molte tabelle, molti indici - > più veloce.

    
risposta data 25.05.2011 - 06:37
fonte
0

Per quanto riguarda la tua idea di trovare un servizio cloud per ospitare il database, hai già trovato SimpleGeo ? Hanno appena tagliato la barra multifunzione su un servizio di archiviazione apparentemente "ottimizzato specificamente per archiviare e interrogare i dati sulla posizione in modo veramente rapido", anche se il costo per archiviare e interrogare più di un miliardo di righe potrebbe rendere questo approccio irrealizzabile.

    
risposta data 25.05.2011 - 18:11
fonte
-2

ti aspetti una bicicletta per correre in autostrada. attualmente stai cercando una soluzione per affrontare solo questo problema, non prevedi il problema e se avessi 2 miliardi di record? la scalabilità deve essere affrontata. la risposta è un database di oggetti di uso semplice. ad esempio cache di Intersystems

e credimi, non sono di intersistemi; -)

    
risposta data 25.05.2011 - 10:13
fonte

Leggi altre domande sui tag