Hay una tentación recurrente: adoptar una herramienta porque es la que "se usa" y después buscar cómo encajar el problema en ella. Spark es el ejemplo clásico. Aparece en todas las ofertas de trabajo, todos los cursos lo mencionan, y termina siendo la opción por defecto para procesar datos.
Pero Spark nació para resolver un problema específico: procesamiento distribuido de grandes volúmenes. Si tu problema no tiene ese perfil, estás sumando complejidad operativa sin beneficio.
El contexto cambió
Históricamente, muchas cargas de trabajo terminaban en Spark porque no había alternativas. Hoy eso cambió.
Por un lado, aparecieron herramientas como Polars, DuckDB, y pandas mejoró mucho. Todo lo que entra en memoria de una máquina moderna se puede procesar con estas herramientas sin necesidad de un cluster distribuido.
Y las máquinas de hoy no son las de hace quince años, cuando apareció Hadoop y después Spark. Con una inversión razonable tenés 32, 64 o más gigas de RAM. Eso alcanza para cientos de millones de filas en muchos casos.
Por otro lado, aparecieron motores SQL distribuidos que te abstraen la gestión del cluster. Mandás SQL, el motor lo ejecuta de forma distribuida, y no tenés que pensar en nodos ni configuración.
Dos comparaciones distintas
Hay que separar dos comparaciones que a veces se mezclan:
Spark vs herramientas single-thread (Polars, pandas, DuckDB). Acá la pregunta es: ¿necesito procesamiento distribuido o mis datos entran en una máquina? Si entran en memoria, las herramientas single-thread son más simples de operar y muchas veces más rápidas para ese volumen.
Spark vs motores SQL distribuidos. Ambos son distribuidos. La diferencia está en el modelo de uso: los motores SQL te abstraen el cluster, mandás SQL y listo. Spark te da más control pero también más responsabilidad operativa.
Cuándo tiene sentido Spark
Spark brilla en escenarios específicos:
Mucho volumen que no entra en una máquina. Si tus datos no entran en memoria de una máquina razonable, necesitás distribuir.
Queries complejas con muchos joins. Cuando tenés transformaciones que cruzan muchas tablas y necesitás aprovechar la distribución para que sea eficiente.
Datos semiestructurados pesados. Logs en JSON, eventos con esquemas variables, archivos grandes que hay que parsear. Spark maneja bien ese tipo de carga.
Necesidad de control fino. Si necesitás tunear memoria, particionamiento, o tenés requerimientos específicos de ejecución.
Si tu caso no tiene ninguna de estas características, probablemente haya una opción más simple.
La complejidad operativa de Spark
Spark es una tecnología compleja. Está buenísima, pero no es soplar y hacer botellas.
Cuando algo no funciona, tenés que entender jobs, stages, tareas, shuffles, planes de ejecución. Funciona con Java por atrás, con su JVM y su manejo de memoria. Todo eso se puede tunear, pero hay que saber qué se está tocando.
Los servicios serverless como AWS Glue te abstraen parte de esa complejidad, pero no toda. Cuando algo falla, igual tenés que interpretar qué pasó.
Esa complejidad tiene sentido pagarla si el problema lo justifica. Si no, es costo operativo sin beneficio.
Una recomendación práctica
Si estás en un entorno cloud, probá primero con el motor SQL distribuido del proveedor. Si funciona y la performance es aceptable, listo. Si por algún motivo no alcanza, ahí evaluá Spark.
Para cargas que entran en memoria, probá primero con Polars o DuckDB. Son más simples de operar y muchas veces suficientes.
La idea no es evitar Spark. Es no usarlo por defecto cuando hay opciones más simples que resuelven el problema.
SQL vs Python en transformaciones
Otra decisión relacionada: ¿escribo la transformación en SQL o en Python?
SQL tiene ventajas para transformaciones declarativas: es más fácil de leer, más fácil de optimizar por el motor, y las herramientas de linaje lo entienden mejor. Si tu transformación se puede expresar en SQL, probablemente convenga hacerlo en SQL.
Python tiene sentido cuando necesitás lógica que SQL no expresa bien: parsing complejo, llamadas a APIs, algoritmos que no son set-based.
La regla es la misma: elegir según el problema, no según la preferencia.
Cierre de la colección
Esta colección arrancó con la restricción física que explica los lakehouse: el object storage es inmutable. Desde ahí vimos cómo separar cómputo de almacenamiento, qué pasa cuando un data lake crece sin gobierno, cómo elegir entre herramientas modulares y plataformas integradas, y qué estrategia de procesamiento usar según la latencia que necesitás.
Todo eso converge acá: la elección de herramienta es el último eslabón. Si entendés la arquitectura subyacente, sabés qué tipo de problema tenés. Si sabés qué tipo de problema tenés, podés elegir la herramienta que lo resuelve sin sumar complejidad innecesaria.
Las decisiones de arquitectura no se toman en el vacío. Se toman entendiendo las restricciones físicas, los trade-offs de cada capa, y el problema concreto que hay que resolver.
En resumen
Spark, Polars, pandas, motores SQL distribuidos: cada herramienta tiene un rango de problemas donde brilla. Spark es para volumen que no entra en una máquina, queries complejas que aprovechan distribución, datos semiestructurados pesados.
Si tus datos entran en memoria, herramientas single-thread como Polars o DuckDB son más simples. Si necesitás distribuir pero no querés gestionar un cluster, los motores SQL distribuidos de los proveedores cloud te abstraen esa complejidad.
Elegir la herramienta antes de entender el problema es la forma más rápida de sumar complejidad innecesaria.