Stockage des métriques : comment nous sommes passés de Graphite+Whisper à Graphite+ClickHouse

Salut tout le monde! Dans son dernier article J'ai écrit sur l'organisation d'un système de surveillance modulaire pour l'architecture des microservices. Rien ne s'arrête, notre projet ne cesse de croître, tout comme le nombre de métriques stockées. Comment nous avons organisé la transition de Graphite+Whisper vers Graphite+ClickHouse dans des conditions de charge élevée, découvrez les attentes et les résultats de la migration sous la coupe.

Stockage des métriques : comment nous sommes passés de Graphite+Whisper à Graphite+ClickHouse

Avant de vous expliquer comment nous avons organisé la transition du stockage des métriques dans Graphite+Whisper vers Graphite+ClickHouse, je voudrais donner des informations sur les raisons d'une telle décision et sur les inconvénients de Whisper avec lequel nous avons vécu pendant longtemps.

Problèmes de graphite + murmure

1. Charge élevée sur le sous-système de disque

Au moment de la transition, environ 1.5 million de mesures nous parvenaient par minute. Avec un tel flux, l'utilisation des disques sur les serveurs était d'environ 30 %. En général, c'était tout à fait acceptable - tout fonctionnait de manière stable, était écrit rapidement, lu rapidement... Jusqu'à ce qu'une des équipes de développement déploie une nouvelle fonctionnalité et commence à nous envoyer 10 millions de métriques par minute. C’est à ce moment-là que le sous-système de disque s’est resserré et que nous avons constaté une utilisation à 100 %. Le problème a été rapidement résolu, mais il restait un résidu.

2. Manque de réplication et de cohérence

Très probablement, comme tous ceux qui utilisent/ont utilisé Graphite+Whisper, nous avons versé le même flux de métriques sur plusieurs serveurs Graphite à la fois afin de créer une tolérance aux pannes. Et cela n'a posé aucun problème particulier - jusqu'au moment où l'un des serveurs est tombé en panne pour une raison quelconque. Parfois, nous avons réussi à récupérer un serveur tombé en panne assez rapidement, et carbon-c-relay a réussi à y charger les métriques de son cache, mais parfois non. Et puis il y a eu un trou dans les métriques, que nous avons comblé avec rsync. La procédure a été assez longue. La seule grâce salvatrice était que cela se produisait très rarement. Nous avons également périodiquement pris un ensemble aléatoire de métriques et les avons comparées avec d'autres du même type sur les nœuds voisins du cluster. Dans environ 5% des cas, plusieurs valeurs étaient différentes, ce qui ne nous plaisait pas beaucoup.

3. Grande empreinte

Puisque nous écrivons dans Graphite non seulement l'infrastructure, mais aussi les métriques commerciales (et maintenant aussi les métriques de Kubernetes), nous nous retrouvons assez souvent dans une situation dans laquelle la métrique ne contient que quelques valeurs et le fichier .wsp est créé en tenant compte de toutes les rétentions. période et occupe une quantité d'espace pré-alloué, qui pour nous était d'environ 2 Mo. Le problème est encore aggravé par le fait que de nombreux fichiers similaires apparaissent au fil du temps et que lors de la création de rapports sur eux, la lecture de points vides prend beaucoup de temps et de ressources.

Je voudrais immédiatement noter que les problèmes décrits ci-dessus peuvent être résolus par diverses méthodes et avec différents degrés d'efficacité, mais plus vous commencez à recevoir de données, plus elles s'aggravent.

Ayant tout ce qui précède (en tenant compte du précédent articles), ainsi qu'une augmentation constante du nombre de métriques reçues, la volonté de transférer toutes les métriques dans un intervalle de stockage de 30 secondes. (jusqu'à 10 secondes si nécessaire), nous avons décidé d'essayer Graphite+ClickHouse comme alternative prometteuse à Whisper.

Graphite+ClickHouse. Attentes

Après avoir visité plusieurs rencontres de gars de Yandex, après avoir lu quelques articles sur Habré, après avoir parcouru la documentation et trouvé des composants sains pour lier ClickHouse sous Graphite, nous avons décidé d'agir !

Je souhaite recevoir ce qui suit :

  • réduire l'utilisation du sous-système de disque de 30 % à 5 % ;
  • réduire la quantité d'espace occupé de 1 To à 100 Go ;
  • être capable de recevoir 100 millions de métriques par minute sur le serveur ;
  • réplication des données et tolérance aux pannes prêtes à l'emploi ;
  • ne restez pas assis sur ce projet pendant un an et effectuez la transition dans un délai raisonnable ;
  • commutateur sans temps d'arrêt.

Assez ambitieux, non ?

Graphite+ClickHouse. Composants

Pour recevoir des données via le protocole Graphite et les enregistrer ensuite dans ClickHouse, j'ai sélectionné carbone-clickhouse (golang).

La dernière version de ClickHouse, la version stable 1.1.54253, a été choisie comme base de données pour stocker les séries chronologiques. Il y avait des problèmes lors de son utilisation : une montagne d'erreurs se déversait dans les journaux, et il n'était pas tout à fait clair quoi en faire. En discussion avec Romain Lomonossov (auteur de carbon-clickhouse, graphite-clickhouse et bien d'autres), le plus ancien a été choisi version 1.1.54236. Les erreurs ont disparu - tout a commencé à fonctionner en trombe.

Sélectionné pour lire les données de ClickHouse graphite-lickhouse (golang). En tant qu'API pour Graphite - carbonapi (golang). ClickHouse a été utilisé pour organiser la réplication entre les tables gardien de zoo. Pour les métriques de routage, nous avons laissé notre bien-aimé carbone-c-relais (C) (voir article précédent).

Graphite+ClickHouse. Structure du tableau

« graphite » est une base de données que nous avons créée pour surveiller les tables.

"graphite.metrics" - table avec moteur ReplicatedReplacingMergeTree (répliqué Remplacement de MergeTree). Ce tableau stocke les noms des métriques et les chemins d'accès à celles-ci.

CREATE TABLE graphite.metrics ( Date Date, Level UInt32, Path String, Deleted UInt8, Version UInt32 ) ENGINE = ReplicatedReplacingMergeTree('/clickhouse/tables/replicator/graphite.metrics', ‘r1’, Date, (Level, Path), 8192, Version);

"graphite.data" - table avec moteur ReplicatedGraphiteMergeTree (répliqué GraphiteMergeTree). Ce tableau stocke les valeurs de métriques.

CREATE TABLE graphite.data ( Path String, Value Float64, Time UInt32, Date Date, Timestamp UInt32 ) ENGINE = ReplicatedGraphiteMergeTree('/clickhouse/tables/replicator/graphite.data', 'r1', Date, (Path, Time), 8192, 'graphite_rollup')

« graphite.date_metrics » est une table remplie de manière conditionnelle avec le moteur ReplicatedReplacingMergeTree. Ce tableau enregistre les noms de toutes les métriques rencontrées au cours de la journée. Les raisons de sa création sont décrites dans la section "Problèmes" à la fin de cet article.

CREATE MATERIALIZED VIEW graphite.date_metrics ( Path String,  Level UInt32,  Date Date) ENGINE = ReplicatedReplacingMergeTree('/clickhouse/tables/replicator/graphite.date_metrics', 'r1', Date, (Level, Path, Date), 8192) AS SELECT toUInt32(length(splitByChar('.', Path))) AS Level, Date, Path FROM graphite.data

"graphite.data_stat" - une table remplie selon la condition, avec le moteur ReplicatedAggregatingMergeTree (répliqué AgrégationMergeTree). Ce tableau enregistre le nombre de métriques entrantes, réparties en 4 niveaux d'imbrication.

CREATE MATERIALIZED VIEW graphite.data_stat ( Date Date,  Prefix String,  Timestamp UInt32,  Count AggregateFunction(count)) ENGINE = ReplicatedAggregatingMergeTree('/clickhouse/tables/replicator/graphite.data_stat', 'r1', Date, (Timestamp, Prefix), 8192) AS SELECT toStartOfMonth(now()) AS Date, replaceRegexpOne(Path, '^([^.]+.[^.]+.[^.]+).*$', '1') AS Prefix, toUInt32(toStartOfMinute(toDateTime(Timestamp))) AS Timestamp, countState() AS Count FROM graphite.data  GROUP BY Timestamp, Prefix

Graphite+ClickHouse. Diagramme d'interaction des composants

Stockage des métriques : comment nous sommes passés de Graphite+Whisper à Graphite+ClickHouse

Graphite+ClickHouse. Migration de données

Comme nous nous en souvenons des attentes de ce projet, la transition vers ClickHouse devait se faire sans temps d'arrêt ; par conséquent, nous avons dû d'une manière ou d'une autre basculer l'ensemble de notre système de surveillance vers le nouveau stockage de la manière la plus transparente possible pour nos utilisateurs.
C'est ainsi que nous avons procédé.

  • Une règle a été ajoutée à carbon-c-relay pour envoyer un flux supplémentaire de métriques au carbon-clickhouse d'un des serveurs participant à la réplication des tables ClickHouse.

  • Nous avons écrit un petit script en python qui, à l'aide de la bibliothèque Whisper-Dump, a lu tous les fichiers .wsp de notre stockage et a envoyé ces données au carbon-clickhouse décrit ci-dessus en 24 threads. Le nombre de valeurs métriques acceptées dans carbon-clickhouse a atteint 125 millions/min, et ClickHouse n'a même pas transpiré.

  • Nous avons créé une DataSource distincte dans Grafana pour déboguer les fonctions utilisées dans les tableaux de bord existants. Nous avons identifié une liste de fonctions que nous avons utilisées, mais elles n'ont pas été implémentées dans carbonapi. Nous avons ajouté ces fonctions et envoyé des PR aux auteurs de carbonapi (un merci spécial à eux).

  • Pour changer la charge de lecture dans les paramètres de l'équilibreur, nous avons modifié les points de terminaison de graphite-api (interface API pour Graphite+Whisper) en carbonapi.

Graphite+ClickHouse. résultats

  • utilisation réduite du sous-système de disque de 30 % à 1 % ;

    Stockage des métriques : comment nous sommes passés de Graphite+Whisper à Graphite+ClickHouse

  • réduit la quantité d'espace occupé de 1 To à 300 Go ;
  • nous avons la capacité de recevoir 125 millions de métriques par minute sur le serveur (pics au moment de la migration) ;
  • transféré toutes les métriques vers un intervalle de stockage de trente secondes ;
  • réplication des données reçues et tolérance aux pannes ;
  • commuté sans temps d'arrêt ;
  • Il a fallu environ 7 semaines pour tout terminer.

Graphite+ClickHouse. Problèmes

Dans notre cas, il y a eu quelques écueils. C'est ce que nous avons rencontré après la transition.

  1. ClickHouse ne relit pas toujours les configurations à la volée ; il faut parfois le redémarrer. Par exemple, dans le cas de la description du cluster zookeeper dans la configuration ClickHouse, il n'a été utilisé qu'après le redémarrage du serveur clickhouse.
  2. Les requêtes ClickHouse volumineuses n'ont pas abouti, donc dans graphite-clickhouse, notre chaîne de connexion ClickHouse ressemble à ceci :
    url = "http://localhost:8123/?max_query_size=268435456&max_ast_elements=1000000"
  3. ClickHouse publie assez souvent de nouvelles versions de versions stables ; elles peuvent contenir des surprises : soyez prudent.
  4. Les conteneurs créés dynamiquement dans Kubernetes envoient un grand nombre de métriques avec une durée de vie courte et aléatoire. Il n'y a pas beaucoup de points pour de telles métriques et il n'y a aucun problème d'espace. Mais lors de la création de requêtes, ClickHouse récupère un grand nombre de ces mêmes métriques dans le tableau « métriques ». Dans 90 % des cas, il n’existe aucune donnée les concernant au-delà de la fenêtre (24 heures). Mais du temps est passé à rechercher ces données dans la table « données », et finit par atteindre un délai d'attente. Afin de résoudre ce problème, nous avons commencé à conserver une vue séparée avec des informations sur les métriques rencontrées au cours de la journée. Ainsi, lors de la création de rapports (graphiques) pour des conteneurs créés dynamiquement, nous interrogeons uniquement les métriques rencontrées dans une fenêtre donnée, et non pour toute la durée, ce qui a considérablement accéléré la construction de rapports sur celles-ci. Pour la solution décrite ci-dessus, j'ai collecté graphite-clickhouse (fourche), qui inclut l'implémentation de l'utilisation de la table date_metrics.

Graphite+ClickHouse. Mots clés

Avec la version 1.1.0, Graphite est devenu officiel balises de support. Et nous réfléchissons activement à quoi et comment faire pour soutenir cette initiative dans la pile graphite+clickhouse.

Graphite+ClickHouse. Détecteur d'anomalies

Sur la base de l'infrastructure décrite ci-dessus, nous avons implémenté un prototype de détecteur d'anomalies, et ça marche ! Mais nous en saurons davantage dans le prochain article.

Abonnez-vous, appuyez sur la flèche vers le haut et soyez heureux !

Source: habr.com

Ajouter un commentaire