Il miglior archivio dati per miliardi di righe


87

Devo essere in grado di memorizzare piccoli bit di dati (circa 50-75 byte) per miliardi di record (~ 3 miliardi / mese per un anno).

L'unico requisito sono gli inserimenti veloci e le ricerche veloci per tutti i record con lo stesso GUID e la possibilità di accedere all'archivio dati da .net.

Sono un tipo di server SQL e penso che SQL Server possa farlo, ma con tutti i discorsi su BigTable, CouchDB e altre soluzioni nosql, suona sempre più come un'alternativa a un RDBS tradizionale potrebbe essere la migliore a causa delle ottimizzazioni per query distribuite e ridimensionamento. Ho provato cassandra e le librerie .net attualmente non si compilano o sono tutte soggette a modifiche (insieme a cassandra stessa).

Ho esaminato molti archivi dati nosql disponibili, ma non riesco a trovarne uno che soddisfi le mie esigenze come piattaforma robusta pronta per la produzione.

Se dovessi archiviare 36 miliardi di record piccoli e piatti in modo che siano accessibili da .net, cosa sceglierebbe e perché?


Sì, i miei numeri sono corretti. Attualmente abbiamo così tanti dati in arrivo nel sistema, ma li aggreghiamo e memorizziamo solo i conteggi aggregati in modo da perdere i dati per record e mantenere solo le somme orarie di dati. A causa dei requisiti aziendali, desideriamo mantenere ogni record come si è verificato originariamente, ovvero 3Bil righe / mese.
Jody Powlette

Hai sollevato alcune buone domande. Le risposte sono: il tempo di attività del 95% è sufficiente - i dati sono già ritardati di una quantità variabile, quindi dovrò sincronizzarli comunque dopo il fatto, quindi rimanere inattivo per un breve periodo non è un problema. La perdita di inserti o anche migliaia di inserti non è la fine del mondo. Tuttavia, perdere un giorno di dati sarebbe piuttosto brutto. Anche la coerenza non è così importante. Fondamentalmente dopo aver inserito 30Mil righe in un giorno, devo recuperare tutte le righe con lo stesso GUID (forse 20 righe) ed essere ragionevolmente sicuro di recuperarle tutte.
Jody Powlette

Esegui il dump di 30 milioni di righe al giorno in lavori batch pianificati ogni giorno / ogni ora o vengono forniti in un flusso costante uno alla volta?
Remus Rusanu

I dati arrivano da un sito FTP ... i file arrivano continuamente e ho un processo che analizza i file e attualmente genera i dati aggregati e inserisce i valori aggregati (forse 1000 righe) come transazione. Il nuovo processo dovrà inserire centinaia di migliaia di righe da ogni file che arriva, probabilmente l'uso dell'inserimento in blocco sarebbe il modo più efficiente per farlo.
Jody Powlette

Sembra un lavoro ETL per SSIS e SQL Server. Detengono un record mondiale per ETL, con una velocità di caricamento di oltre 2 TB / ora: blogs.msdn.com/sqlperf/archive/2008/02/27/etl-world-record.aspx
Remus Rusanu

Risposte:


103

Memorizzare ~ 3,5 TB di dati e inserire circa 1 K / sec 24x7 e anche eseguire query a una velocità non specificata, è possibile con SQL Server, ma ci sono altre domande:

  • che requisito di disponibilità hai per questo? Tempo di attività del 99,999% o è sufficiente il 95%?
  • quale requisito di affidabilità hai? La mancanza di un inserto ti costa $ 1 milione?
  • quale requisito di recuperabilità hai? Se perdi un giorno di dati, è importante?
  • che requisito di coerenza hai? È necessario garantire che una scrittura sia visibile alla lettura successiva?

Se hai bisogno di tutti questi requisiti che ho evidenziato, il carico che proponi costerà milioni in hardware e licenze su un sistema relazionale, qualsiasi sistema, indipendentemente dagli espedienti che provi (partizionamento, partizionamento, ecc.). Un sistema nosql, per definizione, non soddisfa tutti questi requisiti.

Quindi ovviamente hai già rilassato alcuni di questi requisiti. C'è una bella guida visiva che confronta le offerte nosql in base al paradigma 'scegli 2 su 3' in Guida visiva ai sistemi NoSQL :

nosql comparisson

Dopo l'aggiornamento del commento OP

Con SQL Server questo sarebbe un'implementazione semplice:

  • una singola chiave in cluster di tabella (GUID, ora). Sì, sta per arrivare frammentato diventerà , ma la frammentazione influisce sui read-ahead e i read-ahead sono necessari solo per scansioni a distanza significativa. Poiché richiedi solo GUID e intervalli di date specifici, la frammentazione non avrà molta importanza. Sì, è una chiave ampia, quindi le pagine non foglia avranno una scarsa densità di chiavi. Sì, porterà a un fattore di riempimento scadente. E sì, possono verificarsi divisioni di pagina. Nonostante questi problemi, visti i requisiti, resta la migliore scelta di chiavi cluster.
  • partizionare la tabella in base al tempo in modo da poter implementare l'eliminazione efficiente dei record scaduti, tramite una finestra scorrevole automatica . Aumentalo con una ricostruzione della partizione dell'indice in linea dell'ultimo mese per eliminare il fattore di riempimento scadente e la frammentazione introdotti dal clustering GUID.
  • abilitare la compressione della pagina. Poiché la chiave clusterizzata viene prima raggruppata in base al GUID, tutti i record di un GUID saranno uno accanto all'altro, fornendo la compressione della pagina una buona possibilità per distribuire la compressione del dizionario.
  • avrai bisogno di un percorso IO veloce per il file di registro. Sei interessato a un throughput elevato, non a una bassa latenza per un log per tenere il passo con 1K inserimenti / sec, quindi lo stripping è un must.

Il partizionamento e la compressione delle pagine richiedono ciascuno un SQL Server Enterprise Edition, non funzioneranno su Standard Edition ed entrambi sono molto importanti per soddisfare i requisiti.

Come nota a margine, se i record provengono da una farm di server Web front-end, metterei Express su ciascun server Web e invece di INSERT sul back-end, lo farei SEND le informazioni nel back-end, utilizzando una connessione / transazione locale sull'Express che si trova insieme al server web. Ciò fornisce una storia di disponibilità molto migliore per la soluzione.

Quindi è così che lo farei in SQL Server. La buona notizia è che i problemi che dovrai affrontare sono ben compresi e le soluzioni sono note. questo non significa necessariamente che sia migliore di quello che potresti ottenere con Cassandra, BigTable o Dynamo. Lascerò che qualcuno più esperto in cose no-sql-ish per discutere il loro caso.

Nota che non ho mai menzionato il modello di programmazione, il supporto .Net e simili. Onestamente penso che siano irrilevanti nelle grandi distribuzioni. Fanno un'enorme differenza nel processo di sviluppo, ma una volta distribuito non importa quanto sia veloce lo sviluppo, se l'overhead ORM uccide le prestazioni :)


Ho collegato il sito di Nathan, ma questa non è la prima pagina di Slashdot;)
Remus Rusanu

@RemusRusanu: guardando la migrazione dba.se. Solo per prepararti :-) E +1
gbn

A partire da Microsoft SQL Server 2016, l'edizione Enterprise non è più richiesta per il partizionamento delle tabelle poiché il partizionamento delle tabelle è ora disponibile in quasi tutte le edizioni di SQL Server 2016.
TChadwick

17

Contrariamente alla credenza popolare, NoSQL non riguarda le prestazioni e nemmeno la scalabilità. Si tratta principalmente di ridurre al minimo il cosiddetto disadattamento di impedenza relazionale oggetto, ma riguarda anche la scalabilità orizzontale rispetto alla scalabilità verticale più tipica di un RDBMS.

Per il semplice requisito di inserimenti veloci e ricerche veloci, quasi tutti i prodotti di database andranno bene. Se si desidera aggiungere dati relazionali o join o se si desidera applicare una logica o vincoli transazionali complessi, è necessario un database relazionale. Nessun prodotto NoSQL può essere paragonato.

Se hai bisogno di dati senza schema, ti consigliamo di utilizzare un database orientato ai documenti come MongoDB o CouchDB. Lo schema sciolto è l'attrazione principale di questi; Personalmente mi piace MongoDB e lo uso in alcuni sistemi di report personalizzati. Lo trovo molto utile quando i requisiti dei dati cambiano costantemente.

L'altra opzione NoSQL principale è rappresentata dagli archivi valore-chiave distribuiti come BigTable o Cassandra. Questi sono particolarmente utili se si desidera ridimensionare il database su molte macchine che eseguono hardware comune. Funzionano bene anche sui server, ovviamente, ma non sfruttano l'hardware di fascia alta così come SQL Server o Oracle o altri database progettati per il verticale ridimensionamento e, ovviamente, non sono relazionali e non sono adatti per applicare la normalizzazione o vincoli. Inoltre, come hai notato, il supporto .NET tende a essere alquanto irregolare.

Tutti i prodotti di database relazionali supportano il partizionamento di un tipo limitato. Non sono flessibili come BigTable o altri sistemi DKVS, non si partizionano facilmente su centinaia di server, ma non sembra proprio quello che stai cercando. Sono abbastanza bravi a gestire i conteggi dei record nell'ordine dei miliardi, purché indicizzi e normalizzi i dati correttamente, esegui il database su hardware potente (specialmente SSD se te lo puoi permettere) e partiziona su 2 o 3 o 5 dischi fisici se necessario.

Se soddisfi i criteri di cui sopra, se lavori in un ambiente aziendale e hai soldi da spendere per l'ottimizzazione di hardware e database decente, per ora rimango con SQL Server. Se stai pizzicando pochi centesimi e hai bisogno di eseguirlo su hardware di cloud computing Amazon EC2 di fascia bassa, probabilmente preferiresti optare per Cassandra o Voldemort (supponendo che tu possa far funzionare entrambi con .NET).


11

Pochissime persone lavorano con la dimensione del set di righe multimiliardario e la maggior parte delle volte che vedo una richiesta come questa in overflow dello stack, i dati non sono vicini alla dimensione come vengono segnalati.

36 miliardi, 3 miliardi al mese, ovvero circa 100 milioni al giorno, 4,16 milioni all'ora, ~ 70.000 righe al minuto, 1,1.000 righe al secondo che entrano nel sistema, in modo sostenuto per 12 mesi, senza tempi di inattività.

Queste cifre non sono impossibili con un lungo margine, ho realizzato sistemi più grandi, ma vuoi ricontrollare che siano davvero le quantità che intendi - pochissime app hanno davvero questa quantità.

In termini di archiviazione / recupero e un aspetto piuttosto critico che non hai menzionato è l'invecchiamento dei dati più vecchi: la cancellazione non è gratuita.

La normale tecnologia che si osserva è il partizionamento, tuttavia, la ricerca / recupero basata su GUID comporterebbe prestazioni scadenti, supponendo che sia necessario ottenere ogni valore corrispondente per l'intero periodo di 12 mesi. È possibile posizionare un indice cluster nella colonna GUID per ottenere il cluster di dati associato per lettura / scrittura, ma a quelle quantità e velocità di inserimento, la frammentazione sarà troppo alta per essere supportata e cadrà sul pavimento.

Suggerirei anche che avrai bisogno di un budget hardware molto decente se questa è un'applicazione seria con velocità di risposta di tipo OLTP, ovvero con alcune ipotesi approssimative, assumendo pochissimi overhead di indicizzazione, circa 2,7 TB di dati.

Nel campo di SQL Server, l'unica cosa che potresti voler guardare è la nuova edizione di parrallel data warehouse (madison) che è progettata più per il partizionamento dei dati e l'esecuzione di query parallele su di esso per fornire alta velocità contro datamart di grandi dimensioni.


3
Nella bioinformatica i set di dati su miliardi di righe non sono rari. Ma sono spesso trattati in modo puramente streaming da file flat.
Erik Garrison

3
@Erik: per l'elaborazione del flusso (ad esempio, è sufficiente rilevare determinate condizioni, ma non è necessario archiviare i dati per eseguire query successive) qualcosa come StreamInsight è migliore di qualsiasi database microsoft.com/sqlserver/2008/en/us/r2 -complex-event.aspx
Remus Rusanu

2

"Devo essere in grado di memorizzare piccoli bit di dati (circa 50-75 byte) per miliardi di record (~ 3 miliardi / mese per un anno).

L'unico requisito sono inserimenti veloci e ricerche veloci per tutti i record con lo stesso GUID e la possibilità di accedere all'archivio dati da .net.

Posso dirti per esperienza che questo è possibile in SQL Server, perché l'ho fatto all'inizio del 2009 ... ed è ancora operativo fino ad oggi e abbastanza veloce.

La tabella è stata partizionata in 256 partizioni, tieni presente che questa era la versione SQL del 2005 ... e abbiamo fatto esattamente quello che stai dicendo, ovvero memorizzare bit di informazioni tramite GUID e recuperarli rapidamente tramite GUID.

Quando me ne sono andato avevamo circa 2-3 miliardi di record e il recupero dei dati era ancora abbastanza buono (1-2 secondi se si passa attraverso l'interfaccia utente, o meno se su RDBMS) anche se la politica di conservazione dei dati stava per essere istanziata.

Quindi, per farla breve, ho preso l'ottavo carattere (cioè da qualche parte nel mezzo) dalla stringa GUID e SHA1 l'ha hashing e lanciato come tiny int (0-255) e memorizzato nella partizione appropriata e ho usato la stessa chiamata di funzione quando ottenevo i dati indietro.

ping me se hai bisogno di maggiori informazioni ...


2

Il seguente articolo illustra l'importazione e l'utilizzo di una tabella di 16 miliardi di righe in Microsoft SQL. http://sqlmag.com/t-sql/adventures-big-data-how-import-16-billion-rows-single-table .

Dall'articolo:

Ecco alcuni suggerimenti distillati dalla mia esperienza:

  • Più dati hai in una tabella con un indice cluster definito, più lento diventa importare in essa record non ordinati. Ad un certo punto diventa troppo lento per essere pratico.
  • Se vuoi esportare la tua tabella nel file più piccolo possibile, rendilo in formato nativo. Funziona meglio con le tabelle che contengono principalmente colonne numeriche perché sono rappresentate in modo più compatto nei campi binari rispetto ai dati dei caratteri. Se tutti i tuoi dati sono alfanumerici, non guadagnerai molto esportandoli in formato nativo. Non consentire valori nulli nei campi numerici può compattare ulteriormente i dati. Se consenti a un campo di essere annullabile, la rappresentazione binaria del campo conterrà un prefisso di 1 byte che indica quanti byte di dati seguiranno.
  • Non è possibile utilizzare BCP per più di 2.147.483.647 record perché la variabile contatore BCP è un numero intero a 4 byte. Non sono riuscito a trovare alcun riferimento a questo su MSDN o Internet. Se la tua tabella è composta da
    più di 2.147.483.647 record, dovrai esportarla in blocchi
    o scrivere la tua routine di esportazione.
  • La definizione di un indice cluster in una tabella prepopolata richiede molto spazio su disco. Nel mio test, il mio registro è esploso fino a 10 volte la
    dimensione della tabella originale prima del completamento.
  • Quando si importa un numero elevato di record utilizzando l'istruzione BULK INSERT, includere il parametro BATCHSIZE e specificare quanti
    record eseguire il commit alla volta. Se non includi questo parametro,
    l'intero file viene importato come una singola transazione, che
    richiede molto spazio di registro.
  • Il modo più veloce per inserire i dati in una tabella con un indice cluster consiste nel preordinarli prima. È quindi possibile importarlo utilizzando l'
    istruzione BULK INSERT con il parametro ORDER.

1

C'è un fatto insolito che sembra trascurato.

" Fondamentalmente, dopo aver inserito 30Mil righe in un giorno, devo recuperare tutte le righe con lo stesso GUID (forse 20 righe) ed essere ragionevolmente sicuro di recuperarle tutte "

Avendo bisogno di solo 20 colonne, un indice non cluster sul GUID funzionerà perfettamente. È possibile raggruppare su un'altra colonna per la dispersione dei dati tra le partizioni.

Ho una domanda sull'inserimento dei dati: come vengono inseriti?

  • È un inserimento in blocco su una determinata pianificazione (al minuto, all'ora, ecc.)?
  • Da quale fonte vengono estratti questi dati (file flat, OLTP, ecc.)?

Penso che queste debbano essere risolte per aiutare a capire un lato dell'equazione.


1

Amazon Redshift è un ottimo servizio. Non era disponibile quando la domanda è stata originariamente pubblicata nel 2010, ma ora è uno dei principali attori nel 2017. È un database basato su colonne, biforcato da Postgres, quindi le librerie di connettori SQL e Postgres standard funzioneranno con esso.

È utilizzato al meglio per scopi di reportistica, in particolare di aggregazione. I dati di una singola tabella sono archiviati su diversi server nel cloud di Amazon, distribuiti da distkeys di tabella definiti, quindi fai affidamento sulla potenza della CPU distribuita.

Quindi le SELECT e soprattutto le SELECT aggregate sono velocissime. Il caricamento di dati di grandi dimensioni dovrebbe essere preferibilmente eseguito con il comando COPY dai file csv di Amazon S3. Gli svantaggi sono che DELETE e UPDATE sono più lenti del solito, ma è per questo che Redshift non è principalmente un database transnazionale, ma più una piattaforma di data warehouse.


0

Puoi provare a utilizzare Cassandra o HBase, anche se dovresti leggere come progettare le famiglie di colonne secondo il tuo caso d'uso. Cassandra fornisce il proprio linguaggio di query ma è necessario utilizzare le API Java di HBase per accedere direttamente ai dati. Se hai bisogno di usare Hbase, ti consiglio di interrogare i dati con Apache Drill da Map-R, che è un progetto Open Source. Il linguaggio di query di Drill è conforme a SQL (le parole chiave in drill hanno lo stesso significato che avrebbero in SQL).


0

Con così tanti record all'anno finirai per esaurire lo spazio. Perché non l'archiviazione del filesystem come xfs che supporta file 2 ^ 64 e utilizza scatole più piccole. Indipendentemente da quanto le persone fantasiose vogliano ottenere o dalla quantità di denaro che si finirebbe per spendere per ottenere un sistema con qualsiasi database SQL NoSQL ... qualunque questi molti record siano solitamente realizzati da compagnie elettriche e stazioni meteorologiche / fornitori come il ministero dell'ambiente che controlla i più piccoli stazioni in tutto il paese. Se stai facendo qualcosa come memorizzare pressione .. temperatura .. velocità del vento .. umidità ecc ... e guid è la posizione .. puoi comunque dividere i dati per anno / mese / giorno / ora. Supponendo di archiviare 4 anni di dati per disco rigido. Puoi quindi farlo funzionare su un Nas più piccolo con specchio dove fornirebbe anche velocità di lettura migliori e avere più punti di montaggio .. in base all'anno in cui è stato creato. Puoi semplicemente creare un'interfaccia web per le ricerche Quindi dumping posizione1 / 2001/06/01 // temperatura e posizione1 / 2002/06/01 // temperature scaricherebbe solo il contenuto della temperatura oraria per il primo giorno d'estate in quei 2 anni (24h * 2) 48 piccoli file rispetto alla ricerca in un database con miliardi di record e forse milioni spesi. Modo semplice di vedere le cose .. 1,5 miliardi di siti web nel mondo con Dio sa quante pagine ciascuno Se un'azienda come Google dovesse spendere milioni per 3 miliardi di ricerche per pagare supercomputer per questo, sarebbe al verde. Invece hanno la bolletta elettrica ... un paio di milioni di computer di merda. E l'indicizzazione della caffeina ... a prova di futuro ... continua ad aggiungere altro. E sì, dove l'indicizzazione basata su SQL ha senso, allora fantastico Costruire supercomputer per compiti scadenti con cose fisse come il tempo ... statistiche e così via in modo che i tecnici possano vantarsi dei loro sistemi scricchiola xtb in x secondi ... spreco di denaro che può essere trascorso da qualche altra parte ..


-2

Archiviare i record in semplici file binari, un file per GUID, non sarebbe più veloce di così.


5
Ti aspetti davvero che funzioni bene?
ChaosPandion

3
Sì, la creazione di miliardi di file sul file system può essere devastante per alcuni file system. Ho commesso l'errore di fare qualcosa del genere, ma con solo 1 milione e ho praticamente bloccato il sistema cercando di aprire una shell in una di quelle cartelle. Inoltre, a meno che tu non stia cercando in base a una guida, come dovrebbe funzionare il meccanismo di query?
Rob Goodwin

È difficile indovinare come si comporterebbe senza sapere quanti GUID univoci sono attesi :) Ma non c'è niente di più semplice della semplice scrittura su file semplici. E l'unico requisito era l'inserimento veloce e la ricerca tramite GUID.
Thomas Kjørnes

Può funzionare ma devi limitare il numero di file per cartella. Devi generare una nuova cartella per n file. È possibile utilizzare una sottostringa del guid come nome della cartella.
TTT

1
sì, c'è un limite al numero di inode per molti filesystem e ricordo di aver raggiunto quel limite noi stessi sul filesystem predefinito redhat ... il limite era di circa 1.000.000 di file o giù di lì.
Dean Hiller

-3

Puoi usare MongoDB e usare il guid come chiave di partizionamento orizzontale, questo significa che puoi distribuire i tuoi dati su più macchine ma i dati che vuoi selezionare sono solo su una macchina perché selezioni con la chiave di partizionamento orizzontale.

Lo sharding in MongoDb non è ancora pronto per la produzione.

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.