Big Data y Procesamiento Distribuido · Ingeniería de Datos

Formatos columnares y particionado de datos

Diferenciar almacenamiento por fila y por columna, y aplicar formatos columnares, compresión y particionado para minimizar la lectura en grandes volúmenes.

Formatos columnares y particionado de datos

El formato es la primera optimización Antes de que Spark toque los datos, alguien decidió cómo están guardados en disco. Ese formato puede hacer que una consulta lea 5 GB o solo 5 MB.

Hay dos maneras de guardar una tabla: por filas (todas las columnas de un registro juntas) o por columnas (todos los valores de una columna juntos). Las bases transaccionales guardan por fila; el análisis guarda por columna, porque suele leer unas pocas columnas de millones de filas.

Almacenamiento por fila y por columna

Una lectura que necesita una o dos columnas de toda la tabla, en formato columnar ignora el resto del disco. Además, los valores parecidos quedan contiguos, así que comprimen muchísimo mejor que mezclar columnas distintas.

Diagrama de tres bandas: el almacén organizado en carpetas por partición de fecha; un archivo columnar Parquet con sus grupos de columnas y el pie con estadísticas; abajo las tres optimizaciones de lectura (poda de partición, poda de columnas, pushdown de predicados).
La lectura eficiente combina dónde están los archivos, cómo se guarda cada columna y qué metadatos permite saltarse bloques.

Tres podas que ahorran lectura

Compresión

Los formatos columnares comprimen cada bloque con un códec. Snappy prioriza velocidad de CPU; Zstd equilibra ratio y velocidad; Gzip maximiza compresión pero cuesta al descomprimir. Menos bytes en disco también significa menos E/S.

Particionado de datos en el almacenamiento

Además del formato, conviene particionar los archivos en carpetas por una columna de filtro frecuente, como la fecha (anio=2024/mes=06/...). Así el motor descarta de entrada directorios irrelevantes. El riesgo es particionar por columnas de alta cardinalidad o muy finas, que generan miles de archivos pequeños.

Cada optimización ataca un costo distinto de la lectura.
TécnicaQué haceCuidado
Poda de columnaslee solo las columnas usadasninguno, es barata
Pushdown de predicadosfiltra al leer con el pie de archivono sirve con predicados no sargables
Poda de particiónsalta carpetas irrelevantesdemasiadas particiones = archivos pequeños
Compresiónreduce almacenamiento y E/Sun códec lento eleva la CPU

El problema de los archivos pequeños

Particionar muy fino o escribir micro-lotes crea muchísimos archivos diminutos: el motor gasta más abriendo archivos que leyendo datos, y el almacén se satura de metadatos. La solución es fijar un tamaño de archivo objetivo y compactar periódicamente.

Parquet y ORC

Errores frecuentes

Ejemplo resuelto: una consulta lee demasiado

  1. Medir cuántos bytes lee el motor frente a cuántos devuelve.
  2. Confirmar que el filtro principal es por fecha.
  3. Reescribir los datos en Parquet particionado por fecha.
  4. Elegir un códec rápido (snappy o zstd) y un tamaño de archivo objetivo.
  5. Programar compactación para los lotes diarios.

¿Para qué sirve en la realidad?

La mayor parte del costo y del tiempo de una plataforma de datos está en leer datos innecesarios. Elegir formato y partición correctos suele dar más aceleración que ajustar el clúster.

¿Por qué un formato columnar acelera una consulta analítica que agrega pocas columnas?

Particionar por una columna de muy alta cardinalidad suele ser buena idea.

Aplicar el filtro al momento de leer, apoyándose en las estadísticas del pie de archivo, se llama de predicados.

Clasifica cada decisión según si favorece o daña el rendimiento de lectura.

Favorece
Daña

Une cada término con su definición.

Formatos y particionado

Guarda los valores de cada columna juntos
formato columnar
Saltar carpetas por el filtro de fecha
partition pruning
Leer solo columnas del SELECT
column pruning
Filtrar al leer usando el pie de archivo
predicate pushdown
Miles de archivos diminutos
small files problem

Formatos columnares y particionado

# Formatos de datos
## Fila vs columna
### columna para analizar
### mejor compresion
## Podas
### particion
### columnas
### pushdown
## Almacenamiento
### carpetas por fecha
### cuidado cardinalidad
## Parquet y ORC
### pie con estadisticas
### compactar small files

Formato de archivo Parquet (documentación oficial)
Especificación del layout columnar, los bloques y la estadística del pie de archivo.

Spark SQL y Parquet (documentación oficial)
Cómo Spark aplica filter pushdown y particionado sobre archivos Parquet.

Una tabla particionada por customer_id (dos millones de valores) hoy tiene millones de archivos de unos cientos de bytes y las consultas empeoraron. ¿Qué cambio de particionado y de formato propondrías y por qué el filtro habitual de tus consultas manda en esa decisión?