Ir al contenido

Elegir almacén

Diez destinos, y usar más de uno es lo normal. Todos envían por push: la herramienta está pensada para correr donde sea cómodo y alcanzar sus almacenes desde ahí, no para que la consulten. El exportador de Prometheus es la única excepción, y existe porque Prometheus insiste.

AlmacénGuardaBueno paraConfiguración
InfluxDBla historia fechada“a qué velocidad fusionábamos en julio”url, token, org, bucket
PostgreSQLla historia fechada, como SQL que pasas a psqlquien usa Grafana con un Postgres y sin InfluxDBdialect, path
Graphitela historia fechadaun Graphite que ya está ahíaddr, prefix
Elasticsearchla historia fechada, como documentosbuscar en todo lo recogidourl, prefix, api_key
Prometheusel valor actualalertas, y un número en una paredlisten, path
OpenTelemetryuna cosa u otra, según el backendun pipeline de collector ya existenteendpoint, raw
Lokilos eventos, como líneas de log“qué pasó, en orden”url, labels, max_age
Telegraflo que guarden sus salidasalcanzar todo lo que alcance Telegrafurl
Fichero y stdoutline protocol o JSONun agente de envío que ya tengas, y un búferpath, format

No hay destino para ningún proveedor gestionado concreto, y es deliberado. A un backend gestionado se llega por uno de los dos destinos que existen para eso: Telegraf, cuyas salidas cubren Datadog, New Relic, Wavefront, Azure Monitor y cien más, u OpenTelemetry, que la mayoría ya acepta directamente. Un destino por proveedor es una clave que rotar, una API que seguir y un test que necesita una cuenta de pago, para un salto que esos dos ya hacen.

Un punto lleva la fecha en que ocurrió la cosa. Una estrella se fecha cuando se dio, una ejecución de workflow cuando terminó, un día de tráfico en la fecha de ese mismo día.

InfluxDB indexa un punto por medida, conjunto de etiquetas y marca de tiempo, así que escribir la misma ventana de tráfico de catorce días cada seis horas converge en la respuesta correcta en vez de acumular copias. Eso es lo que hace funcionar todo el diseño del relleno histórico, y es por lo que InfluxDB es el destino que guarda la historia.

Prometheus no puede hacer eso. Sella una muestra en el instante del scrape y rechaza cualquier cosa apreciablemente más vieja: medido contra Prometheus 3.14 con el receptor OTLP activado y una ventana de desorden de treinta minutos, una muestra fechada dos días atrás vuelve como HTTP 400. Así que el exportador reduce las filas por elemento a valores actuales antes de servirlas.

El argumento completo, y qué le hace la reducción a cada medida, está en la fecha del punto.

Una pasada ofrece la misma historia cada vez: la ventana de tráfico de catorce días, cada pull request abierta, el calendario de contribuciones. Volver a escribirlo todo es inofensivo para lo que guarda el almacén, porque la fila se indexa por serie y marca de tiempo y simplemente se sobrescribe, y es así como se repara un colector que estuvo caído un día.

No es inofensivo para los ficheros del almacén. InfluxDB 3 Core escribe un fichero Parquet por partición y por petición de escritura, no los compacta nunca, y rechaza cualquier consulta que abriría más ficheros que su límite. Medido antes del arreglo de abajo y con el límite entonces en diez mil: gh_notification tenía poco más de una fila por fichero Parquet, y una consulta sobre catorce días volvió con “Query would scan 10000 Parquet files, exceeding the file limit”.

Pedir un intervalo más grueso no ayuda, porque el límite cuenta los ficheros que abre el planificador, antes de cualquier agregación. Así que la herramienta mantiene un pequeño registro de lo que ya ha escrito y envía solo los puntos cuyos valores se han movido:

sinks:
dedupe_file: /var/lib/ghchronicle/state-written.bin # por omisión: junto a state_file
dedupe_horizon: 720h # olvida un punto que ya nadie ofrece
influxdb:
dedupe: true # el valor por omisión, aquí y en telegraf, graphite, sql y elasticsearch

El registro guarda dos hashes de 64 bits y un día por punto, así que una cuenta grande cuesta unos pocos megabytes. Va indexado por destino, así que un almacén que estuvo inalcanzable recibe todo en su siguiente escritura. Perderlo, o poner dedupe_file: off, cuesta una pasada de reescritura y nada más, que es justo lo que quiere un almacén que se ha vaciado y hay que volver a llenar. Es el segundo fichero que conviene poner en una ruta persistente, junto al fichero de estado.

Una ejecución que termina cuando termina su pasada no abre el registro. -once, -backfill y el dibujo de una tarjeta escriben una vez y salen, así que no hay nada que guardar ni nada que podar, y cada una de ellas vuelve a ofrecer la historia entera. Para eso está el relleno histórico; y por eso una tarea programada con -once, que es la forma en que corre la Action, escribe todos los puntos cada vez. Donde eso importe, hay que correr el bucle.

El registro de la pasada dice lo que esto ha ahorrado:

level=INFO msg=written sink=influxdb family=events points=0 unchanged=300

Si los ficheros ya se han acumulado, el arreglo del escritor detiene el crecimiento pero no los quita: sube --query-file-limit en el servidor, reescribe las tablas afectadas, o pasa a InfluxDB 3 Enterprise, que compacta por su cuenta y es gratis para uso doméstico.

Es normal, y es barato: la recolección ocurre una vez y los puntos se entregan a todos los destinos configurados. La disposición habitual es un almacén de historia más uno de los de valor actual.

sinks:
influxdb:
url: http://localhost:8181
token: ${INFLUX_TOKEN}
org: default
bucket: github
prometheus:
listen: 127.0.0.1:9605
path: /metrics

Un destino que falla se registra y la pasada continúa; que una base de datos esté caída no detiene la recolección, y con el destino de fichero configurado los datos siguen en disco cuando vuelva. Dos fallos se informan de forma especial en vez de como errores, porque son éxitos parciales:

  • líneas rechazadas, donde se escribió todo lo analizable y las líneas rechazadas se registran una a una con la razón que dio el almacén.
  • entradas descartadas, que es el horizonte de antigüedad de Loki dejando fuera lo que su ventana de desorden habría rechazado, en vez de perder el envío entero.