DogStatsD funciona enviando al Agent métricas generadas por tu aplicación, a través de un protocolo de transporte. Este protocolo puede ser UDP (protocolo de datagrama de usuario) o UDS (socket de dominio UNIX).
Cuando se utiliza DogStatsD para enviar un gran volumen de métricas a un único Agent, si no se toman las medidas adecuadas, es frecuente encontrar los siguientes síntomas:
Uso elevado de CPU por parte del Agent
Datagramas y métricas perdidos
La biblioteca cliente de DogStatsD (UDS) devuelve errores
La mayoría de las veces los síntomas pueden aliviarse modificando algunas opciones de configuración que se describen a continuación.
Algunos clientes de StatsD y DogStatsD envían, por defecto, una métrica por cada datagrama. Esto añade una sobrecarga considerable al cliente, al sistema operativo y al Agent. Si tu cliente admite el almacenamiento en buffer de varias métricas en un datagrama, la activación de esta opción aporta mejoras notables.
Si utilizas un cliente de DogStatsD comunitario, compatible con el almacenamiento en búfer, asegúrate de configurar un tamaño máximo de datagrama que no supere el tamaño de buffer por datagrama en el Agent (8 KB por defecto, configurable en el Agent con (dogstatsd_buffer_size) y el tamaño máximo por datagrama en la red o el sistema operativo.
Por defecto, la biblioteca Golang oficial de Datadog DataDog/datadog-go utiliza el almacenamiento en búfer. El tamaño de cada paquete y el número de mensajes utilizan diferentes valores por defecto para UDS y UDP. Para obtener más información sobre la configuración del cliente, consulta Datadog/Datadog-go.
packagemainimport("log""github.com/DataDog/datadog-go/v5/statsd")funcmain(){// In this example, metrics are buffered by default with the correct default configuration for UDP.
statsd,err:=statsd.New("127.0.0.1:8125")iferr!=nil{log.Fatal(err)}statsd.Gauge("example_metric.gauge",1,[]string{"env:dev"},1)}
Cuando se utiliza la biblioteca Python oficial de Datadog datadogpy, el ejemplo siguiente utiliza un cliente de DogStatsD almacenado en búfer que envía métricas en un número mínimo de paquetes. El vaciado automático del almacenamiento se realiza al límite de tamaño de paquete y cada 300ms (configurable).
desdeDatadogimportarDogStatsd# Cuando se utiliza el cliente v0.43.0 o posteriordsd=DogStatsd(host="127.0.0.1",port=8125,disable_buffering=False)dsd.gauge('example_metric.gauge_1',123,tags=["environment:dev"])dsd.gauge('example_metric.gauge_2',1001,tags=["environment:dev"])dsd.flush()# Optional manual flush# Cuando se utiliza el cliente anterior a v0.43.0, el gestor de contextos es necesario para utilizar el almacenamiento en buffer dsd=DogStatsd(host="127.0.0.1",port=8125)condsd:dsd.gauge('example_metric.gauge_1',123,tags=["environment:dev"])dsd.gauge('example_metric.gauge_2',1001,tags=["environment:dev"])
Por defecto, las instancias del cliente Python de DogStatsD (incluyendo la instancia global statsd) no pueden ser compartidas entre procesos, pero son thread-safe. Debido a esto, el proceso principal y cada proceso secundario deben crear sus propias instancias de cliente o el almacenamiento en búfer debe ser explícitamente deshabilitado configurando disable_buffering como True. Para ver más detalles, consulta la documentación sobre datadog.dogstatsd.
Cuando de utiliza la biblioteca Ruby oficial de Datadog [dogstatsd-ruby][1], el siguiente ejemplo crea una instancia de cliente de DogStatsD almacenada en búfer que envía métricas en un paquete cuando se activa el vaciado:
Cuando se utiliza la biblioteca Java oficial de Datadog java-dogstatsd-client, el ejemplo siguiente crea una instancia de cliente de DogStatsD almacenada en buffer, con un tamaño máximo de paquete de 1500 bytes, lo que significa que todas las métricas enviadas desde esta instancia del cliente se almacenan en buffer y se envían en paquetes con una extensión de paquete de 1500 como máximo:
Cuando se utiliza la biblioteca C# oficial de Datadog dogstatsd-csharp-client, el siguiente ejemplo crea un cliente DogStatsD con UDP como transporte:
usingStatsdClient;publicclassDogStatsdClient{publicstaticvoidMain(){vardogstatsdConfig=newStatsdConfig{StatsdServerName="127.0.0.1",StatsdPort=8125,};using(vardogStatsdService=newDogStatsdService()){if(!dogStatsdService.Configure(dogstatsdConfig))thrownewInvalidOperationException("Cannot initialize DogstatsD. Set optionalExceptionHandler argument in the `Configure` method for more information.");// Counter and Gauge are sent in the same datagramdogStatsdService.Counter("example_metric.count",2,tags:new[]{"environment:dev"});dogStatsdService.Gauge("example_metric.gauge",100,tags:new[]{"environment:dev"});}}}
Cuando de utiliza la biblioteca PHP oficial de Datadog php-datadogstatsd, el siguiente ejemplo crea una instancia de cliente de DogStatsD almacenada en búfer que envía métricas en un paquete cuando se completa el bloque:
Es posible reducir el tráfico desde tu cliente de DogStatsD al Agent configurando un valor de tasa de muestreo para tu cliente. Por ejemplo, una frecuencia de muestreo de mitades de 0.5 reduce a la mitad el número de paquetes UDP enviados. Esta solución es un intercambio, ya que reduces el tráfico pero al mismo tiempo pierdes un poco de precisión y granularidad.
UDS es un protocolo de comunicación inter-proceso utilizado para transportar cargas útiles de DogStatsD. Tiene poca sobrecarga, en comparación con el UDP, y reduce la huella general de DogStatsD en tu sistema.
Las bibliotecas de cliente pueden agregar métricas en el lado del cliente, lo que reduce el número de mensajes que deben enviarse al Datadog Agent y mejora el rendimiento de E/S.
La agregación del lado del cliente está disponible en java-dogstatsd-client versión 2.11.0 y posteriores, y está activada por defecto a partir de la versión 3.0.0.
La agregación del lado del cliente está disponible en el cliente de C# de DogStatsD v7.0.0 y posteriores, y está activada por defecto. La agregación del lado del cliente está disponible para indicadores, contadores y conjuntos.
Si tu servidor DogStatsD utiliza UDS y está perdiendo paquetes a un alto rendimiento, configurar el servidor para utilizar más CPU puede mejorar la velocidad de procesamiento y disminuir la pérdida de paquetes.
También puedes configurar tu servidor DogStatsD si la telemetría del cliente indica pérdidas de paquetes y el servidor no utiliza más de 2 CPU o 2 núcleos, aunque estén disponibles.
Para reducir la cantidad de pérdidas de paquetes:
Aumenta el tamaño de la cola de clientes a 8192. Para obtener más información, consulta la configuración de la biblioteca cliente. Puede que veas disminuir la cantidad de pérdidas y que tu aplicación utilice más RAM.
Además, puedes activar la función dogstatsd_pipeline_autoadjust: true en la configuración de tu Datadog Agent. El Agent utiliza varios núcleos para procesar métricas personalizadas, lo que puede suponer un mayor uso de CPU, pero reducir las pérdidas de paquetes.
La mayoría de los sistemas operativos añaden datagramas UDP y UDS entrantes, que contienen tus métricas, a un buffer con un tamaño máximo. Una vez alcanzado el máximo, los datagramas que contienen tus métricas empiezan a ser descartados. Es posible ajustar los valores para dar al Agent más tiempo para procesar las métricas entrantes:
En la mayoría de las distribuciones de Linux, el tamaño máximo del buffer de kernel está configurado por defecto en 212992 (208 KiB). Esto puede confirmarse utilizando los siguientes comandos:
Para los sockets UDS, Linux almacena en buffer internamente los datagramas de una cola, si el lector es más lento que el escritor. El tamaño de esta cola representa el número máximo de datagramas que Linux almacena en buffer por cada socket. Este valor se puede consultar con el siguiente comando:
sysctl net.unix.max_dgram_qlen
Si el valor es menor a 512, puedes aumentarlo a 512 o más, utilizando el siguiente comando:
sysctl -w net.unix.max_dgram_qlen=512
Añade la siguiente configuración a /etc/sysctl.conf, para que este cambio sea permanente:
net.unix.max_dgram_qlen = 512
De la misma manera, net.core.wmem_max podría incrementarse a 4MiB, para mejorar
el rendimiento de escritura del cliente:
net.core.wmem_max = 4194304
A continuación, configura la opción dogstatsd_so_rcvbuf del Agent con el mismo número en datadog.yaml:
Si estás utilizando Kubernetes para desplegar el Agent o DogStatsD, y quieres configurar los sysctls, como se mencionó anteriormente, configura su valor por cada contenedor. Si el sysctlsnet.* incluye espacios de nombre, puedes configurarlos por cada pod. Consulta la documentación de Kubernetes en Uso de sysctls en un clúster de Kubernetes.
Evita el uso extra de CPU enviando paquetes con un tamaño adecuado al servidor DogStatsD en el Datadog Agent. Las últimas versiones de los clientes oficiales de DogStatsD envían paquetes con un tamaño optimizado para el rendimiento.
Puedes saltarte esta sección, si utilizas uno de los últimos clientes de DogStatsD de Datadog.
Si los paquetes enviados son demasiado pequeños, el Datadog Agent agrupa varios de ellos para procesarlos por lotes en el pipeline más adelante. Los clientes oficiales de DogStatsD son capaces de agrupar métricas para tener la mejor proporción de número de métricas por paquete.
El rendimiento del Datadog Agent es óptimo si los clientes de DogStatsD envían paquetes del tamaño de dogstatsd_buffer_size. Los paquetes no deben ser mayores que el tamaño de buffer, de lo contrario, el Agent no podrá cargarlos completamente en el buffer sin que las métricas se generen incorrectamente. Utiliza el campo de configuración correspondiente en tus clientes de DogStatsD.
Nota para UDP: Dado que los paquetes UDP suelen atravesar la capa Ethernet e IP, puedes evitar la fragmentación de paquetes IP limitando el tamaño del paquete a un valor inferior al de un solo marco Ethernet en tu red. La mayoría de las veces, las redes IPv4 se configuran con una MTU de 1500 bytes, por lo que en esta situación el tamaño de los paquetes enviados debe limitarse a 1472.
Nota para UDS: Para obtener los mejores rendimientos, el tamaño del paquete UDS debe ser de 8192 bytes.
El Agent intenta absorber la ráfaga de métricas enviadas por los clientes de DogStatsD, pero para ello necesita utilizar memoria. Aunque sea por poco tiempo y aunque esta memoria se libere rápidamente al sistema operativo, se produce un pico y esto podría ser un problema en entornos contenedorizados, donde el límite de uso de memoria podría desalojar pods o contenedores.
Evita enviar métricas en ráfagas en tu aplicación. Esto evita que el Datadog Agent alcance su uso máximo de memoria.
Otra cosa que necesitas tener en cuenta para limitar el uso máximo de memoria es reducir el almacenamiento en buffer. El buffer principal del servidor DogStatsD en el Agent es configurable con el campo dogstatsd_queue_size (a partir del Datadog Agent v6.1.0). Su valor por defecto de 1024 induce un uso máximo aproximado de memoria de 768MB.
Nota: Reducir el tamaño de buffer podría aumentar el número de paquetes perdidos.
En este ejemplo se reduce el uso máximo de memoria de DogStatsD a aproximadamente 384MB:
dogstatsd_queue_size:512
Consulta la siguiente sección sobre detección de ráfagas, para ayudar a detectar ráfagas de métricas en tus aplicaciones.
DogStatsD tiene un modo de estadísticas en el que puedes ver qué métricas son las más procesadas.
Nota: La activación del modo de estadísticas de métricas puede disminuir el rendimiento de DogStatsD.
Para activar el modo de estadísticas, puedes:
Configurar dogstatsd_stats_enable como true en tu archivo de configuración
Configurar la variable de entorno DD_DogStatsD_STATS_ENABLE como true
Utiliza el comando datadog-agent config set dogstatsd_stats true para activarlo durante el tiempo de ejecución. Puedes desactivarlo durante el tiempo de ejecución, utilizando el comando datadog-agent config set dogstatsd_stats false.
Cuando este modo está activado, ejecuta el comando datadog-agent dogstatsd-stats. Las métricas recibidas devuelven una lista de métricas procesadas en orden descendente.
Mientras funciona en este modo, el servidor DogStatsD ejecuta un mecanismo de detección de ráfagas. Si se detecta una ráfaga, se emite un log de advertencia Por ejemplo:
Una ráfaga de métricas ha sido detectada por DogStatsD: el siguiente es el recuento de los últimos 5 segundos de métricas: [250 230 93899 233 218]
Los clientes de DogStatsD por defecto envían métricas de telemetría al Agent. Esto te permite localizar mejor los cuellos de botella y resolverlos. Cada métrica se etiqueta con el idioma del cliente y la versión del cliente. Estas métricas no se contabilizan como métricas personalizadas.
Cada cliente comparte un conjunto de etiquetas (tags) comunes.
Etiqueta
Descripción
Ejemplo
client
Idioma del cliente
client:py
client_version
Versión del cliente
client_version:1.2.3
client_transport
Transporte utilizado por el cliente (udp o uds)
client_transport:uds
Nota: Cuando se utiliza UDP, los errores de red no pueden ser detectados por el cliente y las métricas correspondientes no reflejan pérdidas de bytes o de paquetes.
Para obtener más información sobre la configuración del cliente, consulta DataDog/dogstatsd-ruby.
A partir de la versión 3.4.0 del cliente Go.
datadog.dogstatsd.client.metrics
Tipo de métrica: recuento Número de metrics enviadas al cliente de DogStatsD por tu aplicación (antes del muestreo y la agregación).
datadog.dogstatsd.client.metrics_by_type
Tipo de métrica: recuento Número de metrics enviadas por el cliente de DogStatsD, antes del muestreo y la agregación, etiquetadas por tipo de métrica (gauge,
set, count, timing, histogram o distribution). A partir de la versión 5.0.0 del cliente Go.
datadog.dogstatsd.client.events
Tipo de métrica: recuento Número de events enviados al cliente de DogStatsD por tu aplicación.
datadog.dogstatsd.client.service_checks
Tipo de métrica: recuento Número de service_checks enviados al cliente de DogStatsD por tu aplicación.
datadog.dogstatsd.client.bytes_sent
Tipo de métrica: recuento Número de bytes enviados correctamente al Agent.
datadog.dogstatsd.client.bytes_dropped
Tipo de métrica: recuento Número de bytes descartados por el cliente de DogStatsD (esto incluye datadog.dogstatsd.client.bytes_dropped_queue
y datadog.dogstatsd.client.bytes_dropped_writer).
datadog.dogstatsd.client.bytes_dropped_queue
Tipo de métrica: recuento Número de bytes descartados porque la cola de clientes de DogStatsD estaba llena.
datadog.dogstatsd.client.bytes_dropped_writer
Tipo de métrica: recuento Número de bytes perdidos por un error al escribir en Datadog, debido a un tiempo de espera o un error de red.
datadog.dogstatsd.client.packets_sent
Tipo de métrica: recuento Número de datagramas enviados correctamente al Agent.
datadog.dogstatsd.client.packets_dropped
Tipo de métrica: recuento Número de datagramas descartados por el cliente de DogStatsD (esto incluye datadog.dogstatsd.client.packets_dropped_queue
y datadog.dogstatsd.client.packets_dropped_writer).
datadog.dogstatsd.client.packets_dropped_queue
Tipo de métrica: recuento Número de datagramas descartados porque la cola de clientes de DogStatsD estaba llena.
datadog.dogstatsd.client.packets_dropped_writer
Tipo de métrica: recuento Número de bytes perdidos por un error al escribir en Datadog, debido a un tiempo de espera o un error de red.
Tipo de métrica: recuento Número de métricas perdidas porque el canal de recepción interno estaba lleno (cuando se utiliza WithChannelMode()). A partir
de la versión 3.6.0 del cliente de Go, cuando WithChannelMode() está habilitado.
datadog.dogstatsd.client.aggregated_context
Tipo de métrica: recuento
Número total de contextos vaciados por el cliente, cuando la agregación del lado del cliente está habilitada. A partir de la versión 5.0.0
del cliente de Go. Esta métrica sólo se informa cuando la agregación está habilitada (opción predeterminada).
Tipo de métrica: recuento
Número total de contextos vaciados por el cliente, cuando la agregación del lado del cliente está habilitada, etiquetados por tipo de métrica
(gauge, set, count, timing, histogram o distribution). A partir de la versión 5.0.0 del cliente de Go. Esta métrica
sólo se informa cuando la agregación está habilitada (opción predeterminada).
Para desactivar la telemetría, utiliza el parámetro WithoutTelemetry:
Tipo de métrica: recuento
Número de contextos agregados por tipo cuando la agregación del lado del cliente está activada. A partir de la versión v2.13.0. La métrica está habilitada por defecto a partir de la versión v3.0.0 pero requiere enableDevMode(true) para v2.13.0. La métrica está etiquetada por metrics_type.
datadog.dogstatsd.client.metrics_by_type
Tipo de métrica: recuento Número de métricas enviadas al cliente de DogStatsD por tu aplicación, etiquetadas por tipo (antes del muestreo). A partir de la versión v2.13.0, cuando se utiliza enableDevMode(true), y por defecto, a partir de v3.0.0. La métrica está etiquetada por metrics_type.
Para desactivar la telemetría, utiliza la opción del creador enableTelemetry(false):
A partir de la versión 1.5.0 del cliente de PHP la telemetría está activada
por defecto, para el cliente de BatchedDogStatsd, y está desactivada por defecto, para el
cliente de DogStatsd.
datadog.dogstatsd.client.metrics
Tipo de métrica: recuento Número de metrics enviadas al cliente de DogStatsD por tu aplicación (antes del muestreo).
datadog.dogstatsd.client.events
Tipo de métrica: recuento Número de events enviados al cliente de DogStatsD por tu aplicación.
datadog.dogstatsd.client.service_checks
Tipo de métrica: recuento Número de service_checks enviados al cliente de DogStatsD por tu aplicación.
datadog.dogstatsd.client.bytes_sent
Tipo de métrica: recuento Número de bytes enviados correctamente al Agent.
datadog.dogstatsd.client.bytes_dropped
Tipo de métrica: recuento Número de bytes descartados por el cliente de DogStatsD.
datadog.dogstatsd.client.packets_sent
Tipo de métrica: recuento Número de datagramas enviados correctamente al Agent.
datadog.dogstatsd.client.packets_dropped
Tipo de métrica: recuento Número de datagramas descartados por el cliente de DogStatsD.
Para activar o desactivar la telemetría, utiliza el argumento disable_telemetry. Atención,
utilizar telemetrías con clientes de DogStatsd incrementa el uso de red
significativamente. Se aconseja utilizar el BatchedDogStatsd cuando se utiliza la telemetría.
Tipo de métrica: recuento Número de contextos agregados por tipo cuando la agregación del lado del cliente está activada. A partir de la versión 7.0.0.
Para desactivar la telemetría, configura TelemetryFlushInterval como null: