Stockage d'énormes quantités de données à partir d'un réseau de capteurs

14

J'ai été chargé de mettre en œuvre une solution (app et db) pour stocker les échantillons de données à partir d'un énorme réseau de capteurs. Le réseau se compose actuellement d'environ 20 000 capteurs, mais cela va bientôt augmenter, jusqu'à 100 000 capteurs. Chaque capteur envoie un échantillon de données toutes les 10 secondes et chaque échantillon a une taille de 28 octets.

Faire les sommes conduit donc à:

  • 8640 échantillons par capteur par jour
  • 242 Ko de données par capteur et par jour
  • 864 millions d'échantillons par jour

Maintenant, je me demandais quelle serait la meilleure façon de stocker / récupérer les données? J'ai «rejoint» ce projet après que le logiciel a déjà été spécifié, il doit donc être implémenté sur une plate-forme Windows utilisant SQL Server.

La solution actuelle dans ma tête est de créer une base de données avec deux tables pour stocker les échantillons de données. Le premier sert comme une sorte d'index dans le second qui stocke les échantillons rassemblés dans un champ binaire par jour et par capteur:

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 

Fondamentalement, j'écrirai les échantillons de tous les capteurs dans des fichiers temporaires (1 par capteur). À la fin de chaque journée, je vais ensuite créer une entrée dans le tableau 1, utiliser le RecordID généré et vider le fichier dans le champ de données du tableau 2.

De cette façon, je me retrouve avec seulement 100 000 entrées dans la table par jour, au lieu de 864 millions d'entrées. Les données doivent être disponibles sur le LAN ou le WAN haute vitesse, de sorte que la récupération des données du capteur sur une journée entière serait acceptable.

Bien que toutes les données doivent être stockées, la plupart d'entre elles ne seront probablement jamais lues. Ainsi, le nombre de lectures sur les tables ne sera pas énormément supérieur aux écritures.

Je sais que je pourrais implémenter quelque chose en utilisant le système de fichiers en stockant simplement le chemin d'accès aux fichiers de données, mais j'ai lu que SQL Server surpasse NTFS tandis que vos champs binaires sont moins 256 Ko. (Une zone grise existe entre 256 Ko et 1 Mo, tandis que NTFS surpasse de loin SQL Server pour des tailles binaires> 1 Mo).

Je suis également légèrement réticent à l'idée de stocker des données de 100 000 capteurs dans leurs propres fichiers sans causer de problèmes dans le système de fichiers en ayant d'énormes quantités de fichiers dans un dossier, ou en ayant une arborescence complexe avec quelques fichiers dans chaque dossier, sans même en tenant compte de la fragmentation des fichiers.

  1. Quelqu'un peut-il me donner des conseils / commentaires pratiques sur ce qui précède?

  2. Y a-t-il des pièges évidents dans lesquels je vais tomber?

  3. Les données d'exemple se compressent assez bien. Un fichier de 242 Ko se comprime à environ 85 Ko. Puis-je cependant implémenter un type de compression au niveau de la base de données afin que les données d'exemple (colonne) soient compressées automatiquement?

  4. SQL Server est-il manifestement un mauvais choix pour ce projet?

  5. Ma conception des deux tables est-elle judicieuse, ou pourrais-je tout aussi bien la combiner en une seule table qui sera toujours aussi "performante" que les deux tables?

Oliver
la source
5
SQL Server prend en charge la compression au niveau des lignes et des tables pour des choses comme celle-ci.
JNK
2
Puisqu'il n'y a qu'une seule entrée / capteur / jour, avez-vous besoin du tableau 1?
GalacticJello
2
Que comptez-vous faire de ces données une fois qu'elles seront dans la base de données? Je ne peux pas imaginer pouvoir agréger des données de capteur dans un format binaire, du moins pas facilement ou rapidement à ces niveaux.
datagod
1
100 000 capteurs X 10 échantillons par seconde X 28 octets par échantillon x 24 heures par jour = 2,2 To par jour. C'est beaucoup à mettre dans deux tableaux.
datagod
2
@AlexKuznetsov: Je me posais des questions sur le choix de SQL Server, mais ce sont des partenaires Microsoft Gold, donc je suppose que c'est la principale raison.
Oliver

Réponses:

12

Oui, il y a un assez gros écueil que vous allez rencontrer assez rapidement, et c'est avec la taille et l'entretien des tables. Vous êtes quelque peu sur la bonne voie en disant que vous souhaitez mettre vos données dans une table temporaire quotidiennement, puis les déplacer dans votre table permanente, mais vous aurez bientôt des problèmes avec ce schéma.

Par exemple, supposons que vous souhaitiez "retirer" les données du mois le plus ancien après deux ans. Dans votre conception, vous devrez émettre une instruction DELETE sur votre grande, grande table. Cela sera probablement un peu lent, selon le nombre d'index dont vous disposez. En outre, cela entraînera la fragmentation des index, et la seule façon de résoudre ce problème serait de reconstruire ou de réorganiser les index sur cette très grande table, ce qui entraînerait également des problèmes de performances. Il existe également toute une série d'autres problèmes liés à la conception d'un grand type de table unique. Par exemple, avec une grande table unique, vous ne pouvez pas faire de sauvegardes basées sur FILEGROUP , ce qui signifie que si vous voulez avoir une sauvegarde complète de votre base de données, ça va être GRAND, et ça va prendre beaucoup de temps pour terminer.

Quelle est la solution? Partitionnement de table. Lisez à ce sujet en profondeur, dans autant d'endroits que possible. Fondamentalement, le partitionnement vous permet de diviser vos données en "tables dans les tables" - chaque partition partage le même schéma et est accessible via l'objet table, mais peut être indexée et gérée différemment. Les partitions sont essentiellement des tables, découpées par une clé utile. Dans votre cas, ce sera probablement la date. Ils peuvent être supprimés comme (et aussi rapidement que) les tables, ce qui signifie que si vous partitionnez vos tables de Big Data par date, vous pouvez simplement supprimer les anciennes partitions instantanément, sans effet négatif sur les index des autres partitions. Vous pouvez placer des partitions sur différents groupes de fichiers, ce qui signifie que les anciennes partitions peuvent être supprimées ou transférées vers un stockage de produits moins cher s'il n'est pas couramment utilisé. Enfin, dans SQL 2012, vous 'sur vos anciennes partitions en lecture seule , tout en ayant un schéma d'indexation différent et plus orienté insert sur la partition active où vous insérez toutes vos données de capteur.

J'espère que cela t'aides. Vous avez beaucoup de recherches à faire concernant le partitionnement et les schémas de partitionnement, mais j'espère que vous savez maintenant dans quelle direction vous devez chercher.

PS: Oh, et j'ai oublié votre liste à puces de questions ... Réponses 1, 2 et 5. Voir ci-dessus. Réponse 3: Dans SQL Server, vous pouvez compresser partition par partition, donc compressez vos anciennes partitions de manière agressive en utilisant la compression PAGE. Mais je crois que vos types de données volumineux hors ligne ne seront pas compressés si vous faites cela - encore une fois, vous souhaiterez peut-être atténuer ce problème en normalisant les valeurs de vos capteurs. Réponse 4: Absolument pas, mais si tout ce que vous voulez faire est de stocker des données statiques par jour et de ne jamais les rechercher autrement, les fichiers plats compressés peuvent être un moyen beaucoup plus facile.

PPS: Oh, et autre chose. Vous n'avez pas besoin de votre solution à deux tables pour que tout cela fonctionne. Les données de capteur binaire volumineux doivent être de type VARBINARY (MAX) car leurs valeurs peuvent être stockées " hors ligne " mais toujours être une colonne dans une seule table (voir la documentation de sp_tableoption ). Vous voudrez peut-être envisager de normaliser certaines de vos données de capteur à partir des données binaires que vous avez dans le tableau, car votre base de données ne sera pas utile bien au-delà de la récupération de morceaux de données de capteur dans le temps si vous ne le faites pas.

Dave Markle
la source
Super information, merci. Je ne suis pas tout à fait sûr de ce que vous entendez par «normaliser» dans ce cas. Je suppose cependant que vous voulez dire que je devrais extraire certains des champs les plus utiles dans les blocs de données et les stocker dans leurs propres colonnes. Si c'est le cas, la raison pour laquelle je ne voulais pas faire cela au départ est que cela signifie que je finirai avec 864 millions de lignes par jour. Tout rassembler et le stocker en un seul morceau signifie seulement 100 000 lignes par jour. Ou existe-t-il une meilleure façon?
Oliver
1
Si vous utilisez une base de données, alors oui, c'est exactement ce que je veux dire. 864 millions de lignes par jour peuvent être traitées efficacement si vous avez le bon matériel, le schéma d'indexation et le schéma de partitionnement pour le faire fonctionner. Tout dépend de vos besoins réels et de la raison pour laquelle vous stockez toutes ces données. Si c'est juste à des fins d'archivage, la colonne binaire est très bien. Si vous souhaitez en extraire la valeur commerciale à l'aide de SQL Server, c'est une tout autre histoire.
Dave Markle
0

Considérez une solution Hadoop. 2 To / jour s'additionnent rapidement. Considérez également la journalisation uniquement des enregistrements delta, c'est-à-dire une valeur initiale, puis uniquement lorsqu'un changement se produit.

Carter Shore
la source