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

Bonjour à tous ! Dans mon Dans notre précédent article, je parlais de l'organisation d'un systÚme de surveillance modulaire pour une architecture microservices. Rien ne reste immobile, notre projet est en constante expansion, tout comme le nombre de métriques stockées. Comment nous avons organisé la transition de Graphite+Whisper à Graphite+ClickHouse dans des conditions de forte charge, nos attentes à cet égard et les résultats de la migration se lisent ci-dessous.

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 de Graphite+Whisper à Graphite+ClickHouse, je voudrais donner des informations sur les raisons qui ont conduit à une telle décision et sur les inconvénients de Whisper avec lesquels nous avons vécu pendant une longue période.

ProblĂšmes avec Graphite+Whisper

1. Charge élevée sur le systÚme de disque

Au moment de la transition, nous recevions environ 1,5 million de mĂ©triques par minute. Avec ce flux, l'utilisation des disques sur les serveurs Ă©tait d'environ 30 %. Dans l'ensemble, c'Ă©tait tout Ă  fait acceptable — tout fonctionnait de maniĂšre stable, les Ă©critures Ă©taient rapides, les lectures aussi
 Jusqu'Ă  ce qu'une des Ă©quipes de dĂ©veloppement ne dĂ©ploie une nouvelle fonctionnalitĂ© et ne commence Ă  nous envoyer 10 millions de mĂ©triques par minute. C'est Ă  ce moment-lĂ  que le systĂšme de disque a commencĂ© Ă  s'engorger, et nous avons vu une utilisation Ă  100 %. Le problĂšme a pu ĂȘtre rĂ©solu rapidement, mais la mauvaise expĂ©rience est restĂ©e.

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

Comme beaucoup de ceux qui utilisent/ont utilisĂ© Graphite+Whisper, nous envoyions le mĂȘme flux de mĂ©triques Ă  plusieurs serveurs Graphite pour crĂ©er de la redondance. Cela ne posait pas de problĂšmes majeurs — jusqu'Ă  ce qu'un des serveurs tombe pour une raison quelconque. Parfois, nous parvenions Ă  redĂ©marrer le serveur tombĂ© assez rapidement, et carbon-c-relay pouvait lui envoyer les mĂ©triques de son cache, parfois non. Et Ă  ce moment-lĂ , il y avait un trou dans les mĂ©triques, que nous remplissions avec rsync. La procĂ©dure Ă©tait assez longue. La seule chose qui nous sauvait, c'est que ces incidents Ă©taient trĂšs rares. De plus, nous prenions pĂ©riodiquement un ensemble alĂ©atoire de mĂ©triques et les comparions avec d'autres similaires sur les nƓuds voisins du cluster. Environ 5 % des cas rĂ©vĂ©laient des diffĂ©rences, ce qui ne nous rĂ©jouissait pas.

3. Grand volume d'espace occupé

Étant donnĂ© que nous Ă©crivons dans Graphite non seulement des mĂ©triques d'infrastructure, mais aussi des mĂ©triques commerciales (et maintenant des mĂ©triques provenant de Kubernetes), nous nous trouvons souvent dans une situation oĂč la mĂ©trique ne contient que quelques valeurs, et le fichier .wsp est créé en tenant compte de toute la pĂ©riode de rĂ©tention, occupant ainsi un espace prĂ©dĂ©fini qui Ă©tait d'environ 2 Mo. Le problĂšme est aggravĂ© par le fait que de tels fichiers apparaissent en grande quantitĂ© avec le temps, et lors de la gĂ©nĂ©ration de rapports basĂ©s sur eux, le temps et les ressources nĂ©cessaires pour lire les points vides sont considĂ©rables.

Il convient de noter dĂšs le dĂ©part que les problĂšmes dĂ©crits ci-dessus peuvent ĂȘtre combattus par divers moyens et avec des degrĂ©s d'efficacitĂ© variĂ©s, mais plus vous recevez de donnĂ©es, plus ils s'aggravent.

Ayant tout ce qui précÚde (en tenant compte de précédents article), ainsi que la croissance constante du nombre de métriques reçues, le désir de réduire l'intervalle de conservation de toutes les métriques à 30 secondes (et si nécessaire, à 10 secondes), nous avons décidé d'essayer Graphite+ClickHouse comme alternative prometteuse à Whisper.

Graphite+ClickHouse. Attentes

AprÚs avoir assisté à plusieurs meetups des gars de Yandex, lu quelques articles sur Habré, fouillé la documentation et trouvé des composants raisonnables pour intégrer ClickHouse à Graphite, nous avons décidé de passer à l'action !

Nous voulions obtenir ce qui suit :

  • rĂ©duire l'utilisation du sous-systĂšme de disque de 30% Ă  5%;
  • rĂ©duire l'espace occupĂ© de 1 To Ă  100 Go;
  • avoir la capacitĂ© d'accepter 100 millions de mĂ©triques par minute sur le serveur;
  • rĂ©plication des donnĂ©es et tolĂ©rance aux pannes par dĂ©faut;
  • ne pas passer une annĂ©e sur ce projet et effectuer la transition dans un dĂ©lai raisonnable;
  • changer sans temps d'arrĂȘt.

Assez ambitieux, n'est-ce pas ?

Graphite+ClickHouse. Composants

Pour recevoir des données via le protocole Graphite et les enregistrer par la suite dans ClickHouse, le choix s'est porté sur carbon-clickhouse (golang).

Comme base de donnĂ©es pour le stockage des sĂ©ries temporelles, la derniĂšre version stable de ClickHouse Ă  ce moment-lĂ , la version 1.1.54253, a Ă©tĂ© choisie. Lors de son utilisation, des problĂšmes ont surgi : une multitude d'erreurs Ă©taient gĂ©nĂ©rĂ©es dans les journaux, et il n'Ă©tait pas tout Ă  fait clair comment y faire face. Dans une discussion avec Roman Lomonosov (auteur de carbon-clickhouse, graphite-clickhouse et bien d'autres), une version plus ancienne la version 1.1.54236. Les erreurs ont disparu – tout a commencĂ© Ă  fonctionner Ă  merveille.

Pour lire les donnĂ©es Ă  partir de ClickHouse, nous avons choisi graphite-slickhouse (golang). En tant qu'interface API pour Graphite – carbonapi (golang). Pour organiser la rĂ©plication entre les tables ClickHouse, nous avons utilisĂ© zookeeper. Pour le routage des mĂ©triques, nous avons gardĂ© notre cher carbon-c-relay (C) (voir l'article prĂ©cĂ©dent).

Graphite+ClickHouse. Structure des tables

«graphite» — une base de donnĂ©es que nous avons créée pour les tables de surveillance.

«graphite.metrics» — table avec le moteur ReplicatedReplacingMergeTree (rĂ©pliquĂ© ReplacingMergeTree). Dans cette table, sont stockĂ©s les noms des mĂ©triques et les chemins vers 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 le moteur ReplicatedGraphiteMergeTree (rĂ©pliquĂ© GraphiteMergeTree). Dans cette table, sont stockĂ©es les valeurs des 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» — table remplie selon condition, avec le moteur ReplicatedReplacingMergeTree. Dans cette table, sont enregistrĂ©s 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» — table remplie selon condition, avec le moteur ReplicatedAggregatingMergeTree (rĂ©pliquĂ© AggregatingMergeTree). Dans cette table, est enregistrĂ© le nombre de mĂ©triques entrantes, avec une rĂ©partition jusqu'au 4e niveau de profondeur.

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. Schéma d'interaction des composants

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

Graphite+ClickHouse. Migration des données

Comme nous nous en souvenons des attentes pour ce projet, la transition vers ClickHouse doit se faire sans temps d'arrĂȘt, par consĂ©quent, nous devions en quelque sorte basculer tout notre systĂšme de surveillance vers le nouveau stockage de maniĂšre aussi transparente que possible pour nos utilisateurs.
Nous l'avons fait de cette façon.

  • Dans carbon-c-relay, nous avons ajoutĂ© une rĂšgle pour envoyer un flux supplĂ©mentaire de mĂ©triques Ă  carbon-clickhouse l'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 flux. Le nombre de valeurs mĂ©triques acceptĂ©es dans carbon-clickhouse atteignait 125 millions par minute, et ClickHouse n'a mĂȘme pas transpirĂ©.

  • Nous avons créé une source de donnĂ©es 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 qui n'Ă©taient pas implĂ©mentĂ©es dans le carbonapi. Nous avons Ă©crit ces fonctions et envoyĂ© des PR aux auteurs de carbonapi (un grand merci Ă  eux).

  • Pour basculer la charge de lecture, nous avons modifiĂ© les points d'extrĂ©mitĂ© dans la configuration des Ă©quilibreurs de charge, passant de graphite-api (interface API pour Graphite+Whisper) Ă  carbonapi.

Graphite+ClickHouse. Résultats

  • nous avons rĂ©duit l'utilisation du systĂšme de disque de 30% Ă  1%;

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

  • nous avons rĂ©duit l'espace occupĂ© de 1 To Ă  300 Go;
  • nous avons la capacitĂ© d'accepter 125 millions de mĂ©triques par minute sur le serveur (pics lors de la migration);
  • nous avons transfĂ©rĂ© toutes les mĂ©triques Ă  un intervalle de stockage de 30 secondes;
  • nous avons obtenu la rĂ©plication des donnĂ©es et la tolĂ©rance aux pannes;
  • nous avons basculĂ© sans temps d'arrĂȘt;
  • nous avons dĂ©pensĂ© environ 7 semaines au total.

Graphite+ClickHouse. ProblĂšmes

Dans notre cas, nous avons également rencontré des écueils. Voici ce à quoi nous avons été confrontés aprÚs la migration.

  1. ClickHouse ne relit pas toujours les configurations Ă  la volĂ©e, il faut parfois le redĂ©marrer. Par exemple, pour la description du cluster zookeeper dans la configuration de ClickHouse — elle n'Ă©tait pas appliquĂ©e avant le redĂ©marrage de clickhouse-server.
  2. Les grandes requĂȘtes ClickHouse ne passaient donc pas, ce qui fait que notre connexion graphite-clickhouse Ă  ClickHouse ressemble Ă  ceci :
    url = "http://localhost:8123/?max_query_size=268435456&max_ast_elements=1000000"
  3. De nouvelles versions stables de ClickHouse sortent assez souvent, et elles peuvent apporter des surprises : restez vigilant.
  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 ces mĂ©triques, et il n'y a pas de problĂšme d'espace. Toutefois, lors de la construction des requĂȘtes, ClickHouse rĂ©cupĂšre un Ă©norme volume de ces mĂ©triques de la table ‘metrics’. Dans 90 % des cas, les donnĂ©es pour celles-ci sont absentes sur la pĂ©riode (24 heures). La recherche de ces donnĂ©es dans la table ‘data’ prend nĂ©anmoins du temps et finit par atteindre un timeout. Pour rĂ©soudre ce problĂšme, nous avons commencĂ© Ă  tenir une vue distincte avec des informations sur les mĂ©triques rencontrĂ©es au cours de la journĂ©e. Ainsi, lors de l'Ă©laboration de rapports (graphes) sur les conteneurs créés dynamiquement, nous interrogeons uniquement les mĂ©triques qui ont Ă©tĂ© rencontrĂ©es dans la fenĂȘtre spĂ©cifiĂ©e, et non pas pendant toute la durĂ©e, ce qui a accĂ©lĂ©rĂ© considĂ©rablement la crĂ©ation des rapports Ă  leur sujet. Pour la solution dĂ©crite ci-dessus, nous avons dĂ©veloppĂ© graphite-clickhouse (fork), incluant la mise en Ɠuvre du travail avec la table date_metrics.

Graphite+ClickHouse. Tags

Depuis la version 1.1.0, Graphite a officiellement pris en charge les tags. Et nous réfléchissons activement à ce qu'il faut 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 réalisé un prototype de détecteur d'anomalies, et il fonctionne ! Mais nous en parlerons dans le prochain article.

Abonnez-vous, cliquez sur la flĂšche vers le haut et soyez heureux !

Source : habr.com

Acheter un hĂ©bergement fiable pour les sites avec protection DDoS, serveurs VPS VDS đŸ”„ Acheter un hĂ©bergement fiable pour les sites avec protection DDoS, serveurs VPS VDS | ProHoster