Observabilidad de datos: frescura, volumen, esquema y linaje
Un pipeline de datos falla en silencio: la tabla existe, pero llega tarde, incompleta o con otro esquema. Cómo medir frescura, volumen, esquema, distribución y linaje, y gestionarlos como un servicio con SLO.
Los equipos de operaciones saben cuándo cae una aplicación: el monitoreo lo detecta y alguien recibe una alerta. Con los datos pasa algo distinto. Un pipeline puede terminar "bien" y aun así dejar una tabla con la mitad de las filas, con datos de ayer o con una columna que cambió de tipo. Nadie recibe una alerta. Lo descubre el área de negocio cuando un tablero muestra un número raro o, peor, cuando un modelo o un reporte regulatorio ya usó esos datos.
La observabilidad de datos aplica a los pipelines la misma disciplina que aplicamos a los servicios: señales definidas, objetivos medibles, alertas con dueño y gestión de incidentes. No requiere una plataforma específica para empezar. Requiere decidir qué datos importan, qué significa que estén "bien" y quién responde cuando no lo están.
Un pipeline es un servicio
Para quien lo consume, un conjunto de datos tiene las mismas propiedades que cualquier servicio: debe estar disponible cuando se necesita, ser correcto y comportarse de forma predecible. La diferencia es que las fallas de datos rara vez son ruidosas. Un servicio caído devuelve errores; una tabla incompleta devuelve resultados plausibles.
Por eso el estado del job (terminó o falló) no alcanza. Es el equivalente a vigilar que un servidor está encendido sin mirar si responde bien. En aplicaciones distinguimos qué pregunta responde cada señal, como explicamos en logs, métricas y trazas. En datos conviene hacer lo mismo: separar las señales y medir cada una donde aporta.
Las cinco señales operativas
- Frescura. Cuándo se actualizaron por última vez los datos respecto de lo que espera el consumidor. Es la señal más simple y la que más fallas detecta: cargas que no corrieron, que corrieron tarde o que procesaron un archivo viejo.
- Volumen. Cuántas filas o registros llegaron, comparado con lo habitual para ese día y hora. Una caída brusca suele indicar una fuente incompleta; un salto, duplicados.
- Esquema. Columnas agregadas, eliminadas, renombradas o con cambio de tipo. Muchos incidentes de datos empiezan con un cambio legítimo en el sistema de origen que nadie comunicó a los equipos que consumen esos datos.
- Distribución. Si los valores son razonables: proporción de nulos, valores fuera de rango, categorías nuevas, unicidad de claves. Detecta errores que no alteran ni el volumen ni el esquema.
- Linaje. Qué tablas y procesos dependen de cuáles. No es una alerta en sí, pero convierte una alerta en diagnóstico: indica de dónde viene el problema y a quién afecta. OpenLineage define un estándar abierto para capturarlo, con un modelo de trabajos, ejecuciones y conjuntos de datos que emiten eventos cada vez que un proceso corre.
Qué medir en cada etapa del pipeline
No todas las señales se miden en todas partes. Medir donde cada una aporta evita duplicar alertas y acorta el diagnóstico.
En el origen interesa detectar temprano cambios de esquema y volúmenes anómalos, antes de que entren a la plataforma. En la ingesta, la frescura de cada carga y la comparación entre filas leídas y escritas. En la transformación, las pruebas de esquema y de distribución sobre los modelos resultantes. En el consumo, la frescura y el volumen tal como los ve el tablero o el modelo, que es lo que de verdad le importa al usuario. Cuando una prueba falla en consumo, el linaje indica qué carga o qué fuente revisar primero.
Para empezar no hace falta cubrir todo el pipeline. Recomendamos elegir un número acotado de conjuntos de datos críticos (por ejemplo, entre cinco y diez), como los que alimentan reportes regulatorios o procesos de cliente, y recorrer su linaje hacia atrás hasta el origen. Ese recorrido muestra qué cargas y fuentes conviene vigilar primero, quién es dueño de cada tramo y dónde faltan pruebas. Es un inventario modesto, pero convierte una discusión abstracta sobre calidad de datos en una lista concreta de señales, umbrales y responsables.
Señales, qué detectan y umbrales de ejemplo
Los umbrales de esta tabla son ilustrativos. Cada conjunto de datos necesita los suyos, acordados con quien lo consume.
| Señal | Qué detecta | Ejemplo de umbral (ilustrativo) |
|---|---|---|
| Frescura | Cargas que no corrieron o llegaron tarde | Advertencia si la última carga tiene más de 2 horas; error si supera las 6 |
| Volumen | Fuentes incompletas o duplicados | Alerta si las filas del día se apartan más de un 30 % del promedio del mismo día en las últimas cuatro semanas |
| Esquema | Columnas nuevas, eliminadas o con otro tipo | Cualquier cambio no registrado en una tabla crítica |
| Distribución | Nulos, valores fuera de rango, claves repetidas | Más de un 1 % de nulos en una columna obligatoria; cualquier clave duplicada |
| Linaje | Origen de una falla e impacto aguas abajo | Toda tabla crítica con sus dependencias registradas automáticamente |
Los umbrales fijos son un buen comienzo porque se entienden y se discuten con facilidad. La detección de anomalías sobre volumen o distribución puede venir después, con las mismas condiciones de historial y medición de precisión que describimos en AIOps sin humo.
Empezar con pruebas junto al código
Si tus transformaciones usan dbt, ya tienes dos herramientas a mano: la verificación de frescura de las fuentes y las pruebas genéricas sobre columnas. El siguiente ejemplo declara una fuente con umbrales de frescura y pruebas de unicidad y de valores no nulos.
# models/fuentes.yml
version: 2
sources:
- name: ventas # datos crudos que deja la ingesta
schema: raw
loaded_at_field: _cargado_en # columna con la hora de carga
freshness: # umbrales ilustrativos
warn_after: {count: 2, period: hour}
error_after: {count: 6, period: hour}
tables:
- name: pedidos
columns:
- name: pedido_id
tests:
- unique # sin claves duplicadas
- not_null # sin claves vacías
El comando dbt source freshness evalúa la frescura y dbt test ejecuta las pruebas. Ambos pueden correr en el orquestador después de cada carga y enviar el resultado al sistema de alertas. Great Expectations ofrece un enfoque similar en Python, con expectativas declarativas sobre volumen, rangos y distribuciones y con reportes legibles para el equipo. La herramienta importa menos que el hábito: cada tabla crítica con sus pruebas versionadas junto al código que la produce.
SLO de datos, alertas y dueños
Las pruebas responden "¿está bien ahora?". Los SLO responden "¿cumple lo que prometimos?". El capítulo "Service Level Objectives" del libro de SRE de Google define un SLO como un valor objetivo para un indicador medido del servicio, y la idea se traslada directamente a los datos. Un ejemplo ilustrativo: "la tabla de saldos diarios está disponible antes de las 7:00 en el 99 % de los días hábiles del trimestre".
Recomendamos:
- SLO solo para conjuntos de datos críticos: los que alimentan reportes regulatorios, procesos de cliente o decisiones diarias.
- Indicadores desde el punto de vista del consumidor, como la frescura en el punto de consumo o la completitud, no detalles internos del pipeline.
- Alertas que interrumpen a alguien solo cuando el SLO está en riesgo; el resto va a una cola que se revisa en horario. Es el mismo criterio que describimos en alertas sin fatiga.
- Un dueño por conjunto de datos, registrado y visible, que responde a la alerta y acuerda los umbrales con los consumidores.
Incidentes de datos
Cuando un SLO se incumple o falla una prueba crítica, conviene tratarlo como un incidente, con el mismo proceso que los incidentes de aplicación: registro, severidad, comunicación, resolución y revisión posterior. La severidad debe reflejar el impacto en los consumidores, no la complejidad técnica de la falla: una columna con nulos en una tabla que alimenta un reporte regulatorio puede ser más grave que una carga caída en un entorno de pruebas. Además, hay dos particularidades.
La primera es la contención. Además de corregir el pipeline, hay que decidir si se detienen los procesos que consumen los datos afectados y avisar a quienes ya los usaron. El linaje responde esa pregunta en minutos; sin él, se responde preguntando por correo.
La segunda es la corrección hacia atrás. Arreglar la carga de hoy no corrige los días anteriores. El cierre del incidente debe incluir el reprocesamiento de los periodos afectados y la verificación de que las pruebas pasan sobre ellos.
Las revisiones posteriores alimentan las pruebas: cada incidente de datos debería terminar con al menos una prueba nueva que lo habría detectado antes. Y si los datos vienen de aplicaciones propias, parte de la solución está en el origen: registrar los cambios de esquema y publicar eventos de carga, igual que pedimos que el software sea observable y no solo la plataforma, como explicamos en plataforma observable no es aplicación observable.
Fuentes
- OpenLineage, especificación abierta para metadatos de linaje: https://openlineage.io/
- dbt, documentación de fuentes y verificación de frescura: https://docs.getdbt.com/docs/build/sources
- dbt, documentación de pruebas: https://docs.getdbt.com/docs/build/data-tests
- Documentación de Great Expectations: https://docs.greatexpectations.io/docs/
- Google, Site Reliability Engineering, capítulo "Service Level Objectives": https://sre.google/sre-book/service-level-objectives/
¿Quieres aplicar esto en tu operación?
Solicitar diagnóstico