Memorizzazione di dati di serie storiche, relazionali o non?


185

Sto creando un sistema che esegue il polling dei dispositivi per i dati su metriche variabili come l'utilizzo della CPU, l'utilizzo del disco, la temperatura, ecc. A (probabilmente) intervalli di 5 minuti utilizzando SNMP. L'obiettivo finale è quello di fornire visualizzazioni a un utente del sistema sotto forma di grafici di serie temporali.

Ho esaminato l'utilizzo di RRDTool in passato, ma l'ho rifiutato poiché la memorizzazione indefinita dei dati acquisiti è importante per il mio progetto e desidero un livello superiore e un accesso più flessibile ai dati acquisiti. Quindi la mia domanda è davvero:

Cosa c'è di meglio, un database relazionale (come MySQL o PostgreSQL) o un database non relazionale o NoSQL (come MongoDB o Redis) per quanto riguarda le prestazioni quando si interrogano i dati per la rappresentazione grafica.

relazionale

Dato un database relazionale, utilizzerei una data_instancestabella, in cui verrebbero archiviate tutte le istanze di dati acquisiti per ogni metrica misurata per tutti i dispositivi, con i seguenti campi:

campi: id fk_to_device fk_to_metric metric_value timestamp

Quando voglio disegnare un grafico per una particolare metrica su un particolare dispositivo, devo interrogare questa singolare tabella filtrando gli altri dispositivi e le altre metriche analizzate per questo dispositivo:

SELECT metric_value, timestamp FROM data_instances
    WHERE fk_to_device=1 AND fk_to_metric=2

Il numero di righe in questa tabella sarebbe:

d * m_d * f * t

dove dè il numero di dispositivi , m_dè il numero cumulativo di metriche registrate per tutti i dispositivi, fè la frequenza con cui i dati vengono sottoposti a polling ed tè il tempo totale in cui il sistema ha raccolto i dati.

Per un utente che registra 10 metriche per 3 dispositivi ogni 5 minuti per un anno, avremmo poco meno di 5 milioni di record.

indici

Senza gli indici attivi fk_to_devicee la fk_to_metricscansione di questa tabella in continua espansione richiederebbe troppo tempo. Pertanto, timestampè obbligatorio l'indicizzazione dei suddetti campi e anche (per la creazione di grafici con periodi localizzati).

Non relazionale (NoSQL)

MongoDB ha il concetto di una raccolta , a differenza delle tabelle che possono essere create a livello di programmazione senza impostazione. Con questi ho potuto partizionare la memorizzazione dei dati per ciascun dispositivo, o anche ogni metrica registrata per ciascun dispositivo.

Non ho esperienza con NoSQL e non so se forniscono funzionalità di miglioramento delle prestazioni della query come l'indicizzazione, tuttavia il paragrafo precedente propone di eseguire la maggior parte del lavoro di query relazionale tradizionale nella struttura in cui i dati sono archiviati in NoSQL.

indeciso

Una soluzione relazionale con una corretta indicizzazione si ridurrebbe a una scansione entro l'anno? Oppure la struttura basata sulla raccolta di approcci NoSQL (che corrisponde al mio modello mentale dei dati memorizzati) offre un notevole vantaggio?


1
Domanda molto valida, io stesso ho riflettuto su questo se il DB relazionale è il modo giusto per memorizzare una struttura di dati che è in realtà gerarchica (struttura SNMP). A volte quando scrivo una query per recuperare anche dati banali, la query è troppo complicata, ho sentito che i dati dovevano essere manipolati in un modulo che non era suo. Ad esempio, abbinare ifnames e i loro indici è presumibilmente un'attività banale, essendo entrambi figli dello stesso oid genitore. Ma il modo in cui è archiviato nel DB relazionale, non si riferisce alla sua struttura originale e ritengo sia più efficiente archiviarlo in modo gerarchico.
Benny,

"Per un utente che registra 10 metriche per 3 dispositivi ogni 5 minuti per un anno, avremmo poco meno di 5 milioni di record." 10 * 3 * 365 * 24 * 12 non è approssimativamente uguale a 3 milioni che non è poco meno di 5 milioni?
Mathieu Borderé,

Risposte:


152

Sicuramente relazionale. Flessibilità ed espansione illimitate.

Due correzioni, sia nel concetto che nell'applicazione, seguite da un'elevazione.

Correzione

  1. Non sta "filtrando i dati non necessari"; sta selezionando solo i dati necessari. Sì, ovviamente, se si dispone di un indice per supportare le colonne identificate nella clausola WHERE, è molto veloce e la query non dipende dalla dimensione della tabella (prendere istantaneamente 1.000 righe da una tabella da 16 miliardi di righe) .

  2. Il tuo tavolo ha un serio impedimento. Data la tua descrizione, il PK effettivo è (Dispositivo, Metrico, DateTime). (Per favore, non chiamarlo TimeStamp, questo significa qualcos'altro, ma questo è un problema minore.) L'unicità della riga è identificata da:

       (Device, Metric, DateTime)
    
    • La Idcolonna non fa nulla, è totalmente e completamente ridondante.

      • Una Idcolonna non è mai una chiave (le righe duplicate, che sono vietate in un database relazionale, devono essere impedite con altri mezzi).
      • La Idcolonna richiede un indice aggiuntivo, che ovviamente impedisce la velocità di INSERT/DELETEe aggiunge allo spazio su disco utilizzato.

      • Puoi liberartene. Per favore.

Elevazione

  1. Ora che hai rimosso l'impedimento, potresti non averlo riconosciuto, ma il tuo tavolo è in sesta forma normale. Altissima velocità, con un solo indice sul PK. Per capire, leggi questa risposta dalla Cos'è la sesta forma normale? proseguendo.

    • (Ho un solo indice, non tre; sui Non-SQL potresti aver bisogno di tre indici).

    • Ho lo stesso identico tavolo (senza la Id"chiave", ovviamente). Ho una colonna aggiuntiva Server. Supporto più clienti in remoto.

      (Server, Device, Metric, DateTime)

    La tabella può essere utilizzata per eseguire il pivot dei dati (ad es. DevicesAttraverso la parte superiore e Metricsinferiore o laterale) utilizzando esattamente lo stesso codice SQL (sì, cambia le celle). Uso la tabella per creare una varietà illimitata di grafici e diagrammi per i clienti in merito alle prestazioni del server.

    • Monitorare il modello di dati statistici .
      (Troppo grande per in linea; alcuni browser non possono caricare in linea; fare clic sul collegamento. Inoltre questa è la versione demo obsoleta, per ovvi motivi, non posso mostrarti DM commerciale del prodotto.)

    • Mi permette di produrre grafici come questo , sei sequenze di tasti dopo aver ricevuto un file di statistiche di monitoraggio non elaborato dal cliente, utilizzando un singolo comando SELECT . Notare il mix-and-match; Sistema operativo e server sullo stesso grafico; una varietà di perni. Naturalmente, non vi è alcun limite al numero di matrici delle statistiche e quindi ai grafici. (Utilizzato con il gentile consenso del cliente.)

    • I lettori che non hanno familiarità con lo standard per la modellazione di database relazionali possono trovare utile la notazione IDEF1X .

Un'altra cosa

Ultimo ma non meno importante, SQL è uno standard IEC / ISO / ANSI. Il freeware è in realtà non SQL; è fraudolento usare il termine SQL se non forniscono lo standard. Possono fornire "extra", ma sono assenti le basi.


1
@PerformanceDBA useresti lo schema suggerito per un'installazione che deve gestire ~ 3 milioni di misure con una frequenza di 1 minuto? Come ordinereste il PK per un tavolo del genere? Device, Metric, DateTime non creerebbe la frammentazione e costringerebbe RDBMS a un sacco di divisione della pagina? Invece mettere al primo posto DateTime ridurrebbe la frammentazione (presumo che gli inserimenti ordinati per tempo) ma peggiori le letture.
marcob

1
@Buchi. Uso Sybase ASE. Ma questo non è un problema di piattaforma (certo, le piattaforme alte forniscono prestazioni che sono ordini di grandezza migliori della fascia bassa; tre ordini di grandezza migliori di Oracle, ma non è questo il punto), l'erezione del grafico dalla tabella " funziona "su qualsiasi piattaforma. Usa lo strumento giusto per il lavoro. RDBMS è uno strumento di database, non uno strumento di rappresentazione grafica. gnuplot, Apple Numbers (o se ti piace pagare dieci volte di più, per metà, MS Excel) sono strumenti grafici, non strumenti di database. In questi giorni usiamo strati di strumenti per produrre un risultato, il monolito è un dinosauro.
PerformanceDBA

1
@marcob. La tua domanda è buona, ma non è possibile rispondere correttamente nei commenti. Se apri una nuova domanda e mi invii un'email (vai al profilo), risponderò. Per la risposta rapida qui. (1) ~ 3 milioni di metriche. Fantastico, più è bello, diffonde i punti INSERT meravigliosamente, i tuoi garantirebbero conflitti nell'ultima pagina. Il server è multi-thread, sì? Partiziona il tavolo. Utilizzare FILLFACTOR e lasciare spazio per gli inserti, evitando così la divisione delle pagine. (2) ~ 3 Mill indica che le metriche non sono normalizzate, se lo correggi, sarà ancora più veloce.
PerformanceDBA

1
@marcob. (3) Uso esattamente l' indice indicato per diffondere gli inserti sotto carico, il che garantisce l'assenza di conflitti. (4) Pertanto, il mio metodo ottiene entrambi gli inserti senza conflitti e alte prestazioni su SELECT.
PerformanceDBA

2
@Loic. Perché mai qualcuno, che ha un investimento (dati; codice) in una piattaforma SQL, che gestisce i dati di serie temporali facilmente e con prestazioni molto elevate (come dettagliato nella risposta), dovrebbe migrare a un TSDB senza SQL; velocità sconosciuta per nulla tranne i dati delle serie storiche? Perché qualcuno che ha un requisito che supera solo le serie temporali, non dovrebbe utilizzare una piattaforma SQL? La mente vacilla. TSDB è più veloce di Relational solo nel caso triste quando i dati sono memorizzati in un db ma non normalizzati Relazionalmente. Per esempio. quando Idvengono utilizzate le colonne, come "chiavi". Come consigliato dai "teorici".
PerformanceDBA

21

Trovate molto interessanti le risposte sopra. Sto provando ad aggiungere un altro paio di considerazioni qui.

1) Invecchiamento dei dati

La gestione delle serie temporali di solito deve creare politiche di invecchiamento. Uno scenario tipico (ad esempio la CPU del server di monitoraggio) richiede di memorizzare:

  • Campioni grezzi da 1 secondo per un breve periodo (ad es. Per 24 ore)

  • Campioni aggregati dettagliati di 5 minuti per un periodo medio (ad es. 1 settimana)

  • Dettagli di 1 ora oltre (ad es. Fino a 1 anno)

Sebbene i modelli relazionali rendano sicuramente possibile (la mia azienda ha implementato enormi database centralizzati per alcuni grandi clienti con decine di migliaia di serie di dati) per gestirli in modo appropriato, la nuova generazione di archivi dati aggiunge funzionalità interessanti da esplorare come:

  • eliminazione automatica dei dati (vedere il comando EXPIRE di Redis)

  • aggregazioni multidimensionali (ad es. lavori di riduzione della mappa a-la-Splunk)

2) Raccolta in tempo reale

Ancora più importante, alcuni archivi di dati non relazionali sono intrinsecamente distribuiti e consentono una raccolta di dati in tempo reale (o quasi in tempo reale) molto più efficiente che potrebbe essere un problema con RDBMS a causa della creazione di hotspot (gestione dell'indicizzazione durante l'inserimento in un unico tavolo). Questo problema nello spazio RDBMS è in genere risolto ripristinando le procedure di importazione in batch (in passato l'abbiamo gestita in questo modo) mentre le tecnologie no-sql sono riuscite a raccogliere e aggregare in tempo reale (vedi Splunk per esempio, menzionato nelle risposte precedenti) .


7

La tabella contiene dati in un'unica tabella. Quindi relazionale vs non relazionale non è la domanda. Fondamentalmente è necessario leggere molti dati sequenziali. Ora se hai abbastanza RAM per archiviare dati per un valore di anni allora niente come usare Redis / MongoDB ecc.

Per lo più i database NoSQL memorizzeranno i tuoi dati nella stessa posizione sul disco e in forma compressa per evitare l'accesso multiplo al disco.

NoSQL fa la stessa cosa della creazione dell'indice sull'ID dispositivo e sull'ID metrica, ma a modo suo. Con il database anche se lo fai, l'indice e i dati potrebbero trovarsi in luoghi diversi e ci sarebbero molti IO del disco.

Strumenti come Splunk stanno usando i backend NoSQL per archiviare i dati delle serie temporali e quindi l'utilizzo della riduzione della mappa per creare aggregati (che potrebbe essere quello che vuoi in seguito). Quindi, secondo me, usare NoSQL è un'opzione poiché le persone l'hanno già provato per casi d'uso simili. Ma milioni di righe porteranno la scansione del database (forse no, con hardware decente e configurazioni adeguate).


1
Potresti spiegare come la tabella è "de-normalizzata"? Marcus presenta un errore nella tabella, ma non si tratta di un errore di normalizzazione.
PerformanceDBA

mi correggerò, le tabelle sono normalizzate nel senso tradizionale. Intendevo de-normalizzato, nel senso che il caso d'uso ha tutti i dati in una tabella qui.
Ravindra,

4

Crea un file, chiamalo 1_2.data. idea weired? cosa ottieni:

  • Risparmia fino al 50% dello spazio perché non è necessario ripetere il valore fk_to_device e fk_to_metric per ogni punto dati.
  • Risparmia ancora più spazio perché non hai bisogno di indici.
  • Salvare coppie di (data / ora, metric_value) nel file aggiungendo i dati in modo da ottenere un ordine per data e ora gratuitamente. (supponendo che le tue fonti non invino dati fuori ordine per un dispositivo)

=> Le query per timestamp sono incredibilmente veloci perché puoi usare la ricerca binaria per trovare il posto giusto nel file da cui leggere.

se ti piace ancora di più, inizia a pensare a suddividere i tuoi file in questo modo;

  • 1_2_january2014.data
  • 1_2_february2014.data
  • 1_2_march2014.data

oppure usa kdb + da http://kx.com perché fanno tutto questo per te :) orientato alle colonne è ciò che può aiutarti.

Esiste una soluzione orientata alle colonne basata su cloud, quindi potresti dare un'occhiata a: http://timeseries.guru


Ho scritto un post sul blog sull'argomento. con google translate potresti trovare utile: blog.michaelwittig.info/die-spaltenorientierte-datenbank-kdb
hellomichibye

3

Se stai guardando i pacchetti GPL, RRDTool è una buona idea . È un buon strumento per archiviare, estrarre e rappresentare graficamente i dati di serie temporali. Il tuo caso d'uso assomiglia esattamente ai dati delle serie temporali.


2

Questo è un problema che abbiamo dovuto risolvere in ApiAxle. Abbiamo scritto un post sul blog su come lo abbiamo fatto usando Redis. Non è stato là fuori per molto tempo ma sta dimostrando di essere efficace.

Ho anche usato RRDTool per un altro progetto che è stato eccellente.


2

Ritengo che la risposta a questo tipo di domanda debba riguardare principalmente il modo in cui il database utilizza l'archiviazione. Alcuni server di database utilizzano RAM e disco, altri usano solo RAM (facoltativamente disco per persistenza), ecc. Le soluzioni di database SQL più comuni utilizzano memoria + archiviazione su disco e scrivono i dati in un layout basato su righe (ogni raw inserito è scritto nello stesso luogo fisico). Per i negozi in serie, nella maggior parte dei casi il carico di lavoro è simile a: Intervallo relativamente basso di una grande quantità di inserti, mentre le letture sono basate su colonne (nella maggior parte dei casi si desidera leggere un intervallo di dati da una colonna specifica, che rappresenta una metrica)

Ho trovato Database Colonnari (google, troverai MonetDB, InfoBright, parAccel, ecc.) Stanno facendo un lavoro formidabile per le serie storiche.

Per quanto riguarda la tua domanda, che personalmente ritengo un po 'invalida (come tutte le discussioni che usano il termine di errore NoSQL - IMO): puoi usare un server di database in grado di parlare SQL da un lato, rendendo la tua vita molto facile poiché tutti conoscono SQL per molti anni e questo linguaggio è stato perfezionato più e più volte per le query sui dati; ma utilizza ancora RAM, cache della CPU e disco in modo orientato alla colonna, rendendo la soluzione più adatta alle serie temporali


2

5 milioni di righe non sono nulla per i dati torrenziali di oggi. Aspettatevi che i dati siano nel TB o nel PB in pochi mesi. A questo punto RDBMS non si adatta all'attività e abbiamo bisogno della scalabilità lineare dei database NoSql. Le prestazioni sarebbero ottenute per la partizione colonnare utilizzata per archiviare i dati, aggiungendo più colonne e meno righe di concetti per migliorare le prestazioni. Sfrutta il lavoro Open TSDB svolto su HBASE o MapR_DB, ecc.


"RDBMS non si adatta all'attività" - perché non dovrebbero? code.facebook.com/posts/190251048047090/…
Zathrus Writer

1

Devo affrontare regolarmente requisiti simili e di recente ho iniziato a utilizzare Zabbix per raccogliere e archiviare questo tipo di dati. Zabbix ha le sue capacità grafiche, ma è abbastanza facile estrarre i dati dal database di Zabbix ed elaborarli come preferisci. Se non hai già controllato Zabbix, potresti trovare utile farlo.


Sì, Zabbix è carino e si integra già con il monitoraggio SNMP. Zabbix può usare MySQL o PostgreSQL e funziona più o meno immediatamente su Ubuntu.
Dirk Eddelbuettel,

Grazie, conosco Zabbix e molti altri strumenti SNMP. Tuttavia sto sviluppando questo progetto come processo educativo, nell'argomento discusso qui e in molti altri aspetti. Un buon punto però!
Marcus Whybrow,

0

È necessario esaminare il database delle serie temporali . È stato creato per questo scopo.

Un database di serie temporali (TSDB) è un sistema software ottimizzato per la gestione di dati di serie temporali, matrici di numeri indicizzati dal tempo (un datetime o un intervallo di datetime).

Esempio popolare di database di serie storiche InfluxDB


aggiungi timescaledb a questo elenco ora
PirateApp,
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.