En peu de temps, Prometheus est devenu l'un des outils de surveillance les plus populaires. Merci en particulier et la rapidité de son travail. Son stockage local est idéal pour le stockage à court terme des métriques et travailler avec eux. Parfois, vous souhaitez conserver les métriques distribuées pendant des mois et des années, en coupant automatiquement les anciennes données, mais sans changer l'interface pour travailler avec elles.
À peu près à ce sujet, le décodage du rapport par Alexey Palazhchenko à RootConf 2018. Dans le rapport: Prometheus, Local Storage TSDB, Remote Storage Prometheus, PromQL, TSDB, Clickhouse, PromHouse, un petit InfluxDB.
Peu importe, s'il vous plaît, sous le chat.
Mes amis! Bonjour à tous! Je m'appelle Alexey Palazhchenko. Je travaille à Percona. Je voudrais vous parler du stockage à long terme des métriques dans Prometheus.

Je travaille chez Percona et je fabrique un produit appelé surveillance et gestion percona. Il s'agit de la solution en boîte que nos clients se sont fixée. PMM est entièrement open source. Il se compose de Prometheus, Grafana pour la représentation graphique, d'un logiciel d'analyse de requêtes personnalisé et de notre propre wrapper qui vous permet de faire de la gestion. Par exemple, vous pouvez ajouter une cible de raclage à Prometheus. Ce sont de nouvelles sources d'où il prendra des métriques sans avoir à entrer manuellement un conteneur ou une machine virtuelle et éditer le fichier de configuration.
Il est important de comprendre qu'il ne s'agit pas de SaaS. Nous n'avons pas de production. Notre production se situe chez nos clients. L'expérimenter n'est pas très bon. Nous avons la chose la plus proche qui pourrait être appelée production - c'est https://pmmdemo.percona.com/ . Au moment du rapport, pmmdemo.percona.com a dû être fermé en raison du RGPD.
Nous livrons PMM aux clients - une solution en boîte: un conteneur Docker ou une machine virtuelle. Ils aiment tous Prométhée. Certaines personnes qui regardent Prometheus pour la première fois rencontrent un modèle pull. Pour les débutants, cela n'est pas pratique. Généralement une grande conversation séparée. Vous pouvez discuter des méthodes pull ou push. En moyenne, c'est à peu près la même chose.
Certaines choses dans Prométhée sont très cool.
Le langage de requête Prometheus est vraiment une chose sympa qui n'a aucun analogue nulle part.
La deuxième chose que vous aimez est la découverte de services. Si vous avez une sorte d'infrastructure dynamique, kubernetes, alors automatiquement, vous n'avez pas besoin d'ajouter toutes les cibles à surveiller avec vos mains. Si statique - cela peut aussi être fait tout simplement. Vous devez utiliser le fichier de configuration.
Les clients de Prometheus aiment ça. Ils veulent garder les métriques de plus en plus longtemps. Quelqu'un utilise Prometheus pour la surveillance opérationnelle uniquement. Mais quelqu'un veut garder les métriques plus longtemps, regarder la dynamique, comparer avec les graphiques d'il y a un an. Dans le même temps, l'objectif du stockage à long terme des métriques n'est pas l'objectif du projet Prometheus. Initialement, il a été créé afin de stocker les métriques pendant une courte période. SoundCloud stocke les mesures en quelques jours seulement. Il existe des mécanismes dans Prométhée qui vous permettent de le faire plus longtemps, mais ils sont disposés un peu sur le côté. Par conséquent, nous pouvons prendre une décision pour l'écosystème Prometheus sans changer le cœur du système lui-même. Sur cette base, nous pouvons prendre notre propre décision au sein du même écosystème.

Ce n'est pas un rapport sur des solutions toutes faites. Ceci est un rapport sur notre expérience, sur notre douleur, sur nos tentatives. Si vous vous attendiez à ce qu'après ce rapport, vous téléchargiez le référentiel ou le conteneur Docker, l'exécutiez et cela fonctionnera, ce n'est pas le cas. Mais en même temps, c'est assez proche pour l'être. Nous avons quelques bases. Ils sont tous open source. Vous pouvez essayer. Ils ne sont pas encore prêts pour la production. Mais avec les informations contenues dans ce rapport, vous pouvez comprendre pourquoi, donc ce qui peut être mieux fait. Vous pouvez prendre votre propre décision qui vous convient.

Comment les métriques sont-elles stockées dans Prometheus? Il y a un stockage local. Il y a du stockage à distance. Ce sont en fait deux mondes différents. Ils se croisent faiblement. Par conséquent, le rapport est également divisé en 2 parties.

Si vous étiez à un rapport précédent dans le hall principal, où il y avait une bonne introduction à Prometheus, vous savez que le stockage local est une bibliothèque distincte appelée TSDB. TSDB n'a rien à voir avec OpenTSDB. TSDB est un package Go distinct que vous pouvez utiliser à partir de votre programme Go. Au niveau de la bibliothèque TSDB, il n'y a ni client ni serveur.
Cette bibliothèque est optimisée pour travailler avec des données de séries chronologiques. Par exemple, TSDB a un codage delta, qui vous permet de stocker non pas les nombres eux-mêmes, mais les changements entre ces nombres. Cela vous permet de stocker 1 octet au lieu de 16 octets. 1 octet pour le temps et 1 octet pour la valeur. Autrement dit, vous stockez en moyenne 1 ou 2 octets précisément en raison de cette bonne compression.
TSDB est optimisé pour les modèles à traction. Les données y sont seulement ajoutées. Prometheus ne peut pas écrire de données historiques. Il n'y a pas d'API pour cela. Le delta maximum est d'environ 5 minutes. Si les données sont plus anciennes, elles ne seront pas acceptées.
Il n'y a pas de sous-échantillonnage intégré tsdb # 313 dans TSDB. Il y a une question ouverte dans laquelle il y a eu une discussion sur le fait qu'en général, il y a des projets qui font quelque chose de Prométhée et il y a un sous-échantillonnage là-bas. Jusqu'à présent, la solution est que TSDB n'ajoutera pas de sous-échantillonnage.

Comment obtiendrions-nous les données du TSDB? TSDB est une base de données sur disque. Vous pouvez travailler avec lui si vous écrivez un programme Go. Mais si vous n'écrivez pas de programme dans Go, il existe une API JSON qui vous permet d'effectuer des requêtes de requête. Si vous avez déjà utilisé Prometheus et au moins une fois créé un graphique, vous connaissez l'API de requête standard, dans laquelle il existe un paramètre de requête dans lequel vous pouvez exécuter n'importe quelle requête PromQL et éventuellement l'heure. S'il n'y a pas de temps, alors l'heure actuelle est prise.
Une requête spécifique est mise en évidence sur la diapositive, que vous voyez rarement dans la vie réelle. Ceci est un hack. Cela nous permet de retirer toutes les métriques de Prometheus. Comment ça marche? Au niveau de PromQL, on dit qu'il est impossible d'écrire une telle expression qui attraperait tout le temps les seriers. Ceci est écrit directement dans les règles. Une autre règle dit que vous ne pouvez pas créer un matcher dans lequel toutes les valeurs sont vides. Si vous écrivez simplement des accolades, cela ne fonctionnera pas. Si vous écrivez le nom n'est égal à rien (pas une valeur vide), cela ne fonctionnera pas. Mais c'est un vrai hack qui vous permet de faire ça. Cependant, il n'est même pas particulièrement documenté. Il y a des commentaires dans le code lui-même que cela fonctionne.
La deuxième requête est query_range, qui fait la même chose, mais vous renvoie des données dans une plage et avec une certaine étape. Il effectue essentiellement une requête plusieurs fois pour chaque étape du début à la fin. Il s'agit de l'API utilisée pour dessiner des graphiques. La première API utilise pour obtenir des valeurs instantanées.

Nous avons une API pour récupérer les métadonnées. Si nous voulons obtenir tous les noms des métriques, nous faisons une requête comme celle-ci, où match est un tableau de métriques. Il peut y avoir plusieurs arguments, mais dans ce cas, nous passons la même correspondance, que tout nous revient.
La deuxième méta API, qui nous renvoie la valeur de toutes les étiquettes. Si nous voulons voir une liste de tous les travaux, au lieu de label_name, nous écrivons le travail et obtenons cette liste. Ces API nous renvoient JSON.

Il existe une autre API qui renvoie toutes les métriques de Prometheus lui-même dans un format natif pour les exportateurs. Le format est appelé expfmt. Dans Prometheus lui-même, il existe une API de fédération qui vous permet de faire une telle demande. À quoi ça sert? L'option la plus simple, si vous avez du code qui fonctionne déjà avec expfmt, vous n'avez pas besoin de le recycler pour qu'il fonctionne avec une API JSON personnalisée. Ce format est beaucoup plus facile à diffuser, car si vous avez JSON quelque part au niveau supérieur de l'objet, vous devez le plus souvent analyser cet objet dans son ensemble. Ici, cela peut se faire ligne par ligne.
La chose la plus importante est qu'il s'agit d'une API distincte. Cela fonctionne comme une véritable exportation. Vous pouvez prendre l'autre Prométhée pour le gratter. Il s'agit d'un travail régulier avec les paramètres habituels. Vous devez passer le paramètre - URL de requête. Si vous faites une demande de boucle, vous obtiendrez la même chose ici. Nous obtenons toutes les métriques pour la valeur de temps actuelle. La seule mise en garde: vous devez définir honor_labels afin que Prometheus, qui supprimera un autre Prometheus via cette API, ne frotte pas la valeur du libellé de tâche et d'instance. À l'aide de cette API de fédération, vous pouvez charger toutes les données d'un Prometheus à un autre.

Comment cela peut-il être utilisé?
Tout d'abord, la chose la plus importante à dire est que vous n'avez pas besoin de le faire. TSDB est optimisé pour différents modes de fonctionnement. Si vous avez un Prometheus qui gratte beaucoup de données, alors il fait beaucoup d'E / S. Si vous utilisez l'API de fédération, la quantité de sortie d'entrée augmentera d'environ 2 fois. Il y a des nuances. Selon la fréquence à laquelle vous raclez sur fédérer et la fréquence à laquelle vous raclez les cibles. Si l'heure n'a pas été modifiée, cela double vraiment la charge. Par conséquent, si vous souhaitez faire évoluer votre Prométhée et activer la fédération, vous le tuerez. La charge doublera.
Deuxième moment. Vous sauterez des données. Vous obtiendrez un conflit de données. Pourquoi Cette API, comme presque toutes les API de Prometheus, n'est pas atomique. Si de nouvelles données arrivent, un nouveau scraping prendra fin au moment où votre demande de fédération est toujours en cours, vous pouvez obtenir une donnée pour une série chronologique et de nouvelles données pour une autre. S'il s'agit d'une série chronologique indépendante, ce n'est généralement pas effrayant. Mais si vous avez un résumé ou un histogramme, qui au niveau expfmt est représenté par plusieurs métriques de base, alors il y aura incohérence entre eux.

Comment résoudre ce problème atomique? Prometheus possède des règles d'enregistrement qui vous permettent de créer une nouvelle série chronologique à partir d'une série chronologique existante. Cela peut être fait moins fréquemment. C'est une façon de procéder au sous-échantillonnage. Par exemple, supprimez la cible toutes les secondes, mais nous voulons ensuite faire une agrégation node_cpu en une minute. Le regroupement dans Prometheus 2.0 vous permet de faire ces agrégations séquentiellement. Les règles qui sont dans le même groupe sont exécutées strictement séquentiellement. À ce stade, il n'y a pas de problème d'atomicité, il n'y a pas de problème que les données changent au cours du processus. Mais cela ne résout pas le problème du fait qu'il est admissible d'autres données qui sont logiquement liées à cela, mais pas connectées du point de vue du modèle de données. Il n'y a pas encore d'atomicité pure. Il y a un problème ouvert sur ce sujet. Vous pouvez faire des instantanés. Vous pouvez effectuer une requête PromQL dans la base de données TSDB et supprimer tous les échantillons inférieurs à une certaine valeur du temps qui a commencé dans l'évaluation à partir des valeurs obtenues. Ce serait le moyen le plus simple, mais jusqu'à présent, cela n'a pas été fait.
Il est important de comprendre que les règles d'enregistrement doivent se faire sur le Prométhée inférieur, et non sur celui que la fédération fait. Sinon, vous sauterez des pics, votre surveillance ne fonctionnera pas correctement.

Comment pouvons-nous utiliser cette combinaison de ces éléments pour effectuer un sous-échantillonnage et un stockage à long terme.
Le premier. Nous venons de mettre en place une fédération et de télécharger toutes les données de ce Prométhée. Cette étrange expression régulière est comme un zoidberg - c'est en fait juste un colon. Un astérisque à gauche et à droite du côlon. Nous utilisons le nom standard pour les règles d'enregistrement, qui ajoute deux points au milieu. Lors de la division du nom d'origine, il y aura un niveau d'agrégation à gauche et une fonction à droite. Une métrique normale du côlon ne fonctionne pas. S'il y a deux points, c'est le signe qu'il s'agit d'une agrégation. Après cela, nous utilisons ce nom de métrique dans notre graphique. Si nous voulons que notre emploi du temps, notre tableau de bord dans grafana fonctionne avec le Prométhée principal, et avec ceux qui sont supérieurs, nous pouvons utiliser l'expression ou . Nous prenons une métrique ou une autre, selon celle-là. Nous pouvons tricher et utiliser le réétiquetage pour renommer la nouvelle métrique en l'ancien nom. C'est une approche assez dangereuse. Vous pouvez mal orthographier les pièces jointes régulières et vous aurez un conflit de séries chronologiques. Prometheus écrira de nombreux avertissements dans le journal. Vous verrez cela, mais trouver la raison peut être assez difficile. Mais si cela est fait avec soin, par exemple, en générant ces expressions régulières par programme, cela fonctionnera. Ensuite, vous aurez un tableau de bord régulier où seul node_cpu est utilisé. Selon le Prometheus utilisé, vous recevrez soit des données brutes soit des données agrégées.

Comme je l'ai dit, les règles d'enregistrement peuvent être générées tout simplement. Nous obtenons simplement toutes les séries chronologiques via l'API que j'ai déjà montrée. Nous créons des règles et ces règles doivent utiliser les bonnes fonctions et les bons opérateurs. Pas besoin d'utiliser le taux avec jauge là-bas. Cela ne fonctionnera pas correctement. Il ne doit être utilisé qu'avec comptage. Au niveau où vous travaillez, vous ne disposez peut-être pas d'informations sur les types de données. Par exemple, si vous utilisez expfmt. Il y a des informations sur les types. Si l'API JSON n'est pas là. Par conséquent, l'expression que vous générez automatiquement peut ne pas avoir de signification physique. Par conséquent, vous pouvez y utiliser une liste blanche ou une liste noire. En fonction de cela, générez la règle dont vous avez besoin ou jetez les règles qui n'ont pas de sens. Il existe un outil promtool qui vous permet de vérifier que les règles que vous avez générées, la configuration que vous avez générée, ont du sens. Il a la syntaxe correcte.

Si nous avons Grafana et qu'il y a plusieurs Prométhée, nous devons savoir à quel Prométhée envoyer la demande. Comment ferions-nous cela?
Une façon consiste à mettre un proxy spécial qui regardera l'heure dans la demande, et en fonction de cela, sélectionnez Prometheus. Les requêtes ont une heure de début et une heure de fin. En fonction de cela, vous pouvez faire le routage avec vos mains. On pourrait écrire une sorte de programme qui fait cela. En pratique, cela se fait par nginx avec le module lua ou un petit programme.

Avons-nous vraiment besoin d'une API? Pouvons-nous travailler directement avec TSDB? Il y a une nuance. Premièrement, si nous essayons d'utiliser TSDB, qui est maintenant utilisé par Prometheus, nous ne pourrons pas le faire. Un fichier de verrouillage spécial empêche cela. Si nous écrivons du code qui ignorera cela et essayera de lire ou d'écrire des données, nous sommes garantis de les endommager. De plus, même en lisant. Que peut-on faire? Nous pouvons lire les données via l'API et créer TSDB côte à côte. Arrêtez ensuite Prometheus et remplacez-le par TSDB. Mais en même temps, nous pouvons réduire les performances si nous lisons toutes les données via l'API. J'en parlerai un peu plus tard.
La deuxième option. Vous pouvez copier (faire une sauvegarde à chaud) ces fichiers, c'est-à-dire les copier tels quels. Oui, ils seront endommagés. Lorsque vous ouvrirez, vous aurez un avertissement que les données sont corrompues. Ils doivent être réparés. Vous risquez de perdre de nouvelles données. Mais cela n'a pas d'importance pour nous. Nous voulons un sous-échantillonnage des anciennes données. Le sous-échantillonnage peut être effectué à l'aide de PromQL. Mais il y a une nuance. Il est beaucoup plus difficile de l'arracher de Prométhée que de TSDB. Si vous êtes un peu familier avec Go et la gestion des dépendances, le fournisseur PromQL est une grosse douleur. Je ne vous conseillerais pas. Évitez cela si possible.

Nous passons au stockage à distance. Quelqu'un a-t-il travaillé avec le stockage étendu dans Prometheus? Quelques mains. Le stockage étendu est une API qui existe depuis longtemps. Maintenant dans la version 2.2 Remote Storage - marqué comme expérimental. De plus, il est connu que l'API de stockage à distance va définitivement changer.
Le stockage étendu vous permet de travailler uniquement avec des données brutes. Il n'y a pas de PromQL à l'entrée ou à la sortie. Lorsque vous lisez, vous ne pouvez pas utiliser toute la puissance de PromQL. Il pompe essentiellement toutes les données du stockage étendu qui correspondent à la condition. PromQL fonctionne déjà avec eux. Cela a un gros frais généraux. Vous devez pomper beaucoup de données sur le réseau. Par conséquent, dans Prometheus 2.3, qui n'a pas encore été publié, mais il a déjà été retardé, il y aura un indice de lecture. Nous en reparlerons un peu plus tard.
Pas encore d'API pour les métadonnées. Vous ne pouvez pas créer une API qui renvoie toutes les séries chronologiques à partir du stockage étendu. Si vous faites une demande à l'API Prometheus, elle ne sera pas envoyée au stockage étendu. Il vous renverra la série chronologique, qui se trouve dans sa base de données locale. Si votre base de données locale est désactivée, elle vous renverra 0. Ce qui peut être un peu inattendu. Maintenant, cette API utilise ProtoBuf et elle sera définitivement remplacée par gRPC à l'avenir. Ils ne l'ont pas encore fait, car gRPC nécessite HTTP2. Et en pratique, ils ont eu des problèmes avec lui.

L'API d'écriture ressemble à ceci. La demande a un ensemble d'étiquettes. L'ensemble d'étiquettes identifie de manière unique la série chronologique. __name__
est vraiment juste une étiquette avec un nom spécial. Et les échantillons sont un ensemble de temps et de valeurs - int64 et float64. Lors de l'enregistrement, la commande est sans importance. Il est supposé que la base de données qui l'écrit se fera correctement. Prometheus peut effectuer une optimisation et ne plus la trier. Par conséquent, une demande d'écriture n'est que quelques séries chronologiques.

La configuration d'écriture a une configuration assez flexible. Il existe de nombreuses options pour configurer la simultanéité en écriture. Ce que Prometheus appelle les tessons sont essentiellement des demandes concurrentielles. Vous pouvez limiter le nombre maximal d'échantillons dans une seule demande, le nombre maximal de demandes parallèles, le délai d'expiration, la façon de répéter, quelle interruption. Pour de nombreuses bases de données, 100 échantillons à la fois - cela peut être très petit. Si vous utilisez ClickHouse, comme nous le faisons, alors bien sûr, la valeur doit être considérablement augmentée. Sinon, ce sera très inefficace.

L'API de lecture à distance ressemble à ceci. C'est juste une plage de temps du début à la fin et un ensemble de matchs.

La correspondance est essentiellement une collection de paires nom / valeur - un type d'étiquette et de condition normal. En comparaison, il existe des égalités, des inégalités ou des expressions régulières. Il s'agit du sélecteur de séries chronologiques habituel que vous voyez dans PromQL. Il n'y a aucune fonctionnalité ici.

La réponse est quelques séries chronologiques qui correspondent à cette requête. Ici, les échantillons doivent être triés par heure. encore une fois, cela aide Prometheus à économiser un peu de CPU - pas besoin de trier. Mais il est supposé que votre base de données devrait le faire. Dans la plupart des cas, il en sera ainsi, car, très probablement, il y aura un indice à temps.

Prométhée 2.3 a introduit un indice de lecture. Qu'est ce que c'est C'est l'occasion de dire à Prométhée quelle fonction interne qui fonctionne avec la série chronologique demandée sera appliquée. Il peut s'agir d'une fonction ou d'un opérateur d'agrégation. Ce peut être un taux. Autrement dit, il est appelé func, mais en fait, il peut être somme, qui du point de vue de PromQL n'est en fait pas une fonction du tout. Ceci est l'opérateur. Et un pas. Dans l'exemple précédent, il y avait un taux de 1 minute. Ici, le taux est une fonction et une minute en millisecondes comme étape. Cette indication peut être ignorée par la base de données distante. En même temps, il n'y a aucune indication dans la réponse si elle a été ou non ignorée.

Quelle est la configuration de lecture?
Premièrement, il existe une telle configuration required_matchers. Cela vous permet d'envoyer une demande de stockage étendu qui correspond à l'expression. Pour lire les données agrégées du stockage étendu, vous devez utiliser une requête qui contient deux points.
Il existe une option qui vous permet de lire ou de ne pas lire les données récentes du stockage étendu, qui se trouve dans TSDB. Habituellement, dans la configuration standard, il y a un petit TSDB local qui est écrit sur le disque local. Elle y entrepose pendant plusieurs heures ou plusieurs jours. Les données que vous utilisez maintenant, qui sont utilisées pour les alertes, qui sont utilisées pour créer le tableau de bord, sont lues uniquement à partir du TSDB local. C'est rapide, mais cela ne nous permet pas de stocker beaucoup de données.
Les anciennes données historiques seront lues à partir du stockage étendu. Cela montre clairement comment le stockage local et le stockage distant communiquent entre eux. Il n'y a pas de déduplication.
Essentiellement ce qui se passe. Les données sont extraites du stockage local, les données sont extraites du stockage distant si read_recent est activé. Ils fusionnent juste ensemble. Il semblerait que ce ne soit pas un problème. Si l'on suppose que nous n'avons pas sous-échantillonné les données récentes, ce sont exactement les mêmes données, elles coïncident complètement avec les données locales, nous aurons deux fois plus d'échantillons, nous ne devrions affecter aucune fonction. Pas vraiment. Il existe une fonction irate () et une paire pour la jauge, qui nous renvoie la différence entre les deux dernières valeurs. Elle revient sur la plage de temps indiquée, mais utilise uniquement les deux dernières valeurs. Si nous avons les deux dernières valeurs en même temps, alors la différence sera nulle. Il s'agit d'un bug et il est presque impossible de le trouver. Il a été réparé il y a seulement quatre jours. Ceci est un ticket pour toute personne intéressée.

Fait intéressant, la lecture à distance a été implémentée par Prometheus depuis la version 1.8. C'est ainsi que vous pouvez lire les données de l'ancien Prometheus lorsque vous migrez vers la version 2.x. La manière officielle conseille de le connecter en lecture à distance. Les données seront soustraites au besoin.
La lecture à distance peut être utilisée pour effectuer un routage de requête sans proxy. Sur l'une des diapositives précédentes, j'ai montré que, selon le temps, nous pouvons faire du routage sur un Prométhée ou un autre. De la même manière, nous pouvons éviter cela. Branchez simplement le Prometheus ci-dessous qui est lu à distance - et les données seront lues à partir de là. Mais il y a un amendement au fait que bien sûr beaucoup de données seront pompées. Surtout si vous n'utilisez pas l'indice de requête.

Pourquoi Clickhouse?
Pour notre solution de recherche, nous avons choisi ClickHouse, car nous la regardons depuis longtemps. Nous avons des gens qui sont constamment engagés dans la performance des bases de données, vérifiant constamment de nouvelles bases de données. Notre entreprise est engagée dans des bases de données open source.
Nous aimons vraiment ses performances brutes. Sa puissance en termes de CPU, de temps et ainsi de suite, est très bonne. La plupart de ces systèmes parlent d'évolutivité infinie, mais parlent peu d'efficacité pour un seul serveur. Beaucoup de nos clients stockent des métriques sur une paire de serveurs.
Réplication intégrée, partitionnement.
GraphiteMergeTree est un moteur spécial pour stocker des données de graphite. Au début, il était très intéressé par nous.

Le moteur est destiné au cumul (amincissement et agrégation / moyennage) des données Graphite.
Le graphite stocke toutes les données dans ClickHouse, et il peut les recevoir, et il indique en outre qu'avec l'amincissement, GraphiteMergeTree est utilisé, MergeTree est utilisé sans amincissement. Le sentiment est que les données sont toujours pleines, elles ne sont pas écrasées, c'est juste une optimisation de la lecture. Mais dans l'ensemble, ce n'est pas mal. Lorsque nous faisons la lecture, nous ne pompons pas les données, elles sont automatiquement agrégées, nous obtenons un peu de données - c'est bien. L'inconvénient pour nous est que toutes les données sont stockées.
Je me préparais au début du mois pour le rapport. Quelqu'un entre dans une discussion par télégramme et demande - "Sous-échantillon de données GraphiteMergeTree"? J'écris déjà non. La documentation dit non. Mais l'autre personne dans le chat répond "oui, vous devez appeler optimiser". Courez, vérifiez - oui la vérité. La documentation est essentiellement un bug. Ensuite j'ai lu le code source, vérifié, il s'avère qu'il y a optimisation, optimisation finale. Optimiser final a été initialement créé spécifiquement pour GraphiteMergeTree. En fait, il sous-échantillonne. Mais il faut l'appeler de ses mains.
GraphiteMergeTree a un modèle de données différent. Il n'a pas d'étiquettes. L'orthographe efficace au nom des métriques ne fonctionne pas très bien.
Les métriques de nom sont stockées dans une table. Le nom des métriques a une longueur différente. Cela conduit au fait que si nous effectuons une recherche d'index par le nom de la métrique, car la longueur est différente, cet index ne sera pas aussi efficace que si cet index avait une valeur de longueur fixe. Parce que vous devez faire une recherche de fichier. Il est impossible de spécifier exactement où atterrir pour effectuer une recherche binaire.

Par conséquent, ils ont fait leur propre plan. La diapositive montre comment nous stockons les séries chronologiques dans la base de données. La date dont ClickHouse a besoin est une empreinte digitale. Si vous avez examiné les sources de Prométhée ou TSDB, vous savez que l'empreinte digitale est essentiellement une courte somme de contrôle rapide de la série chronologique du nom complet. L'empreinte digitale est une combinaison de toutes les étiquettes, clés et valeurs. Un nom est une étiquette régulière. Nous utilisons le même algorithme pour la compatibilité. Débiter quelque chose peut être pratique. L'empreinte digitale est la même et il peut être vérifié dans TSDB et dans notre stockage qu'ils sont les mêmes. Les étiquettes sont stockées dans un JSON spécial, ce qui permet à ClickHouse de travailler avec lui avec ses fonctions standard. Il s'agit d'un JSON compact sans espaces, avec une dénomination légèrement simplifiée. Ce tableau n'est pas utilisé pendant le fonctionnement. Il est toujours stocké dans la mémoire de notre solution actuelle, appelée PromHouse. Il n'est utilisé que lorsque nous démarrons le serveur afin de savoir quelles sont les séries chronologiques. Elle est soustraite. À mesure que de nouvelles séries chronologiques arrivent, nous les enregistrons là-bas. Toutes les instances multiples de PromHouse peuvent lire la même table. ReplacingMergeTree nous indique que ces séries chronologiques - il existe plusieurs instances différentes - écrivent la même série chronologique. Ils contesteront - et il n'y aura aucun problème ici.

Nous stockons les échantillons dans une table séparée très efficacement. Avec une valeur de longueur fixe, cette empreinte digitale est la même, le temps et la valeur. Nous obtenons 24 octets par échantillon. Il a une longueur strictement fixe. Chaque colonne est stockée séparément. Une recherche d'empreintes digitales est efficace car nous savons que la taille est fixe. Il n'y a pas de problème comme avec GraphitmergeTree quand il s'agit d'une chaîne. Nous utilisons un partitionnement personnalisé. Indice d'empreinte digitale primaire et par heure.
24 octets est une version simplifiée. En fait, il se comprime bien. En fait, utilise moins d'espace. Dans nos derniers tests, le taux de compression est d'environ 1 à 42.

Comment pouvons-nous faire un sous-échantillonnage manuel si nous avons GraphiteMergeTree, mais pas comme nous le souhaiterions. En fait, nous pouvons le faire à la main. Comme précédemment, le partitionnement, le partitionnement, quand il n'y avait rien de intégré. Nous faisons une nouvelle table avec nos mains. Lorsqu'un échantillon de temps nous parvient, nous déterminons à quelle table nous écrivons.
Nous sélectionnons l'heure de la requête à partir de laquelle la table à lire. Si la lecture a lieu à la frontière, nous lisons plusieurs tableaux. Ensuite, nous détenons ces données. On pourrait utiliser la vue pour cela. Par exemple, créez une vue pour plusieurs tables, ce qui permet de la lire dans une seule requête. Mais il y a un bug dans ClickHouse: le prédicat de la vue n'est pas substitué dans les requêtes. Par conséquent, si vous faites une demande en vue, elle va à toutes les tables. Vue que nous ne pouvons pas utiliser.
Comment procéder au sous-échantillonnage? Nous créons une table temporaire. Copiez l'insert dans certaines données qu'il contient en utilisant les fonctions correctes.
Nous faisons renommer qui est atomique sous le verrou global. Nous renommons la table existante en ancienne. Nouveau à existant. Nous abandonnons l'ancienne table. Nous avons des données pour 148 jours déjà sous-échantillonnées. Quel est le problème ici? Insérez dans l'air magnifique. En fait, nous devons appliquer les fonctions correctes, la bonne agrégation à faire. En pratique, cela ne peut pas être fait avec une seule grande demande. Même quelques demandes importantes ne peuvent pas être faites. Cela doit être fait à partir du code. Le code envoie un grand nombre de petites demandes. Nous avons fait de notre mieux pour le faire avec des demandes importantes, mais ce n'est pas très efficace. Le sous-échantillonnage des données d'un jour jusqu'à présent prend moins d'une journée. Selon la quantité de données, cela peut prendre beaucoup de temps.

ClickHouse aura la mise à jour / suppression. Supprimer a déjà obtenu la première version. Si la mise à jour / suppression fonctionne, notre schéma de données de sous-échantillonnage peut être simplifié.
Deuxièmement, ClickHouse a pour tâche de faire une compression personnalisée (delta, delta to delta). C'est ce que fait le TSDB. Ceci est bien adapté aux données de séries chronologiques. Ceci est particulièrement utile si nous pouvons choisir le type de compression en fonction des types de données. Par exemple, le compteur, qui ne fait que croître - pour cela, la compression delta-delta convient. Une jauge qui fluctue autour de la magnitude, donc le delta fonctionne bien.

Il y a d'autres rangements qui fonctionnent. Il y a InfluxDB qui fonctionne hors de la boîte. Il est habituel de le gronder pour la vitesse, mais ce qui fonctionne hors de la boîte et vous n'avez rien à faire est bon.
Il existe OpenTSDB et Graphite, qui est en écriture seule. L'adaptateur standard de Prometheus ne fonctionne pas vraiment.
Il y a un CrateDB. Il existe un TimescaleDB qui fork PostgreSQL pour les bases de données de séries chronologiques. Ils disent que cela fonctionne bien, mais nous-mêmes ne l'avons pas essayé.
Il y a Cortex, également connu sous le nom de projet Frankenstein. Cela le décrit très bien. Ce sont les gars qui essaient de prendre une décision basée sur la fédération Prometheus. Ils stockent des données dans S3.
Il y a Thanos.
- Il a une architecture très intéressante. Il y a Prometheus qui utilise le TSDB local. Un cluster est créé entre eux. À côté de chaque Prométhée se trouve un side-car spécial, qui accepte les demandes via l'API de lecture et d'écriture à distance. Il redirige ces demandes vers Prométhée. Prometheus peut utiliser ses API de lecture et d'écriture à distance. Tous les side-cars sont interconnectés et entre maîtres API personnalisés via gRPC, la réplication est disponible, il y a re-ombrage.
- Architecture sophistiquée.
- C'est assez humide. Il y a quelques mois, il tombait en dehors d'un demi-coup de pied quand il a commencé.

L'utilisation du modèle pull n'écrit pas beaucoup de données. Vous devez attendre une année entière pour remplir les données annuelles. Nous essayons en quelque sorte de les écrire là-bas.
Il n'y a pas d'écriture à distance dans Prometheus, par conséquent, l'écriture d'un grand nombre de données sur le TSDB local ne fonctionnera pas.
Le deuxième problème. Si nous générons des données pour les tests de résistance, elles tremblent souvent bien. Par exemple, si nous prenons des données existantes et générons 100 instances, et que ce sont les mêmes données, alors le coefficient de compression sera si beau qu'en réalité, cela ne se produit pas.

Nous avons écrit un faux exportateur qui ressemble à un exportateur régulier que Prometheus peut tenir ensemble:
- Lorsque la ferraille arrive, il se rend chez un exportateur en amont. Prend des données.
- Génère de nombreuses instances. Disons que 1 est une tremblante et que nous obtenons 100 à la sortie.
- Modifie légèrement les données: plus moins 10% pour le compteur et la jauge.
- Il ne modifie pas les valeurs simples 0 ou 1. Parce que s'il existe une métrique UP qui répond, elle indique si le service est en cours d'exécution: oui - 1 ou non - 0. Et la signification de 098 UP n'est pas très claire.
- Nous ne changeons pas les entiers en réels et vice versa.
- Il donne juste des données au format expfmt habituel.

Un outil de promload qui charge les données. Lecture des données:
- Peut lire des fichiers dans son propre format
- Peut-être de la lecture à distance
- Peut lire à partir d'un exportateur
Écrit dans différents formats. Y compris dans / dev / null, si nous voulons tester exactement comment la lecture fonctionne rapidement.
Maintenant, c'est un outil de test de charge non seulement pour PromHouse, mais aussi pour toute solution qui utilise la lecture à distance ou Prometheus.

Nous voulons ajouter la mise en cache de lecture, car dans nos tests, le goulot d'étranglement était souvent le faux exportateur, qui générait des données pendant longtemps. Nous pourrions les mettre en cache. Qu'ils soient irréalistes. Mais nous ne ralentirons pas. Nous n'avons pas eu à attendre des jours pour les tests de résistance.
Une sorte de filtrage à la volée, une sorte de modification à la volée.
Prise en charge native de TSDB. Afin de travailler avec la base de données sur disque, et non via l'API.
Concentrez-vous sur la précision de la migration. J'ai une fois pmmdemo.percona.com mis: connecté, reçu toutes les métriques. Si vous le faites de manière native, Prometheus ouvre TSDB, lève toutes les séries temporelles à partir du disque, lève les index, puis explore les fichiers en morceaux, se rend compte qu'ils existent vraiment. À ce stade, tout peut simplement se coucher.
L'approche naïve consiste à prendre toute la série chronologique et à lire les anciennes données aux nouvelles. À ce moment, il se couchera. Vous devez faire le contraire. Vous devez d'abord obtenir la liste des séries chronologiques avec quelques requêtes avec des expressions régulières. Par exemple, une série chronologique qui commence par A. Donnez-moi ensuite une série chronologique qui commence par B. Ensuite, chargez-les exactement par métriques, pas par heure. C'est illogique, mais c'est ainsi que cela fonctionne. C'est une nuance si vous faites quelque chose comme ça. Si vous voyez que OOM Killer s'est produit là-bas, alors vous saurez que c'est à cause de vous.

Les résultats des tests de charge, il n'y aura pas de graphiques. Les tests de charge prennent beaucoup de temps et, malheureusement, en raison d'une erreur de configuration, tout s'est mal passé. Par conséquent, les résultats n'ont pas fonctionné.
Nous écrirons sur le blog Percona lorsque nous ferons des tests de charge.
Je peux dire les résultats sans graphiques. L'enregistrement était linéaire. La lecture a sauté et n'a pas été très rapide. La lecture des données actuelles n'est pas très importante pour nous. Ils peuvent être accélérés grâce à des conseils de lecture. Vous pouvez activer read_recent pour améliorer la lecture. Et pour les anciennes données, cela fonctionne bien.

Les gens veulent un stockage à long terme. Il y a une telle demande. Nous avons parlé de PromHouse à PromCon. Là, c'était un sujet très chaud. Thanos se développe activement.
C'est déjà possible maintenant. Il y a une solution à cela. Il y a une API. Il y a quelques intégrations. Mais tout cela doit être finalisé avec un fichier. Aucune solution prête pour la production.

Liens où chercher. Le premier lien est le référentiel PromHouse. Le deuxième lien est l'endroit où il est susceptible de se déplacer. Maintenant, dans un référentiel, il y a plusieurs choses différentes? pas très étroitement liés. Par conséquent, vous devrez les transférer.
Notre blog contiendra des informations sur les performances et quelques nouvelles.
Questions:
Question: Avez-vous vérifié les rumeurs concernant InfluxDB?
Réponse: Il n'était pas très bon. Il est devenu beaucoup mieux. Toutes ces histoires sur le fait qu'InfluxDB est lent, s'effondre - elles concernent l'ancienne version. La version actuelle est stable. Je ne dirais pas? que cela fonctionne rapidement. Mais cela fonctionne de manière stable. Avantages d'InfluxDB à mon avis:
- Tout d'abord, il n'est pas nécessaire de faire quelque chose à proximité, car InfluxDB fonctionne immédiatement.
- Deuxièmement, dans ClickHouse, comme dans d'autres solutions basées sur des bases de données, mais pas TSDB, vous pouvez utiliser un langage de requête qui vous est plus familier. Le langage de requête InfluxDB est similaire à SQL. Vous pouvez faire des analyses dessus, ce qui est difficile à faire sur PromQL. Si vous utilisez TimeScaleDB - il y a du vrai SQL.
Question: Le moteur GraphiteMergeTree sert-il uniquement à enregistrer des travaux? Si nous voulons afficher des graphiques, Grafana doit-il être configuré sur Graphite afin de montrer le stockage à long terme?
Réponse: oui. L'intégration qui est dans Prometheus lui-même ne fonctionne que pour l'enregistrement. Il écrit seulement des données. Donc de Grafana vous allez au graphite.
Question: Et il perd des étiquettes quand il écrit?
Réponse: Il y a une configuration qui dit quoi faire avec eux, comment les insérer, où les insérer.
Informations du public: Avito a déclaré qu'il rédige sa solution pour les enregistrements de Prométhée au graphite.
Question: il a été conclu qu'avec l'enregistrement, tout va bien sur un serveur de stockage à long terme.
(5- 15-). raid 6 sata ?
: PMM — . downsampling c 14 1 . , . . . .
: IOPS ?
: .
:
: . , . , , .
: InfluxDB, InfluxDB?
: read_recent. , remote storage. InfluxDB . . read_recent , .
: , Prometheus. InfluxDB. Grafana Prometheus. Prometheus PromQL , InfluxDB?
: .
: Prometheus InfluxDB Grafana?
: . Prometheus 2.2 , .
PS : valyala gecube
, .