web-dev-qa-db-fra.com

Stocker des données chronologiques, relationnelles ou non?

Je suis en train de créer un système qui interroge les périphériques pour obtenir des données sur différentes mesures, telles que l'utilisation du processeur, l'utilisation du disque, la température, etc. à des intervalles (probablement) de 5 minutes avec SNMP. Le but ultime est de fournir à l'utilisateur du système des visualisations sous forme de graphiques chronologiques.

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

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

Relationnel

Étant donné une base de données relationnelle, j'utiliserais un data_instances table, dans laquelle seraient stockées toutes les instances de données capturées pour chaque métrique mesurée pour tous les périphériques, avec les champs suivants:

Champs: idfk_to_devicefk_to_metricmetric_valuetimestamp

Lorsque je veux dessiner un graphique pour une métrique particulière sur un périphérique particulier, je dois interroger ce tableau singulier en filtrant les autres périphériques 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 cette table serait:

d * m_d * f * t

d est le nombre de périphériques, m_d est l'accumulateur nombre de métriques en cours d'enregistrement pour tous les périphériques, f est la fréquence à laquelle les données sont interrogées et t est la quantité totale de time le système a collecté des données.

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

Les index

Sans index sur fk_to_device et fk_to_metric numériser ce tableau en expansion constante prendrait trop de temps. Il est donc indispensable d’indexer les champs susmentionnés ainsi que timestamp (pour créer des graphiques avec des périodes localisées).

Non relationnel (NoSQL)

MongoDB a le concept d'une collection , contrairement aux tables, celles-ci peuvent être créées par programmation sans configuration. Avec ceux-ci je pourrais partitionner le stockage de données pour chaque périphérique, ou même chaque métrique enregistrée pour chaque périphérique.

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

Indécis

Une solution relationnelle avec une indexation correcte réduirait-elle votre analyse en un an? Ou bien la structure des approches NoSQL basée sur la collection (qui correspond au modèle mental des données stockées) offre-t-elle un avantage notable?

176
Marcus Whybrow

Vraiment relationnel. Flexibilité et expansion illimitées.

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

Correction

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

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

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

      • Une colonne Id n'est jamais une clé (les doublons, qui sont interdits dans une base de données relationnelle, doivent être évités par d'autres moyens).
      • La colonne Id requiert un index supplémentaire, ce qui empêche évidemment la vitesse de INSERT/DELETE, et 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 à partir de Qu'est-ce que la sixième forme normale? en avant?.

    • (Je n'ai qu'un 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. Je supporte plusieurs clients à distance.

      (Server, Device, Metric, DateTime)

    La table peut être utilisée pour faire pivoter les données (c.-à-d. Devices en haut et Metrics en bas, ou en les faisant pivoter) en utilisant exactement le même code SQL (oui, changez de cellule). J'utilise ce tableau pour créer une variété illimitée de graphiques et de graphiques destinés aux clients concernant les performances de leur serveur.

    • Modèle de données statistiques du moniteur .
      ]

    • Cela me permet de produire des graphiques comme celui-ci , six frappes au clavier après la réception d'un fichier de statistiques de surveillance brutes du client, à l'aide d'un single Commande SELECT. Notez le mix-and-match; OS et serveur sur le même graphique; une variété de pivots. Bien entendu, 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 familiers avec la norme de modélisation de bases de données relationnelles peuvent trouver utile Notation IDEF1X .

Encore une chose

Dernier point mais non le moindre, 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.

149
PerformanceDBA

Trouvé très intéressant 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 stratégies de vieillissement. Un scénario typique (par exemple, le processeur du serveur de surveillance) nécessite de stocker:

  • 1 sec échantillons bruts pendant une courte période (par exemple, pendant 24 heures)

  • 5 min détailler les échantillons globaux pour une période moyenne (par exemple, une semaine)

  • 1 heure plus de détails à ce sujet (par exemple, jusqu'à un an)

Bien que les modèles relationnels permettent à coup sûr (ma société a mis en œuvre d’énormes bases de données centralisées pour certains gros clients disposant de 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 telles que:

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

  • agrégations multidimensionnelles (par exemple, les travaux de carte-réduction à la Splunk)

2) Collection en temps réel

Plus important encore, certains magasins de données non relationnels sont distribués de manière inhérente et permettent une collecte de données beaucoup plus efficace en temps réel (ou presque) qui pourrait poser problème avec le SGBDR en raison de la création de points chauds (gestion de l'indexation lors de l'insertion) une seule table). Ce problème dans l'espace du SGBDR est généralement résolu en revenant à des 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 à rassembler et à agréger en temps réel de manière massive (voir Splunk par exemple, mentionné dans les réponses précédentes). .

19
Paolo Bozzola

Votre table a 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 assez RAM pour stocker des années de données, rien de tel que d’utiliser Redis/MongoDB, etc.

Généralement, les bases de données NoSQL stockent vos données au même emplacement sur le disque et sous une forme compressée pour éviter les accès multiples au disque.

NoSQL fait la même chose que créer l'index sur l'ID de périphérique et l'ID de 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 se trouver à différents endroits et il y aurait beaucoup d'entrées/sorties sur disque.

Des outils tels que Splunk utilisent des systèmes NoSQL pour stocker des données de série temporelle, puis utilisent Map Réduire pour créer des agrégats (ce qui pourrait être ce que vous souhaiterez 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 entraîneront-elles l’exploration de la base de données (peut-être pas, avec un matériel correct et des configurations appropriées).

7
Ravindra

Créez un fichier, nommez-le 1_2.data. weired idée? 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 que vous obteniez une commande par horodatage gratuitement. (en supposant que vos sources n'envoient pas de données hors service pour un périphérique)

=> Les requêtes par horodatage sont extrêmement rapides car vous pouvez utiliser la recherche binaire pour trouver le bon emplacement dans le fichier à lire.

si vous l'aimez encore plus, commencez à songer à diviser vos fichiers de cette manière;

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

ou utilisez kdb + à partir de http://kx.com car ils font tout cela pour vous :) la colonne est ce qui peut vous aider.

Une solution basée sur les colonnes et basée sur le cloud fait son apparition. Vous voudrez peut-être jeter un coup d'œil à: http://timeseries.gur

4
hellomichibye

Si vous regardez les paquets GPL, RRDTool est un bon exemple. C'est un bon outil pour stocker, extraire et représenter graphiquement des données chronologiques. Votre cas d'utilisation ressemble exactement aux données de série chronologique.

3
sunil

C'est un problème que nous avons eu à résoudre chez ApiAxle. Nous avons écrit un article de blog sur la façon dont nous l'avons fait avec Redis. Cela ne fait pas longtemps que ça existe, mais cela s'avère efficace.

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

2
Phil Jackson

Je pense que la réponse à ce type de question devrait principalement porter sur la manière dont votre base de données utilise le stockage. Certains serveurs de base de données utilisent RAM et disque, d'autres = RAM uniquement (éventuellement Disk pour la persistance)), etc. La plupart des solutions de base de données SQL courantes utilisent de la mémoire + disque et écrit les données dans une mise en page basée sur les lignes (chaque raw inséré est écrit au même emplacement physique) Pour les magasins de séries temporelles, dans la plupart des cas, la charge de travail ressemble à peu près à: Intervalle relativement bas de quantités massives d'insertions, tandis que les lectures sont basées sur des colonnes (dans la plupart des cas, vous souhaitez lire une plage de données d'une colonne spécifique, représentant une métrique)

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

Pour ce qui est de votre question, je pense personnellement qu’elle est quelque peu invalide (comme toutes les discussions utilisant le terme de faute NoSQL - IMO): Vous pouvez utiliser un serveur de base de données pouvant parler SQL d’une part, ce qui vous rend la vie très facile, tout le monde connaissant SQL pour beaucoup ans et cette langue a été perfectionnée à plusieurs 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, pour adapter votre solution au mieux aux séries chronologiques

2
Shay

5 millions de lignes, ce n'est rien pour les données torrentielles d'aujourd'hui. Attendez-vous à ce que les données se trouvent dans TB ou PB dans quelques mois seulement). À ce stade, les SGBDR ne sont pas à la hauteur de la tâche et nous avons besoin de l'évolutivité linéaire des bases de données NoSql. Partition en colonnes utilisée pour stocker les données, en ajoutant plus de colonnes et moins de lignes, type de concept permettant d'optimiser les performances.

2
Juan Asenjo

Je suis régulièrement confronté à des exigences similaires et, récemment, j'ai 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 bon vous semble. Si vous n'avez pas encore vérifié Zabbix, vous jugerez peut-être intéressant de le faire.

1
monch1962

Vous devriez examiner base de données de séries chronologiques . Il a été créé à cet effet.

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

Exemple populaire de base de données chronologique InfluxDB

0
Adam