Cómo reducir las métricas en Prometheus si no es DevOps

A veces, el equipo de desarrollo se enfrenta a un problema en el que tienen poca experiencia como experto y, a través de prueba y error, encuentran una solución no obvia. Esto nos sucedió cuando necesitábamos transferir la colección de métricas de Infux a Prometheus. Su tamaño total resultó ser de 1,5 millones y decidimos reducirlo. La infraestructura para recopilar métricas (Prometheus, k8s, implementación a través de Helm) fue creada por ingenieros de DevOps de otro equipo que no tenía los recursos para nuestra tarea. Por lo tanto, solicitamos su asesoramiento, estudiamos la documentación y decidimos reducir la dimensión de las métricas mediante esfuerzos de desarrollo.



Este artículo no es adecuado para ingenieros de DevOps con experiencia, pero será útil para desarrolladores que quieran reducir la dimensión de las métricas y no quieran sumergirse en la documentación. O para aquellos que abandonan deliberadamente la federación jerárquica y buscan una solución, pero no quieren pisar nuestro rastrillo. Digamos:



  • cómo reducir la dimensión de las métricas en dos pasos utilizando dos ServiceMonitor,
  • cuál es la forma de referencia para reducir la dimensión de las métricas sin "muletas",
  • por qué no debería perder tiempo en la reducción de dimensionalidad con Pushgateway.


Por qué fue necesario reducir la dimensión de las métricas



Nuestro equipo es responsable de uno de los productos de Mindbox: recomendaciones de productos en el sitio web y en los boletines. Recolectamos el tiempo de procesamiento de las recomendaciones en tiempo real en Influx, y para ayudar a la empresa a evaluar el desempeño del producto, también fue necesario contar el Apdex (Application Performance Index). La compañía está transfiriendo gradualmente métricas de Influx a Prometheus, por lo que decidieron recopilar ambas métricas a la vez en Prometheus utilizando histogramas.





El



gráfico de barras métricas que queríamos crear para medir el rendimiento del producto. Nuestros servicios se implementan en Kubernetes. Recopilamos métricas en Prometheus utilizando ServiceMonitor. Usamos Prometheus.NET en la aplicación .En la configuración predeterminada, se agrega una etiqueta de pod con el valor correspondiente a cada métrica que exporta el pod.



Recopilación de métricas en Prometheus usando ServiceMonitor







Para mostrar el tiempo de procesamiento promedio, los percentiles (p50, p95, p99) y Apdex, se planeó usar un histograma con 20 cubos. Teniendo en cuenta el hecho de que queríamos recibir información sobre cada una de las 2.5 mil mecánicas de recomendación, la dimensión total de las métricas fue de 50 mil. Los nombres de los pods cambian en cada diseño y la etiqueta del pod se asigna a cada métrica, por lo que con una retención de 30 días y un diseño diario, la dimensión crece a 1,5 millones. Una métrica con esta dimensión ocupaba mucho más espacio en Prometheus del que queríamos.



2.500 * 20 * 30 = 1.500.000

(número de mecánicas) * (número de cubos de histograma) * (retención) = (dimensión final)




Decidimos deshacernos de las etiquetas del pod y de la instancia para que la dimensión no aumente en los cálculos. Al mismo tiempo, intentamos encontrar una solución simple y barata que se pueda implementar y mantener sin la participación de un ingeniero de DevOps.



Una suposición importante: la métrica para la que queríamos reducir la dimensión se recopila de un solo grupo a la vez. El módulo solo puede cambiar cuando se reinicia la aplicación, por ejemplo, al diseñar.



Que soluciones se consideraron



Hagamos una reserva de inmediato de que la federación jerárquica es más adecuada para resolver problemas de dimensión; los ejemplos de uso se describen en detalle en la documentación correspondiente. Podríamos implementar Prometheus con baja retención de métricas y recopilar métricas sin procesar allí. Luego, a través de las reglas de grabación, calcule los agregados y recójalos en otro Prometheus con una alta retención de datos.



No consideramos la federación porque queríamos encontrar una solución más fácil, económica y rápida de implementar. Además, los desarrolladores tenían que trabajar en la tarea, no en DevOps, por lo que quería usar herramientas y técnicas familiares. Aunque la práctica ha demostrado que pasamos tiempo buscando una solución de este tipo, durante la cual fue posible hacer una federación, nuestra implementación resultó ser una "muleta". Formulamos



dos soluciones equivalentes:



1. Eleve Pushgateway e impulse las métricas allí sin etiquetas. La compañía ya tenía un gráfico de timón para monitorear la pila, incluso para Pushgateway.



Pros:el código y los gráficos se pueden reutilizar, las métricas de otros servidores del equipo que están fuera de Kubernetes y aún no se han movido de Influx a Prometheus se pueden transferir al Pushgateway elevado.



Contras: soporte más caro.



Recopilación de métricas en Prometheus mediante Pushgateway







2. Genere el segundo ServiceMonitor y configure el enrutamiento de métricas entre ellos. En uno, a través de la retransmisión, elimine las etiquetas de pod / instancia y, en el otro, déjelo como está.



Ventajas: más económico: solo necesita implementar ServiceMonitor, más fácil de mantener.



Contras: una implementación de operaciones con la que los desarrolladores no estaban familiarizados.



Recopilación de métricas en Prometheus mediante un segundo ServiceMonitor







Cómo falló la solución Pushgateway



Primera solución. Para empezar, elegimos la implementación obvia a través de Pushgateway. Recogimos Pushgateway, enviamos métricas allí y usamos una constante como etiqueta de instancia. La solicitud se parecía a esto:



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





Hicimos frente rápidamente a la tarea y, al principio, el resultado fue agradable: se recopilaron las métricas, pero la dimensión no creció. Pero pronto comenzamos a notar grandes lagunas en las métricas de algunas mecánicas. Al mismo tiempo, se trazó un patrón extraño: cuando para algunos mecánicos la métrica se transmitía correcta y continuamente, para otros, comenzaron las fallas. Esto dio la impresión de que solo un grupo de mecánicos informaba a la vez. Había varios de esos grupos y no cambiaban sin ningún orden en particular.



¿Por qué no funcionó?Cualquiera que esté familiarizado con el dispositivo Pushgateway probablemente supiera de inmediato que nuestra solución no estaba funcionando. En Pushgateway, las etiquetas se pasan de dos formas: a través de la ruta de la solicitud o en el cuerpo de la solicitud. En este caso, el conjunto de etiquetas y sus valores que se pasan a través de la ruta actúan como clave para el diccionario donde se almacenan las métricas. Todo lo que se pasó a través del cuerpo de la solicitud entra en el valor mediante esta clave. Es decir, en nuestro caso, cada solicitud de un pod sobrescribe todas las métricas que se enviaron desde otros pods. Dado que Prometheus recopila métricas a intervalos, solo se incluyeron las métricas del grupo que fue el último en enviarse.



Para enviar métricas correctamente a Pushgateway, tendría que escribir código C # personalizado. Pero tal solución no era fácil ni barata, por lo que se abandonó.



Segunda solución. Decidimos aferrarnos a Pushgateway nuevamente: recopilar métricas iniciales y empujar con todas las etiquetas, y luego eliminar la etiqueta del pod utilizando ServiceMonitor, que recopila métricas de Pushgateway. Pero ya al principio, nos dimos cuenta de que la idea no funcionaría.



Por qué no implementado.Pushgateway tiene varias características que hacen que esta solución sea imposible. Principal: los datos no se borran automáticamente por retención. Esto significa que debe realizar un seguimiento del tamaño del disco y escribir el código de limpieza manualmente. Otro problema es que después de la retransmisión, las métricas con el mismo conjunto de etiquetas, pero con una etiqueta de pod diferente, entrarán en conflicto. Como resultado, solo la última métrica permanecerá en el orden de Pushgateway. En este caso, las métricas no se ordenan por la fecha de la última modificación, sino por orden alfabético. Por lo tanto, al diseñar, es posible que los valores de las nuevas cápsulas no entren en Prometheus.



Cómo funcionó la solución con el segundo ServiceMonitor



Volvimos a nuestro segundo diseño original e hicimos dos ServiceMonitor. Adicionalmente, se colocó una etiqueta especial en el código (en nuestro caso, negocio) para aquellas métricas cuya dimensión estamos reduciendo:



  • en un ServiceMonitor, se eliminaron todas las métricas con una etiqueta especial y el resto se dejó como estaba;
  • por otro lado, solo se dejaron las métricas con una etiqueta especial y se eliminaron las etiquetas de pod e instancia.


Hicimos todo a través de la retransmisión, agregamos el código a la configuración del primer ServiceMonitor:



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

      
      





Se agregó lo siguiente a la configuración del segundo ServiceMonitor:



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

      
      





Lo que aprendimos de la historia de la búsqueda de soluciones.



  1. Ni Pushgateway directamente ni retransmitir en él son adecuados para reducir la dimensión de las métricas.
  2. Si usa la retransmisión, las métricas con el mismo conjunto de etiquetas no deben informarse simultáneamente desde diferentes grupos.
  3. El segundo ServiceMonitor es una "muleta" que es fácil y rápida de implementar si no desea desperdiciar recursos en la federación.
  4. La mejor solución para la reducción de la dimensionalidad es la federación:

    • Prometeo de baja retención,
    • recopilar agregados (reglas de registro),
    • enviado a Prometeo con alta retención.


Yuri Sokolov, desarrollador



All Articles