InfluxDB
El destino InfluxDB escribe cada punto de ghchronicle, fechado cuando ocurrió, en InfluxDB 2 o 3, y es el almacén contra el que están hechos los dashboards.
sinks: influxdb: url: http://localhost:8181 token: ${INFLUX_TOKEN} org: default bucket: github batch: 5000 # exclude: [gh_job_log]Lo que va por el cable
Sección titulada «Lo que va por el cable»Line protocol enviado al endpoint de escritura v2, que sirven tanto
InfluxDB 2 como InfluxDB 3, así que un solo destino cubre ambos. El token va en
una cabecera Authorization, y org y bucket en la cadena de consulta.
La precisión es de nanosegundos, porque los puntos de tráfico son días y los de workflows son segundos y una sola precisión tiene que cubrir ambos.
Los lotes son de 5000 líneas por petición por omisión. batch lo baja para un
servidor con un límite de cuerpo menor.
Qué puede responder que los demás no
Sección titulada «Qué puede responder que los demás no»Todo lo fechado, que es casi todo el proyecto:
- El tráfico de un martes concreto, meses después.
- La curva de estrellas desde la primera, dibujada con una fila por repositorio y día.
- El tiempo de fusión de una pull request cerrada en julio.
- Líneas añadidas y quitadas por commit, por autor, a lo largo de años.
InfluxDB indexa un punto por medida, conjunto de etiquetas y marca de tiempo, así que reescribir un punto que ya existe no es un duplicado. Repetir la misma ventana de tráfico de catorce días cada seis horas converge en vez de acumular, que es lo que hace funcionar todo el diseño del relleno histórico.
Los dashboards se generan contra este almacén primero; los otros cuatro conjuntos de consultas son traducciones de él.
Reescribir sale gratis en filas y no en ficheros
Sección titulada «Reescribir sale gratis en filas y no en ficheros»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. Así que la fila que se sobrescribe sin daño cuesta de todos modos un fichero, y una pasada que ofrece la misma historia cada seis horas compra un “Query would scan 10000 Parquet files, exceeding the file limit” unas semanas después.
Por eso existe el registro de escrituras, por eso dedupe viene encendido aquí,
y por eso apagarlo es una decisión y no una limpieza:
solo se escribe lo que ha cambiado.
exclude
Sección titulada «exclude»Nombra las medidas que este destino no debe recibir. Por omisión es
gh_job_log, que es texto destinado a un almacén de logs: escribir miles de
líneas de salida de compilación en una base de datos de métricas es mucho
almacenamiento para algo que nadie va a consultar como número.
Una medida excluida se recoge igual y se le ofrece igual a este destino, así que el log de la pasada dice lo que aceptó la base de datos y no lo que se le entregó:
level=INFO msg=written sink=influxdb family=joblogs points=0 unchanged=0 filtered=440Aquí filtered es una medida nombrada arriba, o un punto que no lleva ningún
campo que el protocolo de línea pueda representar. Es la misma clave que usan
todos los destinos.
Hasta que se contó, la línea decía points=440 de una medida de la que la base
de datos no ha tenido nunca una fila.
Los tipos de columna se fijan al primer contacto
Sección titulada «Los tipos de columna se fijan al primer contacto»Líneas rechazadas
Sección titulada «Líneas rechazadas»Una escritura que vuelve 400 se biseca: el destino parte el lote por la mitad, reintenta y acota hasta las líneas concretas que el servidor se niega a analizar. Esas se registran una a una con la razón del propio servidor, todo lo demás se escribe, y la pasada informa de un aviso y no de un fallo.
level=WARN msg="sink rejected some lines" sink=influxdb family=actions rejected=2Ese comportamiento importa porque un lote son cinco mil líneas. Fallar el lote entero por un valor malformado perdería cuatro mil novecientos noventa y nueve puntos buenos.
Grafana
Sección titulada «Grafana»Usa el datasource de InfluxDB 3 en modo SQL para el dashboard incluido, y
apúntalo a la base de datos en la que escribe el destino. El fichero del dashboard
declara DS_INFLUXDB como entrada, así que al importarlo te pide elegir tu
propio datasource en vez de arrastrar el uid de otra persona.
SELECT time, "count" FROM gh_traffic WHERE kind = 'views' AND repo = 'ghchronicle'Qué hace aquí una migración
Sección titulada «Qué hace aquí una migración»Cuando una versión cambia aquello por lo que se identifican las filas de una
medida, -migrate pregunta
al catálogo de InfluxDB 3 si la etiqueta antigua es una columna de etiqueta de
la tabla viva, y aplicar el cambio borra esa única tabla:
DELETE /api/v3/configure/table?db=<bucket>&table=<medida>Ese borrado es la manera propia de InfluxDB de apartar una tabla. Medido
contra InfluxDB 3 Core de la 3.0.0 a la 3.11.5: la tabla se renombra
<medida>-<instante>, el instante en UTC, por ejemplo
gh_discussion_comment-20261001T091004, sigue listada y responde a consultas
con ese nombre, y la siguiente escritura con el nombre antiguo crea la tabla de
nuevo, con la forma nueva, aunque una columna pase de etiqueta a campo. El
binario lee el nombre del catálogo, lo imprime y lo guarda en el fichero de
estado, con cuándo ha programado el servidor su borrado definitivo, leído de la
tabla de sistema de su base de datos _internal. Eso es 72 horas después del
borrado (medido de la 3.2.1 a la 3.11.5), y el servidor guarda el nombre en su
catálogo durante su --delete-grace-period después de eso, 24 horas por
omisión; donde no se puede leer la hora, entre ellos la 3.2.0, se suponen 72
horas, que es lo que programa también la 3.2.0. Un servidor anterior a la 3.2
no la purga nunca: ver más abajo.
ghchronicle deja la copia al servidor, y la olvida cuando llega la hora del
servidor. Nunca pide que se vaya antes: hard_delete_at no se envía nunca,
porque medido en la 3.11.5 now no había quitado las filas once minutos
después, y se lleva los días para deshacer el cambio; y desde la 3.10.0 un
borrado de la tabla renombrada recibe un 409, con hard_delete_at o sin él
(medido de la 3.10.0 a la 3.11.5). Hasta entonces las filas de la copia se
pueden leer con SQL y escribir de vuelta a través del destino.
InfluxDB 3 Core rechaza una consulta que abriría más ficheros Parquet que su
--query-file-limit, 432 por omisión, que una tabla escrita cada diez minutos
supera en días. La comprobación lee el catálogo, que no abre ninguno, y cuenta
las filas solo de una tabla que guarda la etiqueta antigua; un recuento que
Core rechaza deja la relectura sin límite, y una lectura rechazada de quién son
las filas de la tabla deja el cambio necesitando tu palabra, con el rechazo
citado en el plan. Ver el límite de ficheros por
consulta.
El token tiene que poder borrar una tabla. Un borrado rechazado deja el cambio pendiente, y el error nombra la misma petición para enviarla a mano.
InfluxDB 2 no tiene renombrado. Aplicar el cambio allí borra todas las filas de
la medida en el bucket, en todos los instantes que puede guardar, con
POST /api/v2/delete y el predicado _measurement="<medida>", y eso es
definitivo. Medido contra InfluxDB 2.7.12: se llevó esa medida y dejó como
estaban gh_discussion_comment_x, las demás medidas del bucket y la misma
medida en otro bucket. Por eso un arranque nunca lo aplica por su cuenta;
-migrate -yes sí.
-uninstall data deja fuera las tablas que InfluxDB 3 ya ha borrado, y dice
de cada una si la purga el servidor o se queda: en un servidor anterior a la
3.2 se quedan todas, y en uno posterior cada una que borró una versión anterior
a la 3.2, preguntado a la tabla de sistema del servidor, con la petición que la
quita donde la versión la acepta (ver más
abajo). Las demás le toca purgarlas al
servidor, y solo de una versión desde la 3.10 se dice que se niega a que se le
pida antes. La tabla de sistema de la 3.2.0 no puede decir cuáles, y allí la
nota lo dice.
Antes de la 3.2 la copia se queda
Sección titulada «Antes de la 3.2 la copia se queda»Medido contra InfluxDB 3 Core 3.0.0, 3.0.3 y 3.1.0, ninguna de las cuales
tiene borrado definitivo: no corre ningún borrador, hard_delete_at se acepta
y se ignora, _internal no tiene system.tables, y un borrado de la tabla
renombrada responde 200 y la renombra otra vez,
<medida>-<instante>-<instante>. La copia se queda, y responde a consultas,
mientras el servidor ejecute una de esas versiones. La 3.2.0 es la primera
versión con borrador: en la 3.2.0 y la 3.3.0 se midió que programan un borrado
definitivo y lo llevan a cabo como la 3.4.0 y las siguientes.
El binario lee la versión de /ping, y en un servidor anterior a la 3.2 lo dice
donde importa: el plan dice set aside for good antes de aplicar nada, aplicar
lo dice con el nombre de la copia, y -migrate lista cada copia que guarda un
servidor así como kept aside ... for good, preguntándoselo al propio
servidor, de modo que la lista incluye una copia que el fichero de estado ha
olvidado, o que un fichero de estado nuevo nunca conoció. -uninstall data
dice lo mismo de cada tabla que borra allí. Cada una termina en la petición que
quita la copia en cuanto el servidor ejecute una versión que la acepte:
curl -X DELETE '<url>/api/v3/configure/table?db=<bucket>&table=<copia>&hard_delete_at=now' \ -H 'Authorization: Bearer <token>'Una copia hecha antes de la 3.2 no gana hora de borrado definitivo al
actualizar: medido con copias hechas por la 3.0.3 y la 3.1.0, abiertas por la
3.2.0, la 3.4.0, la 3.9.13 y la 3.11.5. Así que también se queda después de
actualizar, hasta que se le diga que se vaya. La 3.2.0, la 3.4.0 y la 3.9.13
aceptaron la petición para una copia así y la quitaron de su catálogo al pasar
su periodo de gracia de borrado, la 3.2.0 después de renombrarla otra vez; de
la 3.10.0 a la 3.11.5 responden con un 409. Así que la petición se envía
mientras el servidor ejecuta una versión de la 3.2 a la 3.9, de camino hacia
arriba. Desde la 3.2.1, -migrate lista las copias que la tabla de sistema
muestra sin hora de borrado definitivo, que es como se ve allí una copia así, y
-uninstall data dice que cada una se queda, con esa petición donde la versión
la acepta (medido en la 3.4.0 con una copia hecha por la 3.1.0). La tabla de
sistema de la 3.2.0 no tiene esa columna, y responde a la pregunta con un 500,
así que en la 3.2.0 -migrate no lista ninguna y -uninstall data dice que no
lo sabe. Medido también: la 3.11.5, arrancada sobre el directorio de datos
de una 3.0.3, empezó con un catálogo vacío, mientras que la 3.4.0 y la 3.9.13
leyeron los catálogos que habían dejado la 3.0.3 y la 3.1.0.
Por dónde seguir
Sección titulada «Por dónde seguir»- Elegir almacén compara InfluxDB con los demás, y lleva el registro de escrituras que todos comparten.
- Los dashboards dice cuál de los cinco se dibuja contra cada almacén, y en qué se convierte un panel que un almacén no puede responder.