Skip to main content

Propagación de Contexto

Si analizamos cuál es el flujo de un span hasta llegar a su destino, tenemos esto.

alt text

La instrumentación no afecta mucho a la aplicación, ya que el coste de CPU y memoria es muy bajo. Todo se hace de forma muy rápida y no hay muchas cosas que podamos mejorar, aparte de evitar la creación de spans indeseados para generar costes como mencionamos antes.

En el otro extremo tenemos el backend que es un servicio externo con recursos totalmente separados que no interfiere en nada nuestra aplicación.

El exporter es responsable de transformar los spans al formato adecuado y coordinar su envío al backend siendo responsable de la actividad de red del proceso. Puede trabajar con spans individuales o en lotes.

El procesamiento (Span Processor) es un componente importante en el flujo de OpenTelemetry que actúa como intermediario entre la instrumentación (donde se crean los spans) y el exporter (que envía los datos al backend). Gestiona el ciclo de vida de los spans. El Span Processor es crucial para garantizar rendimiento y fiabilidad en el procesamiento de los datos de telemetría, actuando como un buffer inteligente entre la generación y el envío de los datos. Actúa íntegramente en memoria (sin persistencia en disco) y mantiene una cola para almacenar los spans. El tamaño de esa cola puede ser configurable, sin embargo, si la cola está llena, nuevos spans serán descartados.

Entonces tenemos:

  • Instrumentación
    • Impacto muy bajo, ya que son básicamente interceptaciones ligeras
    • Usa recursos mínimos ya que solo recoge datos
    • El overhead principal viene de la creación de los spans y sus atributos
    • En general no bloquea el flujo principal de la aplicación
  • Procesamiento (SpanProcessor)
    • Impacto moderado, ya que maneja los spans en memoria
    • El BatchSpanProcessor puede consumir más memoria debido al buffer
    • Puede haber contención si la cola se llena
    • El procesamiento es asíncrono, por lo que no bloquea el hilo principal
  • Exporter
    • Impacto moderado a alto dependiendo de la configuración
    • El envío de datos por la red es la operación más "pesada"
    • Puede haber contención si el backend está lento
    • Problemas de red pueden afectar al procesamiento de los spans
  • Backend
    • Impacto mínimo en la aplicación, ya que es un sistema separado
    • La única interferencia sería si comienza a rechazar datos
    • Problemas de latencia del backend pueden afectar al exporter
    • En general no afecta al rendimiento de la aplicación directamente

Sobre el procesamiento tenemos dos tipos.

  • SimpleSpanProcessor: no mantiene cola, cada span se procesa inmediatamente, usa menos memoria pero es menos eficiente.
  • BatchSpanProcessor: se crea un buffer y una cola para procesamiento y es lo que debemos usar en producción.

Sabiendo esto, podemos entender que si la aplicación se para, todo lo que estaba en memoria también se perderá y el consumo de memoria necesita ser monitorizado. En caso de no conseguir entregar al backend, la memoria puede crecer rápidamente.

Simple vs Batch

El BatchSpanProcessor es significativamente más eficiente que el SimpleSpanProcessor, especialmente en escenarios de alta carga.

CaracterísticaSimpleSpanProcessorBatchSpanProcessorObservaciones
Patrón de ProcesamientoProcesa y exporta cada span individualmenteAgrupa spans en lotes antes de exportarBatchSpanProcessor reduce significativamente el overhead de red
Throughput~100-1000 spans/segundo~10000-100000 spans/segundoBatchSpanProcessor puede ser 100x más eficiente
Llamadas de RedUna llamada por spanUna llamada por batch (ej: 512 spans)Reducción de hasta 99.8% en las llamadas de red con BatchSpanProcessor
Latencia100ms por span (asumiendo 100ms de latencia de red)~0.2ms por span (100ms/512 spans)BatchSpanProcessor distribuye el coste de la latencia entre todos los spans del batch
Uso de CPUAlto (overhead por span)Bajo (overhead compartido)Reducción de hasta 90% en el overhead de CPU con BatchSpanProcessor
Uso de MemoriaBajo (sin buffer)Moderado (buffer configurable)BatchSpanProcessor usa más memoria pero es controlable vía maxQueueSize
Back PressureNo poseePosee (vía maxQueueSize)BatchSpanProcessor puede controlar sobrecarga del sistema
Caso de UsoDesarrollo y DebugProducciónSimpleSpanProcessor no se recomienda para producción
FiabilidadMenor (más susceptible a fallos de red)Mayor (mejor tolerancia a fallos)BatchSpanProcessor tiene retry y buffer
ConfigurabilidadMínimaAlta (batch size, queue size, delay, etc)BatchSpanProcessor ofrece más control
Pérdida de DatosPierde solo el span actual en procesamientoPierde el Buffer completo (debido al buffer)BatchSpanProcessor puede preservar spans en memoria
DebugMás fácil (comportamiento directo)

Verifica en el SDK creado qué tipo de processor se utiliza y cámbialo si es necesario al batch. Es interesante configurar algunas variables que definen sus límites.

Podemos configurar pasando variables de entorno o definiendo vía código.

  • OTEL_BSP_MAX_EXPORT_BATCH_SIZE (Por defecto 512): El número máximo de spans que puede ser enviado al backend de una vez. Es bueno que sea grande, pero no tan grande ya que el tiempo de descarga y subida irá aumentando de acuerdo con el tamaño. En este caso enviará hasta 512 spans a la vez.

  • OTEL_BSP_MAX_QUEUE_SIZE (Por defecto 2048):

    • Es el número máximo de spans en la cola. Si supera 2048 será descartado.
  • OTEL_BSP_SCHEDULE_DELAY (Por defecto 5000, 5s)

    • Cada 5 segundos el procesador intenta exportar los spans acumulados. Si no hay spans en el buffer, nada se envía. Si hay spans, envía hasta el límite definido en OTEL_BSP_MAX_EXPORT_BATCH_SIZE.
  • OTEL_BSP_EXPORT_TIMEOUT (Por defecto 30000, 30s):

    • El exporter envía los spans al backend y espera hasta X milisegundos (ej: 30000ms = 30 segundos) por una respuesta.
    • Si el backend no responde en ese tiempo la operación se considera fallida y los spans pueden ser descartados o reintentados dependiendo de la configuración.