Archiviazione di enormi quantità di dati da un array di sensori


14

Mi è stato assegnato il compito di implementare una soluzione (app e db) per archiviare i campioni di dati da un enorme array di sensori. L'array è attualmente composto da circa 20.000 sensori, ma che presto crescerà, fino a 100.000 sensori. Ogni sensore invia un campione di dati ogni 10 secondi e ogni campione ha una dimensione di 28 byte.

Fare le somme porta quindi a:

  • 8640 campioni per sensore al giorno
  • 242kB di dati per sensore al giorno
  • 864 milioni di campioni al giorno

Ora mi chiedevo quale sarebbe il modo migliore per archiviare / recuperare i dati? Ho aderito a questo progetto dopo che il software è già stato specificato, quindi deve essere implementato su una piattaforma Windows utilizzando SQL Server.

La soluzione attuale nella mia testa è quella di creare un DB con due tabelle per memorizzare i campioni di dati. Il primo funge da una sorta di indice nel secondo che memorizza i campioni raccolti in un campo binario su base giornaliera per sensore:

Table 1:

  RecordID - BigInt - Identity
  SensorID - BigInt - Primary Key
  Date - DateTime - Primary Key (yyyy-mm-dd)

Table 2:

  RecordID - BigInt - Primary Key (from an insert into Table 1)
  Data - Binary 

Fondamentalmente scriverò i campioni da tutti i sensori in file temporanei (1 per sensore). Alla fine di ogni giorno creerò quindi una voce nella Tabella 1, userò il RecordID generato e scaricherò il file nel campo Dati nella Tabella 2.

In questo modo finisco con solo 100.000 voci nella tabella al giorno, invece di 864 milioni di voci. I dati dovrebbero essere disponibili sulla LAN o sulla WAN ad alta velocità, quindi il recupero dei dati del sensore su base giornaliera sarebbe accettabile.

Sebbene tutti i dati debbano essere archiviati, probabilmente non verranno mai letti. Quindi la quantità di letture nelle tabelle non sarà enormemente maggiore delle scritture.

So che potrei implementare qualcosa usando il file system semplicemente memorizzando il percorso dei file di dati, ma ho letto che SQL Server supera NTFS mentre i tuoi campi binari sono meno grazie a 256kB. (Esiste un'area grigia tra 256 KB e 1 MB, mentre NTFS supera di gran lunga SQL Server per dimensioni binarie> 1 MB).

Sono anche leggermente diffidente nell'archiviare i dati da 100.000 sensori nei propri file senza causare problemi nel file system avendo enormi quantità di file in una cartella o avendo una struttura ad albero complessa con pochi file in ogni cartella, ma non anche tenendo conto della frammentazione dei file.

  1. Qualcuno può offrirmi alcuni consigli pratici / commenti su quanto sopra?

  2. Ci sono ovvie insidie ​​in cui cadrò?

  3. I dati di esempio vengono compressi abbastanza bene. Un file di 242 kB si comprime a circa 85 kB. Posso tuttavia implementare un tipo di compressione a livello di database in modo che i dati di esempio (colonna) vengano compressi automaticamente?

  4. SQL Server è ovviamente una scelta errata per questo progetto?

  5. Il mio design dei due tavoli è saggio o potrei anche combinarlo in un unico tavolo che sarà comunque "performante" come i due tavoli?


5
SQL Server supporta la compressione a livello di riga e a livello di tabella per cose come questa.
JNK

2
Dato che c'è solo 1 ingresso / sensore / giorno, hai bisogno di Table1?
GalacticJello

2
Cosa pensi di fare con questi dati, una volta che sono nel database? Non riesco a immaginare di essere in grado di aggregare i dati dei sensori in un formato binario, almeno non facilmente o rapidamente a quei livelli.
datagod

1
100.000 sensori X 10 campioni al secondo X 28 Bit per campione x 24 ore al giorno = 2,2 TB al giorno. Questo è molto da mettere in due tabelle.
datagod

2
@AlexKuznetsov: Mi stavo chiedendo da solo sulla scelta di SQL Server, ma sono partner gold di Microsoft, quindi immagino che sia la ragione principale.
Oliver

Risposte:


12

Sì, c'è una grande trappola che ti imbatterai abbastanza rapidamente, cioè con le dimensioni e la manutenzione dei tavoli. Sei in qualche modo sulla buona strada dicendo che vuoi mettere i tuoi dati in una tabella temporanea quotidianamente e poi spostarli nella tua tabella permanente, ma presto incontrerai problemi con questo schema.

Ad esempio, supponiamo che tu voglia "distribuire" i dati del mese più vecchio dopo due anni. Nel tuo progetto, dovresti emettere un'istruzione DELETE sul tuo tavolo grande e grande. Questo sarà probabilmente un po 'lento, a seconda del numero di indici che hai. Inoltre, causerà la frammentazione degli indici e l'unico modo per risolvere questo sarebbe ricostruire o riorganizzare gli indici su questa tabella molto grande che causerebbe anche problemi di prestazioni. Ci sono tutta una serie di altri problemi con un grande tipo di progettazione a tabella singola. Ad esempio, con una grande tabella singola, non è possibile eseguire backup basati su FILEGROUP , il che significa che se si desidera avere un backup completo del database, sarà GRANDE e il completamento del processo richiederà molto tempo.

Qual è la soluzione? Partizionamento delle tabelle. Leggi in dettaglio questo argomento, in tutti i posti che puoi. Fondamentalmente, il partizionamento consente di suddividere i dati in "tabelle all'interno di tabelle": ogni partizione condivide lo stesso schema e vi si accede tramite l'oggetto tabella, ma può essere indicizzata e gestita in modo diverso. Le partizioni sono fondamentalmente tabelle, suddivise da una chiave utile. Nel tuo caso sarà probabilmente la data. Possono essere eliminati proprio come (e altrettanto velocemente) le tabelle, il che significa che se partizionate le tabelle dei big data per data, potete semplicemente eliminare istantaneamente le vecchie partizioni, senza effetti negativi sugli indici su nessuna delle altre partizioni. È possibile inserire partizioni in diversi filegroup, il che significa che è possibile eseguire il roll-off delle partizioni più vecchie o archiviarle in una memoria di prodotti più economica se non viene utilizzata comunemente. Ultimo ma non meno importante, in SQL 2012 tu 'sulle partizioni precedenti, di sola lettura , pur avendo uno schema di indicizzazione diverso, più orientato all'inserzione, sulla partizione attiva in cui si stanno inserendo tutti i dati del sensore.

Spero che sia di aiuto. Hai una buona quantità di ricerca da fare per quanto riguarda il partizionamento e gli schemi di partizionamento, ma spero che ora conosci la direzione che devi guardare.

PS: Oh, e ho dimenticato il tuo elenco puntato di domande ... Rispondi 1, 2 e 5. Vedi sopra. Risposta 3: In SQL Server, è possibile comprimere su una partizione in base alla partizione, quindi comprimere le partizioni più vecchie in modo aggressivo utilizzando la compressione PAGE. Ma credo che i tuoi grandi tipi di dati fuori fila non verranno compressi se lo fai - di nuovo, potresti voler alleviare questo problema normalizzando i valori del tuo sensore. Risposta 4: Assolutamente no, ma se tutto ciò che vuoi fare è archiviare i dati statici di giorno e non cercarli mai in altro modo, i file flat compressi potrebbero essere un modo molto più semplice di procedere.

PPS: Oh, e un'altra cosa. Non hai bisogno della tua soluzione a due tavoli per far funzionare tutto questo. I dati del sensore binario di grandi dimensioni devono essere di tipo VARBINARY (MAX) perché i suoi valori possono essere memorizzati " fuori riga " ma essere comunque una colonna in una singola tabella (consultare la documentazione di sp_tableoption ). Tuttavia, potresti considerare di normalizzare alcuni dei dati del tuo sensore dai dati binari che hai nella tabella, perché il tuo database non sarà molto utile se non per recuperare pezzi di dati del sensore in tempo.


Informazioni fantastiche, grazie. Non sono del tutto sicuro di cosa intendi con "normalizzare" in questo caso. Presumo però che tu intenda che dovrei estrarre alcuni dei campi più utili nei blocchi di dati e archiviarli nelle loro colonne. Se è così, il motivo per cui non volevo farlo inizialmente è che significa che finirò con 864 milioni di righe al giorno. Raccogliere tutto e archiviarlo in un blocco significa solo 100.000 file al giorno. O c'è un modo migliore?
Oliver

1
Se stai usando un database, allora sì, è esattamente quello che intendo. 864 milioni di righe al giorno possono essere gestite in modo efficiente se si dispone dell'hardware, dello schema di indicizzazione e dello schema di partizionamento giusti per farlo funzionare. Tutto dipende da quali sono le tue esigenze e dal motivo per cui stai memorizzando tutti questi dati. Se è solo a scopo di archiviazione, la colonna binaria va bene. Se vuoi estrarre valore aziendale da esso utilizzando SQL Server, questa è una storia completamente diversa.
Dave Markle

0

Prendi in considerazione una soluzione Hadoop. 2 TB / giorno si sommano rapidamente. Considera anche di registrare solo i record delta, ovvero un valore iniziale, e solo quando si verifica una modifica.

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.