J'écris une application qui doit stocker et analyser de grandes quantités de données électriques et de température.
J'ai essentiellement besoin de stocker de grandes quantités de mesures horaires de consommation d'électricité au cours des dernières années et des années à venir pour des dizaines de milliers d'emplacements, puis d'analyser les données de manière peu complexe.
Les informations que je dois stocker (pour le moment) sont les suivantes: ID d'emplacement, Horodatage (Date et heure), Température et consommation d'électricité.
À propos de la quantité de données à stocker, c’est une approximation, mais plutôt:
20 000 emplacements, 720 enregistrements par mois (mesures horaires, environ 720 heures par mois), 120 mois (il y a 10 ans) ) et de nombreuses années dans le futur. Des calculs simples donnent les résultats suivants:
20 000 emplacements x 720 enregistrements x 120 mois (10 ans en arrière) = 1 728 000 000 enregistrements .
Il s’agit des enregistrements passés. De nouveaux enregistrements seront importés tous les mois, ce qui représente environ 20 000 x 720 = 14 400 000 nouveaux enregistrements par mois .
Le nombre total d'emplacements augmentera également régulièrement.
Sur toutes ces données, les opérations suivantes devront être exécutées:
- Récupérer les données pour une certaine date ET une période: tous les enregistrements pour un certain ID d'emplacement entre les dates 01.01.2013 et 01.01.2017 et entre 07h00 et 13h00.
- Opérations mathématiques simples pour une certaine date ET une plage horaire, par exemple température et consommation d’électricité MIN, MAX et AVG pour un certain ID de lieu pendant 5 ans entre 07h00 et 13h00.
Les données seront écrites mensuellement, mais seront lues par des centaines d'utilisateurs (au moins) en permanence, de sorte que la vitesse de lecture est beaucoup plus importante.
Je n'ai aucune expérience des bases de données NoSQL, mais d'après ce que j'ai rassemblé, elles constituent la meilleure solution à utiliser ici. J'ai lu sur les bases de données NoSQL les plus populaires, mais comme elles sont assez différentes et permettent également une architecture de table très différente, je n'ai pas été en mesure de décider quelle est la meilleure base de données à utiliser.
Mes choix principaux étaient Cassandra et MongoDB, mais comme je n’ai que des connaissances très limitées et que je n’ai aucune expérience réelle en ce qui concerne les grandes données et NoSQL, je ne suis pas très certain. J'ai également lu que PostreSQL gère également de telles quantités de données.
Mes questions sont les suivantes:
- Devrais-je utiliser une base de données NoSQL pour de telles quantités de données? Sinon, puis-je m'en tenir à MySQL?
- Quelle base de données devrais-je utiliser?
- Devrais-je conserver la date et l'heure dans des colonnes indexées (si possible) distinctes pour récupérer et traiter les données rapidement pour certaines périodes et dates, ou est-ce possible de le faire en conservant l'horodatage dans une seule colonne?
- Une approche de modélisation des données chronologiques est-elle appropriée ici? Sinon, pourriez-vous me donner des indications pour une bonne conception de tableau?
Je vous remercie.
Réponses:
C'est exactement ce que je fais tous les jours, sauf qu'au lieu d'utiliser les données horaires, j'utilise les données de 5 minutes. Je télécharge environ 200 millions de disques par jour, donc le montant dont vous parlez n’est pas un problème. Les données de 5 minutes ont une taille d’environ 2 To et j’ai des données météorologiques remontant à 50 ans à un niveau horaire par lieu. Alors laissez-moi répondre à vos questions en fonction de mon expérience:
Astuce générale: Je stocke la plupart des données entre deux bases de données. La première est une série chronologique simple et normalisée. Ma deuxième base de données est très dé-normalisée et contient des données pré-agrégées. Aussi rapide que mon système est, je ne suis pas aveugle au fait que les utilisateurs ne veulent même pas attendre 30 secondes pour le chargement d'un rapport - même si je pense personnellement que 30 secondes pour traiter 2 To de données, c'est extrêmement rapide.
Pour expliquer pourquoi je recommande de stocker l'heure séparément de la date, voici quelques raisons pour lesquelles je le fais de cette façon:
DATETIME
colonne.Comme je l'ai dit ci-dessus, tout est basé sur mon expérience personnelle, et laissez-moi vous dire que cela a été plusieurs années difficiles et de nombreuses restructurations pour arriver là où je suis maintenant. Ne faites pas ce que j'ai fait, apprenez de mes erreurs et assurez-vous d'impliquer les utilisateurs finaux de votre système (ou les développeurs, auteurs de rapports, etc.) lors de la prise de décisions concernant votre base de données.
la source
Index PostgreSQL et BRIN
Testez-le vous-même. Ce n'est pas un problème sur un ordinateur portable de 5 ans avec un SSD.
Il a donc fallu 22 minutes pour créer la table. En grande partie, parce que la table est un modeste 97GB. Ensuite, nous créons les index,
La création des index a également pris beaucoup de temps. Bien qu'ils soient BRIN, ils ne font que 2 à 3 Mo et se stockent facilement dans le bélier. La lecture de 96 Go n'est pas instantanée, mais ce n'est pas un réel problème pour mon ordinateur portable au moment de votre charge de travail.
Maintenant nous l'interrogeons.
Mettre à jour avec les horodatages
Ici, nous générons une table avec différents horodatages afin de satisfaire la demande d'indexation et de recherche sur une colonne d'horodatage, la création prend un peu plus de temps car elle
to_timestamp(int)
est nettement plus lente quenow()
(mise en cache pour la transaction).Maintenant, nous pouvons exécuter une requête sur une valeur d'horodatage à la place,
Résultat:
Donc, en 83,321 ms, nous pouvons agréger 86 401 enregistrements dans une table avec 1,7 milliard de lignes. Cela devrait être raisonnable.
Heure se terminant
Calculer la fin de l'heure est assez facile aussi, tronquer l'horodatage vers le bas, puis ajoutez simplement une heure.
Il est important de noter qu'il n'utilise pas d'index sur l'agrégation, bien que ce soit le cas. Si c'est ce que vous voulez en général, vous voulez probablement que BRIN
date_trunc('hour', tsin)
pose un petit problème, car ildate_trunc
n'est pas immuable, vous devez donc d'abord l'envelopper pour qu'il en soit ainsi.Partitionnement
Un autre point d’information important sur PostgreSQL est que PG 10 apporte le DDL de partitionnement . Ainsi, vous pouvez, par exemple, créer facilement des partitions pour chaque année. Décomposer votre base de données modeste en minuscules. Ce faisant, vous devriez pouvoir utiliser et gérer les index btree plutôt que BRIN, qui serait encore plus rapide.
Ou peu importe.
la source
Je suis étonné de constater que personne ici n’a mentionné le benchmarking - c’est-à-dire jusqu’à ce que @EvanCarroll apporte son excellente contribution!
Si j'étais vous, je passerais un certain temps (et oui, je sais que c'est un produit précieux!) Pour configurer des systèmes, exécuter ce que vous pensez (obtenez les commentaires de l'utilisateur final ici!), Par exemple vos 10 requêtes les plus courantes.
Mes propres pensées:
Les solutions NoSQL peuvent très bien fonctionner pour des cas d'utilisation particuliers, mais sont souvent inflexibles pour des requêtes ad-hoc. Pour une version amusante de NoSQL par Brian Aker - ancien architecte en chef de MySQL, voir ici !
Je suis d’accord avec @ Mr.Brownstone pour dire que vos données sont parfaitement adaptées à une solution relationnelle (et cette opinion a été confirmée par Evan Carroll )!
Si je devais m'engager dans une dépense, ce serait pour ma technologie de disque! Je dépenserais tout l'argent dont je disposais sur NAS ou SAN ou peut-être des disques SSD pour stocker mes données globales rarement écrites!
D'abord, je regarderais ce que j'ai disponible maintenant . Exécutez des tests et montrez les résultats aux décideurs. Vous avez déjà un proxy sous la forme de travail d' EC ! Mais, un test rapide ou deux fouettés ensemble sur votre propre matériel serait plus convaincant!
Alors pensez à dépenser de l'argent! Si vous envisagez de dépenser de l'argent, examinez d'abord le matériel plutôt que les logiciels. Selon les informations dont vous avez la connaissance, vous pouvez louer la technologie de disque pour une période d’essai ou, mieux, créer quelques preuves de concept sur le cloud.
PostgreSQL est mon premier point de contact personnel pour un projet de ce type. Cela ne veut pas dire que j'éliminerais une solution propriétaire, mais les lois de la physique et des disques sont les mêmes pour tout le monde! "Yae cannae beet les lois de la physique Jim" :-)
la source
Si vous ne l’avez pas déjà fait, jetez un coup d’œil à un SGBD de séries chronologiques, car il est optimisé pour le stockage et l’interrogation de données dont le principal objectif est le type date / heure. En règle générale, les bases de données de séries chronologiques sont utilisées pour enregistrer des données dans la plage des minutes / secondes / sous-secondes. Par conséquent, je ne suis pas sûr que cela soit toujours approprié pour les incréments horaires. Cela dit, ce type de SGBD semble valoir la peine d’être examiné. Actuellement, InfluxDB semble être la base de données de séries chronologiques la plus établie et la plus utilisée.
la source
Clairement, ce n'est pas un problème NoSQL, mais je suggérerais qu'une solution SGBDR puisse fonctionner, mais qu'une approche OLAP conviendrait mieux, et étant donné les plages de données très limitées impliquées, je suggérerais fortement d'envisager l'utilisation d'une base de données basée sur des colonnes. plutôt que basé sur la rangée. Pensez-y de cette façon, vous pourriez avoir 1,7 milliard de données, mais vous n’avez toujours besoin que de 5 bits pour indexer chaque valeur possible d’heure ou de jour du mois.
J'ai déjà travaillé dans un domaine similaire où Sybase IQ (maintenant SAP IQ) stocke jusqu'à 300 millions de compteurs de données de gestion de la performance des équipements télécoms par heure, mais je doute que vous disposiez d'un budget suffisant pour ce type de solution. MariaDB ColumnStore est un candidat très prometteur dans le domaine des logiciels libres, mais je recommanderais également d’enquêter sur MonetDB.
Étant donné que les performances des requêtes sont un facteur important pour vous, prenez en compte le libellé des requêtes. C'est là que OLAP et SGBDR présentent leurs plus grandes différences: - avec OLAP, vous normalisez en fonction des performances des requêtes, et non en réduisant la répétition, le stockage ou même l'application de la cohérence. Donc, en plus de l'horodatage d'origine (vous vous êtes souvenu de capturer son fuseau horaire, j'espère?), Disposez d'un champ distinct pour l'horodatage UTC, d'autres pour la date et l'heure, et encore davantage pour l'année, le mois, le jour, l'heure et la minute. et décalage UTC. Si vous disposez d'informations supplémentaires sur les emplacements, n'hésitez pas à les conserver dans une table d'emplacement séparée qui peut être consultée à la demande. Vous pouvez également conserver la clé de cette table dans votre enregistrement principal tout en conservant le nom complet de l'emplacement dans votre table principale. après tout
En guise de suggestion finale, utilisez des tables distinctes pour les données agrégées courantes et utilisez des travaux par lots pour les renseigner. Ainsi, vous n'avez pas à répéter l'exercice pour chaque rapport qui utilise une valeur agrégée et effectue des requêtes comparant les données actuelles à l'historique ou à l'historique. historique à historique beaucoup plus facile et beaucoup, beaucoup plus rapide.
la source