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.
Quelqu'un peut-il me donner des conseils / commentaires pratiques sur ce qui précède?
Y a-t-il des pièges évidents dans lesquels je vais tomber?
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?
SQL Server est-il manifestement un mauvais choix pour ce projet?
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?
la source
Réponses:
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.
la source
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.
la source