Comment réduire la taille des métriques dans Prometheus si vous n'êtes pas DevOps

Parfois, l'équipe de développement est confrontée à un problème dans lequel elle a peu d'expérience d'expert, et par essais et erreurs, elle trouve une solution non évidente. Cela nous est arrivé lorsque nous avons dû transférer la collection de métriques d'Infux vers Prometheus. Leur taille totale s'est avérée être de 1,5 million, et nous avons décidé de la réduire. L'infrastructure de collecte des métriques (Prometheus, k8s, déploiement via Helm) a été créée par des ingénieurs DevOps d'une autre équipe qui n'avait pas les ressources pour notre tâche. Par conséquent, nous avons fait appel à leurs conseils, étudié la documentation et décidé de réduire la dimension des métriques par des efforts de développement.



Cet article ne convient pas aux ingénieurs DevOps expérimentés, mais il sera utile aux développeurs qui souhaitent réduire la dimension des métriques et ne souhaitent pas se plonger dans la documentation. Ou à ceux qui abandonnent délibérément la fédération hiérarchique et recherchent une solution de contournement, mais ne veulent pas marcher sur notre râteau. Disons :



  • comment réduire la dimension des métriques en deux étapes à l'aide de deux ServiceMonitor,
  • quel est le moyen de référence pour réduire la dimension des métriques sans "béquilles",
  • pourquoi vous ne devriez pas perdre de temps sur la réduction de la dimensionnalité avec Pushgateway.


Pourquoi il était nécessaire de réduire la dimension des métriques



Notre équipe est responsable de l'un des produits Mindbox - les recommandations de produits sur le site Web et dans les newsletters. Nous avons collecté le temps de traitement des recommandations en temps réel dans Influx, et afin d'aider l'entreprise à évaluer les performances du produit, il a également fallu compter l'Apdex (Application Performance Index). La société transfère progressivement les métriques d'Influx vers Prometheus. Elle a donc décidé de collecter les deux métriques à la fois dans Prometheus à l' aide d'histogrammes.





Le



graphique à barres métrique que nous voulions créer pour mesurer les performances des produits Nos services sont déployés sur Kubernetes. Nous collectons des métriques dans Prometheus à l'aide de ServiceMonitor. Nous utilisons Prometheus.NET dans l'application .Dans la configuration par défaut, une étiquette de pod avec la valeur correspondante est ajoutée à chaque métrique exportée par le pod.



Collecte de métriques dans Prometheus à l'aide de ServiceMonitor







Pour afficher le temps de traitement moyen, les centiles (p50, p95, p99) et Apdex, il était prévu d'utiliser un histogramme avec 20 buckets. Compte tenu du fait que nous voulions recevoir des informations sur chacun des 2,5 mille mécanismes de recommandation, la dimension totale des métriques était de 50 mille. Les noms de pod changent sur chaque mise en page et l'étiquette de pod est attribuée à chaque métrique, donc avec une conservation de 30 jours et une mise en page quotidienne, la dimension passe à 1,5 million. Une métrique de cette dimension prenait beaucoup plus de place dans Prometheus que nous ne le voulions.



2 500 * 20 * 30 = 1 500 000

(nombre de mécanismes) * (nombre de compartiments d'histogramme) * (rétention) = (dimension finale)




Nous avons décidé de nous débarrasser des étiquettes de pod et d'instance afin que la dimension n'augmente pas dans les calculs. Dans le même temps, nous avons essayé de trouver une solution simple et bon marché pouvant être implémentée et maintenue sans l'intervention d'un ingénieur DevOps.



Une hypothèse importante : la métrique pour laquelle nous voulions réduire la dimension est collectée à partir d'un seul pod à la fois. Le pod ne peut changer que lorsque l'application est redémarrée, par exemple, lors de la mise en page.



Quelles solutions ont été envisagées



Réservons d' emblée que la fédération hiérarchique est la plus adaptée pour résoudre les problèmes de dimension, des exemples d'utilisation sont décrits en détail dans la documentation de celle-ci. Nous pourrions déployer Prometheus avec une faible rétention de métriques et y collecter des métriques brutes. Ensuite, grâce aux règles d'enregistrement, calculez les agrégats et collectez-les dans un autre Prometheus avec une rétention de données élevée.



Nous n'avons pas envisagé la fédération car nous voulions trouver une solution plus simple, moins chère et plus rapide à mettre en œuvre. De plus, les développeurs devaient travailler sur la tâche, pas sur DevOps, je voulais donc utiliser des outils et des techniques familiers. Même si la pratique a montré que nous avons passé du temps à chercher une telle solution, durant laquelle il était possible de faire une fédération, et notre mise en place s'est avérée être une « béquille ».



Nous avons formulé deux solutions équivalentes :



1. Élever Pushgateway et y envoyer des métriques sans étiquettes. L'entreprise disposait déjà d'une charte de pilotage pour le suivi de la pile, y compris pour Pushgateway.



Avantages:le code et les graphiques peuvent être réutilisés, les métriques d'autres serveurs d'équipe qui se trouvent en dehors de Kubernetes et qui ne sont pas encore passés d'Influx à Prometheus peuvent être transférées vers la passerelle surélevée.



Inconvénients : support plus cher.



Collecte de métriques dans Prometheus à l'aide de Pushgateway







2. Élevez le deuxième ServiceMonitor et configurez le routage des métriques entre eux. Dans l'un, en relayant, supprimez les étiquettes de pod / instance et dans l'autre, laissez-le tel quel.



Avantages : moins cher - il vous suffit de déployer ServiceMonitor, plus facile à entretenir.



Inconvénients : une implémentation opérationnelle avec laquelle les développeurs n'étaient pas familiers.



Collecte de métriques dans Prometheus à l'aide d'un deuxième ServiceMonitor







Comment la solution Pushgateway a échoué



Première solution. Pour commencer, nous avons choisi la mise en œuvre évidente via Pushgateway. Nous avons récupéré Pushgateway, y avons poussé des métriques et utilisé une constante comme étiquette d'instance. La demande ressemblait à ceci :



curl -i -X POST \
     -d 'some_metric{bar=\"fooo\"} 3.22' \
     'https://pushgateway:9091/metrics/instance/constant/'
      
      





Nous avons rapidement fait face à la tâche et au début, le résultat était satisfaisant - les métriques ont été collectées, mais la dimension n'a pas augmenté. Mais bientôt, nous avons commencé à remarquer de grandes lacunes dans les métriques pour certains mécaniciens. Dans le même temps, un schéma étrange a été tracé - lorsque pour certains mécaniciens la métrique était transmise correctement et en continu, pour d'autres, des défaillances ont commencé. Cela donnait l'impression qu'un seul groupe de mécaniciens faisait rapport à la fois. Il y avait plusieurs de ces groupes, et ils ont changé sans ordre particulier.



Pourquoi ça n'a pas marché.Toute personne familière avec le dispositif Pushgateway a probablement su tout de suite que notre solution ne fonctionnait pas. Dans Pushgateway, les étiquettes sont transmises de deux manières : via le chemin de la demande ou dans le corps de la demande. Dans ce cas, l'ensemble d'étiquettes et leurs valeurs qui sont passés par le chemin agissent comme une clé pour le dictionnaire où sont stockées les métriques. Tout ce qui a été transmis via le corps de la requête entre dans la valeur à l'aide de cette clé. C'est-à-dire, dans notre cas, chaque requête d'un pod écrase toutes les métriques qui ont été poussées depuis d'autres pods. Étant donné que Prometheus collecte des métriques à intervalles, seules les métriques du pod qui a été le dernier à être poussé y ont été incluses.



Pour envoyer correctement les métriques à Pushgateway, vous devrez écrire du code C# personnalisé. Mais une telle solution n'était ni facile ni bon marché, elle a donc été abandonnée.



Deuxième solution. Nous avons décidé de nous emparer à nouveau de Pushgateway : collecter les métriques initiales et pousser avec toutes les étiquettes, puis supprimer l'étiquette du pod à l'aide de ServiceMonitor, qui collecte les métriques de Pushgateway. Mais déjà au départ, on s'est rendu compte que l'idée ne fonctionnerait pas.



Pourquoi pas mis en œuvre.Pushgateway possède plusieurs fonctionnalités qui rendent cette solution impossible. Principal - les données ne sont pas effacées automatiquement, par rétention. Cela signifie que vous devez suivre la taille du disque et écrire le code de nettoyage manuellement. Un autre problème est qu'après le relais, les métriques avec le même ensemble d'étiquettes, mais avec une étiquette de pod différente, entreront en conflit. Par conséquent, seule la dernière métrique restera dans l'ordre Pushgateway. Dans ce cas, les métriques ne sont pas triées par date de dernière modification, mais par ordre alphabétique. Ainsi, lors de la mise en page, les valeurs des nouveaux pods peuvent ne pas entrer dans Prometheus.



Comment la solution a fonctionné avec le deuxième ServiceMonitor



Nous sommes revenus à notre deuxième conception originale et avons créé deux ServiceMonitor. De plus, une étiquette spéciale a été placée dans le code (dans notre cas, entreprise) pour les métriques dont nous réduisons la dimension :



  • sur un ServiceMonitor, toutes les métriques avec une étiquette spéciale ont été supprimées et les autres ont été laissées telles quelles ;
  • d'autre part, seules les métriques avec une étiquette spéciale ont été laissées et les étiquettes de pod et d'instance en ont été supprimées.


Nous avons tout fait par relais, ajouté le code à la configuration du premier ServiceMonitor :



metricRelabelings:
  - action: drop
    sourceLabels:
      - business
    regex: "[Tt]rue"

      
      





Les éléments suivants ont été ajoutés à la configuration du deuxième ServiceMonitor :



metricRelabelings:
  - action: keep
    sourceLabels:
      - business
    regex: "[Tt]rue"
  - action: labeldrop
    regex: instance|pod|business

      
      





Ce que nous avons appris de l'histoire de la recherche de solutions



  1. Ni Pushgateway directement ni son relais ne sont adaptés pour réduire la dimension des métriques.
  2. Si vous utilisez le relais, les métriques avec le même ensemble d'étiquettes ne doivent pas être signalées simultanément à partir de différents pods.
  3. Le deuxième ServiceMonitor est une « béquille » facile et rapide à mettre en œuvre si vous ne voulez pas gaspiller de ressources sur la fédération.
  4. La meilleure solution pour la réduction de la dimensionnalité est la fédération :

    • Prométhée à faible rétention,
    • collecter des agrégats (règles d'enregistrement),
    • envoyé à Prométhée avec une rétention élevée.


Youri Sokolov, développeur



All Articles