Saltar al contenido principal
DB-1401 • 34 Horas • Nivel Avanzado / Principal Time-Series DB Architect

Bases de Datos de Series Temporales (TSDB) y Telemetría IoT/FinTech: TimescaleDB, InfluxDB 3.0 (Arrow) y Gorilla

Patologías de ingesta temporal en B-Trees tradicionales, particionamiento espacio-temporal en Hypertables y Chunks (TimescaleDB), compresión híbrida Fila-a-Columna (Delta-of-Delta y XOR Gorilla), motor FDAP (Apache Arrow + DataFusion + Parquet) y control de High Cardinality.

Módulo 1: Módulo 1: Por Qué los B-Trees Colapsan en Ingesta Temporal y Arquitectura de Hypertables (TimescaleDB)

El Acantilado de Rendimiento en Tablas Monolíticas y Particionamiento Automático en Chunks (Hypertables) (50 min)

El Acantilado de Rendimiento en Tablas Monolíticas y Particionamiento Automático en Chunks (Hypertables)

1. Por Qué el Throughput de Inserción Cae un 90% Cuando los Índices Superan la RAM

En una tabla relacional única de $2\text{ TB}$ con índices compuestos sobre (device_id, ts) y (metric_type, ts), aunque las inserciones van al final del eje temporal, las páginas hoja de los índices secundarios para millones de device_id distintos están dispersas en un árbol B+ de $400\text{ GB}$. Cuando el conjunto de trabajo de los índices supera shared_buffers, cada INSERT provoca Page Swapping aleatorio en disco.

flowchart LR
    ING["Ingesta 250,000 métricas/seg"] --> HT["Hypertable (Abstracción Lógica Única)"]
    HT --> C_HOT["Chunk Activo Hoy (100% de sus índices B-Tree caben en RAM)"]
    HT --> C_WARM["Chunk Ayer (Congelado y Comprimido Columnar 94% ahorro)"]
    HT --> C_COLD["Chunk > 30 días (Tiered a Object Storage S3 Parquet)"]

2. Regla de Dimensionamiento de chunk_time_interval

El intervalo temporal de cada Chunk en TimescaleDB debe dimensionarse de modo que todos los índices de los chunks activos simultáneamente ocupen como máximo el $25\%$ de la memoria RAM física del servidor, garantizando que el $100\%$ de la ingesta opere en memoria sin I/O aleatorio de lectura.

Matemática de Compresión TSDB (92%–97%): Delta-of-Delta para Timestamps y XOR Gorilla para Floats (55 min)

Matemática de Compresión TSDB (92%–97%): Delta-of-Delta para Timestamps y XOR Gorilla para Floats

1. Compresión de Timestamps: Delta-of-Delta (Pelkonen et al. - Facebook Gorilla)

En telemetría periódica (ej. cada $10\text{ s}$: $1000, 1010, 1020, 1030$), las primeras diferencias son $\Delta_t = t_i - t_{i-1} = 10$, y las segundas diferencias (Delta-of-Delta) son:

$D_i = (t_i - t_{i-1}) - (t_{i-1} - t_{i-2}) = 0$

Cuando $D_i = 0$ (el $96\%$ de las muestras en sensores e infraestructura), el timestamp de 64 bits se codifica con un único bit 0 (compresión de $64:1$).

2. Compresión de Punto Flotante IEEE 754: Operador XOR sobre Valores Adyacentes

Dado que la temperatura de una turbina o el precio de un activo cambia suavemente entre segundos consecutivos ($v_{i-1} = 24.50, v_i = 24.51$), sus representaciones binarias IEEE 754 de 64 bits comparten el mismo signo, exponente y la mayoría de los bits de mantisa. Al calcular $X_i = v_i \oplus v_{i-1}$: - Si $X_i = 0$ (valor idéntico al anterior), se escribe 1 solo bit 0. - Si $X_i \neq 0$, solo se codifican los bits significativos centrales delimitados por la cantidad de ceros iniciales (leading zeros) y finales (trailing zeros).

Arquitectura Híbrida Row-to-Columnar en TimescaleDB: Diseño de compress_segmentby y compress_orderby (45 min)

Arquitectura Híbrida Row-to-Columnar en TimescaleDB: Diseño de compress_segmentby y compress_orderby

1. Conversión Automática de Filas Recientes a Arreglos Columnales Comprimidos

Cuando un Chunk envejece (ej. tiene $> 24\text{ h}$), la política de compresión agrupa hasta $1,000$ filas por entidad y las transpone en 1 sola fila física que contiene arreglos columnares comprimidos:

ALTER TABLE sensor_telemetry SET (
  timescaledb.compress,
  timescaledb.compress_segmentby = 'tenant_id, device_id',
  timescaledb.compress_orderby = 'ts DESC'
);
SELECT add_compression_policy('sensor_telemetry', INTERVAL '24 hours');

[!IMPORTANT]
Selección de compress_segmentby: Debe contener las columnas por las que siempre filtras con igualdad (WHERE tenant_id = ? AND device_id = ?). Si pones una columna con cardinalidad única por fila (como event_uuid) en segmentby, cada segmento tendrá 1 sola fila y la compresión caerá al $0\%$.

Módulo 2: Módulo 2: El Problema de la Alta Cardinalidad (High Cardinality) y la Pila FDAP (InfluxDB 3.0 / Arrow)

Anatomía de la Explosión de Cardinalidad (Unbounded Series Churn) en Índices Invertidos de Etiquetas (50 min)

Anatomía de la Explosión de Cardinalidad (Unbounded Series Churn) en Índices Invertidos de Etiquetas

1. Cómo un Tag Efímero (pod_id, trace_id, container_id) Derrumba Motores TSDB de 1ra/2da Generación

En motores basados en índices invertidos de series (Prometheus TSDB, InfluxDB 1.x/2.x TSM), cada combinación única de etiquetas metric_name + {tag1=v1, tag2=v2, ...} crea una Serie Temporal Independiente (Series ID) en el índice en memoria.

Si tienes: $100\text{ métricas} \times 50\text{ regiones} \times 2,000\text{ nodos} \times 500\text{ pods efímeros/día} = 5 \times 10^9\text{ Series Únicas}$

Este fenómeno (Series Churn) agota decenas de gigabytes de RAM solo en el índice de etiquetas.

Regla Inmutable de Diseño de Esquema TSDB: - Tags / Segment Columns (Indexados): Únicamente dimensiones acotadas de baja/media cardinalidad usadas en cláusulas WHERE y GROUP BY (region, service_name, env, host_id). - Fields / Value Columns (No Indexados en el Series Index): Métricas numéricas e identificadores efímeros de ultra-alta cardinalidad (request_id, trace_id, ip_origen).

La Revolución FDAP (InfluxDB 3.0 IOx / GreptimeDB): Apache Arrow, Flight RPC, DataFusion y Parquet (50 min)

La Revolución FDAP (InfluxDB 3.0 IOx / GreptimeDB): Apache Arrow, Flight RPC, DataFusion y Parquet

1. Cómo el Motor Columnar FDAP Elimina el Techo de Cardinalidad

Las bases de datos de series temporales de nueva generación reemplazan los motores TSM propietarios por el stack abierto FDAP: 1. Apache Arrow (In-Memory Columnar Format): Representación columnar estandarizada en RAM alineada a registros SIMD (AVX-512) con Zero-Copy entre procesos. 2. Apache Arrow Flight (gRPC Zero-Copy Streaming): Transfiere millones de filas por segundo hacia clientes Python/Pandas/Polars sin serializar ni deserializar JSON/Protobuf. 3. Apache DataFusion (Query Engine en Rust): Motor de ejecución SQL e InfluxQL vectorizado con Late Materialization y Predicate Pushdown. 4. Apache Parquet en Object Storage (S3/GCS): Persistencia desacoplada de cómputo con diccionarios de compresión y estadísticas Min/Max Zone Maps por Row Group.

Agregaciones Continuas Incrementales (Downsampling), Políticas de Retención y Sketches (UDDSketch / t-digest) (45 min)

Agregaciones Continuas Incrementales (Downsampling), Políticas de Retención y Sketches (UDDSketch / t-digest)

1. El Error Matemático de Promediar Promedios o Percentiles

Si calculas el percentil $p99$ de cada minuto y luego intentas obtener el $p99$ del día promediando o tomando el máximo de esos 1,440 percentiles, el resultado es matemáticamente falso.

Solución Exacta (Merging de Sketches de Distribución): En las vistas materializadas incrementales (Continuous Aggregates), almacenamos la estructura resumen UDDSketch o t-digest de cada ventana de 1 minuto. Dado que los sketches son conmutativos y asociativos (Monoides), podemos combinar los sketches de 30 días en milisegundos para obtener el $p99$ exacto de todo el mes sin conservar los miles de millones de puntos crudos.

Módulo 3: Módulo 3: Consultas Analíticas Temporales Avanzadas: Time Buckets, Gapfilling, LOCF y ASOF Joins

Regularización de Series Irregulares en SQL: time_bucket_gapfill(), LOCF e Interpolación Lineal (50 min)

Regularización de Series Irregulares en SQL: time_bucket_gapfill(), LOCF e Interpolación Lineal

1. El Problema de las Ventanas Vacías en Sensores IoT y Mercados Ilíquidos

Un GROUP BY time_bucket('5 minutes', ts) estándar omite por completo los intervalos de 5 minutos donde no llegaron eventos. Esto rompe los modelos de forecasting y los gráficos de monitoreo que esperan una grilla temporal equiespaciada.

En TimescaleDB, combinamos la generación de grilla densa con dos estrategias de imputación causal: - locf(value) (Last Observation Carried Forward): Propaga hacia adelante el último estado conocido (ideal para estados discretos, saldos o precios de cierre). - interpolate(value): Interpolación lineal para variables físicas continuas (temperatura, presión, voltaje).

ASOF JOIN en Finanzas Cuantitativas y Telemetría: Emparejamiento del Estado Previo Más Cercano sin Futuro (50 min)

ASOF JOIN en Finanzas Cuantitativas y Telemetría: Emparejamiento del Estado Previo Más Cercano sin Futuro

1. Cruce de dos Flujos Asíncronos con Distinta Frecuencia de Muestreo

Supongamos que una orden de compra de acciones (trades) se ejecuta a las 10:00:01.452, y las cotizaciones de mercado (quotes) se registraron a las 10:00:01.100 y 10:00:01.890. Un INNER JOIN por igualdad de timestamp devuelve 0 filas.

Un ASOF JOIN (nativo en DuckDB, ClickHouse, QuestDB y emulable con LATERAL en PostgreSQL) empareja cada fila de trades con la única fila de quotes del mismo símbolo cuyo timestamp sea el máximo menor o igual ($t_{\text{quote}} \le t_{\text{trade}}$):

SELECT
  t.trade_id, t.symbol, t.trade_ts, t.execution_price,
  q.bid_price, q.ask_price
FROM trades t
LEFT JOIN LATERAL (
  SELECT bid_price, ask_price
  FROM quotes q
  WHERE q.symbol = t.symbol AND q.quote_ts <= t.trade_ts
  ORDER BY q.quote_ts DESC
  LIMIT 1
) q ON true;

Cálculo Exacto de Derivadas y Tasas sobre Contadores Monotónicos con Reinicios (Counter Resets) (45 min)

Cálculo Exacto de Derivadas y Tasas sobre Contadores Monotónicos con Reinicios (Counter Resets)

1. El Peligro de value_t - value_{t-1} Cuando un Contenedor o Router Se Reinicia

Las métricas de red (bytes_sent_total) o peticiones (http_requests_total) son contadores acumulativos monotónicos que vuelven a $0$ cuando el proceso se reinicia. Si en $t-1$ el contador valía $1,000,000$ y tras un reinicio en $t$ vale $450$, la resta ingenua produce una tasa absurda de $-999,550$ peticiones.

Regla de Corrección de Counter Reset: $\Delta_{\text{corregido}}(t) = \begin{cases} v_t - v_{t-1} & \text{si } v_t \ge v_{t-1} \\ v_t & \text{si } v_t < v_{t-1} \; (\text{Reinicio detectado}) \end{cases}$

Módulo 4: Módulo 4: Laboratorio de Counter Resets / ASOF Join y Evaluación de Certificación

Cascada de Retención FinOps: Datos Crudos (7d) -> Agregados 1m (90d) -> Agregados 1h (5 años) (45 min)

Cascada de Retención FinOps: Datos Crudos (7d) -> Agregados 1m (90d) -> Agregados 1h (5 años)

Combinar add_retention_policy('raw_metrics', INTERVAL '7 days') sobre la hypertable cruda mientras las vistas materializadas continuas de 1 minuto y 1 hora conservan sus propios intervalos de retención independientes reduce el costo de disco NVMe en un $96\%$ sin perder visibilidad histórica de largo plazo.

Laboratorio Práctico: Cálculo de Tráfico Real con Corrección de Counter Resets en Series Temporales (60 min)

Laboratorio Práctico: Cálculo de Tráfico Real con Corrección de Counter Resets en Series Temporales

Contexto del Desafío TSDB

La tabla network_counter_timeseries almacena las lecturas consecutivas del contador monotónico cumulative_packets de una interfaz de red de núcleo (iface = 'eth0'), ordenada por sample_seq: - sample_seq (INTEGER: secuencia temporal $1, 2, 3, \dots$) - cumulative_packets (BIGINT: valor acumulado del contador desde el último arranque)

Entre dos muestras consecutivas, la interfaz sufrió un reinicio de firmware (Counter Reset), haciendo que cumulative_packets cayera a un valor menor que el de la muestra inmediata anterior.

Objetivo de la Consulta SQL

Utilizando la función de ventana LAG(cumulative_packets) OVER (ORDER BY sample_seq), escribe una consulta SQL para las muestras con sample_seq > 1 que devuelva: 1. sample_seq 2. prev_counter: valor de la muestra anterior 3. curr_counter: valor actual de cumulative_packets 4. true_delta_packets: si curr_counter >= prev_counter entonces curr_counter - prev_counter; si hubo reinicio (curr_counter < prev_counter), entonces curr_counter. 5. reset_detected: 1 si curr_counter < prev_counter, 0 en caso contrario. Ordena por sample_seq ASC.

Evaluación de Certificación: Bases de Datos de Series Temporales (TSDB) y Telemetría de Alta Frecuencia (45 min)

Evaluación de Certificación: DB-1401

Comprueba tu dominio de TimescaleDB, compresión Gorilla (Delta-of-Delta / XOR), arquitectura FDAP (Apache Arrow) y alta cardinalidad.