Stocker des données chronologiques, relationnelles ou non?

185

Je crée un système qui interroge les périphériques pour des données sur des métriques variables telles que l'utilisation du processeur, l'utilisation du disque, la température, etc. à (probablement) 5 minutes d'intervalle en utilisant SNMP. Le but ultime est de fournir des visualisations à un utilisateur du système sous la forme de graphiques chronologiques.

J'ai envisagé d'utiliser RRDTool dans le passé, mais je l'ai rejeté car le stockage des données capturées indéfiniment est important pour mon projet, et je souhaite un accès de plus haut niveau et plus flexible aux données capturées. Donc ma question est vraiment:

Quoi de mieux, une base de données relationnelle (comme MySQL ou PostgreSQL) ou une base de données non relationnelle ou NoSQL (comme MongoDB ou Redis) en ce qui concerne les performances lors de l'interrogation des données pour la représentation graphique.

Relationnel

Étant donné une base de données relationnelle, j'utiliserais une data_instancestable dans laquelle serait stockée chaque instance de données capturées pour chaque métrique mesurée pour tous les appareils, avec les champs suivants:

Des champs: id fk_to_device fk_to_metric metric_value timestamp

Lorsque je veux dessiner un graphique pour une métrique particulière sur un appareil particulier, je dois interroger cette table singulière en filtrant les autres appareils et les autres métriques en cours d'analyse pour cet appareil:

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

Le nombre de lignes dans ce tableau serait:

d * m_d * f * t

dest le nombre d' appareils , m_dest le nombre cumulé de métriques enregistrées pour tous les appareils, fest la fréquence à laquelle les données sont interrogées et test la durée totale pendant laquelle le système a collecté des données.

Pour un utilisateur enregistrant 10 métriques pour 3 appareils toutes les 5 minutes pendant un an, nous aurions un peu moins de 5 millions d' enregistrements.

Index

Sans index fk_to_deviceet sans fk_to_metricanalyse, cette table en expansion continue prendrait trop de temps. Ainsi, l'indexation des champs susmentionnés et également timestamp(pour créer des graphiques avec des périodes localisées) est une exigence.

Non relationnel (NoSQL)

MongoDB a le concept d'une collection , contrairement aux tables, celles-ci peuvent être créées par programme sans configuration. Avec ces derniers, je pourrais partitionner le stockage des données pour chaque appareil, ou même chaque métrique enregistrée pour chaque appareil.

Je n'ai aucune expérience avec NoSQL et je ne sais pas s'ils fournissent des fonctionnalités améliorant les performances des requêtes telles que l'indexation, mais le paragraphe précédent propose de faire la plupart du travail de requête relationnelle traditionnel dans la structure par laquelle les données sont stockées sous NoSQL.

Indécis

Une solution relationnelle avec une indexation correcte se réduirait-elle à une exploration dans l'année? Ou la structure basée sur la collection des approches NoSQL (qui correspond à mon modèle mental des données stockées) offre-t-elle un avantage notable?

Marcus Whybrow
la source
1
Question très valable, je me suis moi-même demandé si la base de données relationnelle est la bonne façon de stocker une structure de données qui est en fait hiérarchique (structure SNMP). Parfois, lorsque j'écris une requête pour récupérer des données même insignifiantes, la requête est trop compliquée, j'ai senti que les données devaient être transformées sous une forme qui n'est pas la sienne. Par exemple, la correspondance des ifnames et de leurs index est censée être une tâche triviale, les deux étant des enfants du même oid parent. Mais la façon dont il est stocké dans la base de données relationnelle ne correspond pas à sa structure d'origine et je pense qu'il est plus efficace de le stocker de manière hiérarchique.
Benny
"Pour un utilisateur enregistrant 10 métriques pour 3 appareils toutes les 5 minutes pendant un an, nous aurions un peu moins de 5 millions d'enregistrements." N'est-ce pas 10 * 3 * 365 * 24 * 12 approximativement égal à 3 millions, ce qui n'est pas un peu moins de 5 millions?
Mathieu Borderé

Réponses:

152

Certainement relationnel. Flexibilité et expansion illimitées.

Deux corrections, à la fois dans le concept et dans l'application, suivies d'une élévation.

Correction

  1. Il ne s'agit pas de "filtrer les données inutiles"; il ne sélectionne que les données nécessaires. Oui, bien sûr, si vous avez un index pour prendre en charge les colonnes identifiées dans la clause WHERE, c'est très rapide et la requête ne dépend pas de la taille de la table (saisir 1000 lignes d'une table de 16 milliards de lignes est instantané) .

  2. Votre table a un obstacle sérieux. Compte tenu de votre description, le PK réel est (Device, Metric, DateTime). (Veuillez ne pas l'appeler TimeStamp, cela signifie autre chose, mais c'est un problème mineur.) L'unicité de la ligne est identifiée par:

       (Device, Metric, DateTime)
    
    • La Idcolonne ne fait rien, elle est totalement et totalement redondante.

      • Une Idcolonne n'est jamais une clé (les lignes en double, qui sont interdites dans une base de données relationnelle, doivent être évitées par d'autres moyens).
      • La Idcolonne nécessite un index supplémentaire, ce qui entrave évidemment la vitesse de INSERT/DELETEet ajoute à l'espace disque utilisé.

      • Vous pouvez vous en débarrasser. S'il vous plaît.

Élévation

  1. Maintenant que vous avez supprimé l'obstacle, vous ne l'avez peut-être pas reconnu, mais votre table est en sixième forme normale. Très haute vitesse, avec un seul index sur le PK. Pour comprendre, lisez cette réponse dans Qu'est-ce que la sixième forme normale? aller de l'avant.

    • (J'ai un seul index, pas trois; sur les non-SQL, vous aurez peut-être besoin de trois index).

    • J'ai exactement la même table (sans la Id"clé", bien sûr). J'ai une colonne supplémentaire Server. J'assiste plusieurs clients à distance.

      (Server, Device, Metric, DateTime)

    Le tableau peut être utilisé pour faire pivoter les données (c.-à-d. En Deviceshaut et en Metricsbas sur le côté, ou pivoter) en utilisant exactement le même code SQL (oui, changer les cellules). J'utilise le tableau pour dresser une variété illimitée de graphiques et de tableaux pour les clients concernant les performances de leur serveur.

    • Surveiller le modèle de données statistiques .
      (Trop volumineux pour l'inline; certains navigateurs ne peuvent pas se charger en ligne; cliquez sur le lien. C'est également la version démo obsolète, pour des raisons évidentes, je ne peux pas vous montrer le produit commercial DM.)

    • Cela me permet de produire des graphiques comme celui-ci , six frappes après avoir reçu un fichier de statistiques de surveillance brutes du client, en utilisant une seule commande SELECT . Remarquez le mix-and-match; OS et serveur sur le même graphique; une variété de pivots. Bien sûr, il n'y a pas de limite au nombre de matrices de statistiques, et donc aux graphiques. (Utilisé avec l'aimable autorisation du client.)

    • Les lecteurs qui ne sont pas familiarisés avec la norme pour la modélisation des bases de données relationnelles peuvent trouver la notation IDEF1X utile.

Encore une chose

Enfin, SQL est une norme CEI / ISO / ANSI. Le logiciel gratuit est en fait non SQL; il est frauduleux d'utiliser le terme SQL s'ils ne fournissent pas la norme. Ils peuvent fournir des "extras", mais ils sont absents des bases.

PerformanceDBA
la source
1
@PerformanceDBA utiliseriez-vous le schéma suggéré pour une configuration qui doit gérer ~ 3 millions de mesures avec une fréquence d'une minute? Comment commanderais-tu le PK pour une telle table? Est-ce que Device, Metric, DateTime ne créeraient pas de fragmentation et forceraient le SGBDR à beaucoup de division de page? Au lieu de cela, mettre DateTime en premier réduirait la fragmentation (je suppose que les insertions sont ordonnées dans le temps) mais rendrait les lectures pires.
marcob
1
@ Boschi. J'utilise Sybase ASE. Mais ce n'est pas un problème de plate-forme (bien sûr, les plates-formes hautes offrent des performances d'un ordre de grandeur meilleures que le bas de gamme; trois ordres de grandeur mieux qu'Oracle, mais ce n'est pas le but), érection du graphique à partir du tableau " fonctionne "sur n'importe quelle plate-forme. Utilisez le bon outil pour le travail. Le SGBDR est un outil de base de données, pas un outil graphique. gnuplot, Apple Numbers (ou si vous aimez payer dix fois plus, pour moitié moins, MS Excel) sont des outils de création de graphiques, pas des outils de base de données. Ces jours-ci, nous utilisons des couches d'outils pour produire un résultat, le monolithe est un dinosaure.
PerformanceDBA
1
@marcob. Votre question est bonne, mais on ne peut pas y répondre correctement dans les commentaires. Si vous ouvrez une nouvelle question et que vous m'envoyez un courriel (allez au profil), je vais y répondre. Pour la réponse rapide ici. (1) ~ 3 millions de métriques. Génial, plus on est de fous, il répartit magnifiquement les points INSERT, le vôtre garantirait des conflits sur la dernière page. Le serveur est multi-thread, oui? Partitionnez la table. Utilisez FILLFACTOR et laissez de l'espace pour les insertions, évitez ainsi les fractionnements de page. (2) ~ 3 Mill indique que les métriques ne sont pas normalisées, si vous corrigez cela, ce sera encore plus rapide.
PerformanceDBA
1
@marcob. (3) J'utilise précisément l' index donné pour répartir les inserts sous charge, ce qui garantit l'absence de conflits. (4) Par conséquent, ma méthode obtient les deux insertions sans conflits et hautes performances sur les SELECT.
PerformanceDBA
2
@Loic. Pourquoi diable quelqu'un, qui a un investissement (données; code) dans une plate-forme SQL, qui gère les données de séries chronologiques facilement et avec des performances très élevées (comme détaillé dans la réponse), migrerait vers un TSDB sans SQL; vitesse inconnue pour autre chose que les données de séries chronologiques? Pourquoi quiconque a une exigence qui dépasse les données de séries chronologiques uniquement, n'utiliserait-il pas une plate-forme SQL? L'esprit est époustouflant. TSDB est plus rapide que Relational uniquement dans l'instance triste lorsque les données sont stockées dans une base de données mais pas normalisées Relationnellement. Par exemple. lorsque des Idcolonnes sont utilisées, comme "clés". Comme conseillé par les "théoriciens".
PerformanceDBA
21

J'ai trouvé très intéressantes les réponses ci-dessus. Essayer d'ajouter quelques considérations supplémentaires ici.

1) Vieillissement des données

La gestion des séries chronologiques doit généralement créer des politiques de vieillissement. Un scénario typique (par ex. CPU du serveur de surveillance) nécessite de stocker:

  • Échantillons bruts d'une seconde pendant une courte période (par exemple pendant 24 heures)

  • Échantillons agrégés détaillés de 5 minutes pour une période moyenne (par exemple 1 semaine)

  • Détails d'une heure sur cela (par exemple jusqu'à 1 an)

Bien que les modèles relationnels permettent à coup sûr (mon entreprise a mis en œuvre des bases de données centralisées massives pour certains gros clients avec des dizaines de milliers de séries de données) de la gérer de manière appropriée, la nouvelle génération de magasins de données ajoute des fonctionnalités intéressantes à explorer comme:

  • purge automatisée des données (voir la commande EXPIRE de Redis)

  • agrégations multidimensionnelles (par exemple, les tâches de réduction de carte a-la-Splunk)

2) Collecte en temps réel

Plus important encore, certains magasins de données non relationnels sont intrinsèquement distribués et permettent une collecte de données en temps réel (ou quasi-réel) beaucoup plus efficace qui pourrait poser problème avec le SGBDR en raison de la création de hotspots (gestion de l'indexation lors de l'insertion dans une seule table). Ce problème dans l'espace SGBDR est généralement résolu en revenant aux procédures d'importation par lots (nous l'avons géré de cette manière dans le passé) tandis que les technologies no-sql ont réussi à collecter et à agréger massivement en temps réel (voir Splunk par exemple, mentionné dans les réponses précédentes) .

Paolo Bozzola
la source
7

Votre table contient des données dans une seule table. Donc, relationnel vs non relationnel n'est pas la question. Fondamentalement, vous devez lire beaucoup de données séquentielles. Maintenant, si vous avez suffisamment de RAM pour stocker des données valant des années, rien de tel que d'utiliser Redis / MongoDB, etc.

La plupart des bases de données NoSQL stockeront vos données au même emplacement sur le disque et sous forme compressée pour éviter les accès multiples au disque.

NoSQL fait la même chose que la création de l'index sur l'identifiant de l'appareil et l'identifiant de la métrique, mais à sa manière. Avec la base de données, même si vous faites cela, l'index et les données peuvent être à des endroits différents et il y aurait beaucoup d'E / S disque.

Des outils tels que Splunk utilisent des backends NoSQL pour stocker des données de séries chronologiques, puis utilisent la réduction de carte pour créer des agrégats (ce que vous voudrez peut-être plus tard). Donc, à mon avis, utiliser NoSQL est une option car les gens l'ont déjà essayé pour des cas d'utilisation similaires. Mais un million de lignes amèneront-elles la base de données à explorer (peut-être pas, avec un matériel décent et des configurations appropriées).

Ravindra
la source
1
Pourriez-vous expliquer comment le tableau est «dé-normalisé»? Marcus a une erreur dans le tableau, mais ce n'est pas une erreur de normalisation.
PerformanceDBA
je vais me corriger, les tableaux sont normalisés au sens traditionnel. Je voulais dire dé-normalisé dans le sens où le cas d'utilisation contient toutes les données dans une table ici.
Ravindra
4

Créez un fichier, nommez-le 1_2.data. idée bizarre? ce que vous obtenez:

  • Vous économisez jusqu'à 50% d'espace car vous n'avez pas besoin de répéter les valeurs fk_to_device et fk_to_metric pour chaque point de données.
  • Vous économisez encore plus d'espace car vous n'avez besoin d'aucun index.
  • Enregistrez des paires de (timestamp, metric_value) dans le fichier en ajoutant les données afin d'obtenir une commande par horodatage gratuitement. (en supposant que vos sources n'envoient pas de données hors service pour un appareil)

=> Les requêtes par horodatage fonctionnent incroyablement vite car vous pouvez utiliser la recherche binaire pour trouver le bon endroit dans le fichier à lire.

si vous l'aimez encore plus optimisé, commencez à penser à diviser vos fichiers comme ça;

  • 1_2_janvier2014.data
  • 1_2_février2014.data
  • 1_2_march2014.data

ou utilisez kdb + de http://kx.com car ils font tout cela pour vous :) orienté colonnes est ce qui peut vous aider.

Une solution orientée colonnes basée sur le cloud apparaît, vous pouvez donc jeter un œil à: http://timeseries.guru

hellomichibye
la source
J'ai écrit un article de blog sur le sujet. avec google translate vous le trouverez peut-être utile: blog.michaelwittig.info/die-spaltenorientierte-datenbank-kdb
hellomichibye
3

Si vous recherchez des packages GPL, RRDTool est un bon outil à examiner. C'est un bon outil pour stocker, extraire et représenter graphiquement des données chronologiques. Votre cas d'utilisation ressemble exactement à des données de séries chronologiques.

sunil
la source
2

C'est un problème que nous avons dû résoudre chez ApiAxle. Nous avons rédigé un article de blog sur la façon dont nous l'avons fait en utilisant Redis. Il n'existe pas depuis très longtemps, mais il s'avère efficace.

J'ai également utilisé RRDTool pour un autre projet qui était excellent.

Phil Jackson
la source
2

Je pense que la réponse à ce genre de question devrait principalement concerner la manière dont votre base de données utilise le stockage. Certains serveurs de base de données utilisent la RAM et le disque, certains utilisent uniquement la RAM (éventuellement le disque pour la persistance), etc. Les solutions SQL Database les plus courantes utilisent la mémoire + le stockage sur disque et écrivent les données dans une disposition basée sur les lignes (chaque brut inséré est écrit dans le même emplacement physique). Pour les magasins de séries temporelles, dans la plupart des cas, la charge de travail est quelque chose comme: Intervalle relativement faible de quantité massive d'insertions, tandis que les lectures sont basées sur des colonnes (dans la plupart des cas, vous voulez lire une plage de données à partir d'une colonne spécifique, représentant une métrique)

J'ai trouvé que les bases de données en colonnes (google it, vous trouverez MonetDB, InfoBright, parAccel, etc.) font un travail formidable pour les séries chronologiques.

Quant à votre question, qui personnellement je pense est quelque peu invalide (comme toutes les discussions utilisant le terme d'erreur NoSQL - IMO): vous pouvez utiliser un serveur de base de données qui peut parler SQL d'une part, ce qui vous simplifie la vie car tout le monde connaît SQL pour beaucoup ans et ce langage a été perfectionné à maintes reprises pour les requêtes de données; mais utilisez toujours la RAM, le cache du processeur et le disque de manière orientée colonnes, ce qui rend votre solution la mieux adaptée aux séries chronologiques

Shay
la source
2

5 millions de lignes ne sont rien pour les données torrentielles d'aujourd'hui. Attendez-vous à ce que les données soient dans le TB ou le PB dans quelques mois seulement. À ce stade, le SGBDR ne s'adapte pas à la tâche et nous avons besoin de l'évolutivité linéaire des bases de données NoSql. Les performances seraient atteintes pour la partition en colonnes utilisée pour stocker les données, en ajoutant plus de colonnes et moins de lignes de concept pour améliorer les performances. Tirez parti du travail Open TSDB effectué par-dessus HBASE ou MapR_DB, etc.

Juan Asenjo
la source
«Les SGBDR ne s'adaptent pas à la tâche» - pourquoi ne le feraient-ils pas? code.facebook.com/posts/190251048047090/…
Zathrus Writer
1

Je suis régulièrement confronté à des exigences similaires et j'ai récemment commencé à utiliser Zabbix pour collecter et stocker ce type de données. Zabbix a sa propre capacité graphique, mais il est assez facile d'extraire les données de la base de données de Zabbix et de les traiter comme vous le souhaitez. Si vous n'avez pas encore vérifié Zabbix, cela vaut peut-être la peine de le faire.

monch1962
la source
Oui, Zabbix est sympa et s'intègre déjà à la surveillance SNMP. Zabbix peut utiliser MySQL ou PostgreSQL et fonctionne plus ou moins directement sur Ubuntu.
Dirk Eddelbuettel le
Merci, j'ai une connaissance de Zabbix et de nombreux autres outils SNMP. Cependant, je développe ce projet comme un processus éducatif, dans le sujet abordé ici et de nombreux autres aspects. Un bon point cependant!
Marcus Whybrow
0

Vous devriez regarder dans la base de données de séries chronologiques . Il a été créé dans ce but.

Une base de données de séries chronologiques (TSDB) est un système logiciel optimisé pour gérer des données de séries chronologiques, des tableaux de nombres indexés par heure (une date / heure ou une plage de date / heure).

Exemple populaire de base de données de séries chronologiques InfluxDB

Adam
la source
ajouter timescaledb à cette liste maintenant
PirateApp