Spark
Nivel medio¿Cuándo ayuda de verdad el broadcast join de Spark, y cuándo se vuelve en tu contra?
Un broadcast join es apostar a que un lado del join es lo bastante pequeño como para copiarlo a todas partes barato. Cuando la apuesta acierta, es el join más rápido que tiene Spark. Cuando falla, es la forma más rápida de tumbar un driver por OOM.
spark.sql.autoBroadcastJoinThreshold (10MB por defecto) le dice al planificador: si el tamaño estimado de una tabla está por debajo de esto, sáltate el shuffle y envía una copia completa a cada executor.
Qué controla realmente el umbral
Por debajo del umbral, el planificador reemplaza un shuffle join (ambos lados reparticionados y mezclados por la red) por un broadcast join (el lado pequeño se recolecta en el driver y luego se envía a cada executor como tabla hash). Sin shuffle para el lado grande significa sin stage de shuffle read, sin el sesgo asociado al shuffle, y normalmente un join notablemente más rápido - exactamente por eso el planificador hace esto automáticamente cada vez que estima que una tabla es lo bastante pequeña.
El modo de fallo: un broadcast que debió quedarse como shuffle
La estimación que usa el planificador viene de las estadísticas de la tabla, que se desactualizan - una tabla que pesaba 8MB cuando se calcularon las estadísticas por última vez pero ahora pesa 800MB igualmente será enviada por broadcast si nadie refrescó esas estadísticas. El resultado: cada executor intenta mantener a la vez una tabla hash de 800MB en memoria, y a menudo es el driver (que recolecta los datos del broadcast primero) el que hace OOM antes que cualquier executor.
Cómo distinguirlo desde el event log
Busca un stage con muy pocas tareas (una etapa de recolección de broadcast esencialmente se ejecuta en una sola tarea) mostrando un uso de memoria pico inusualmente alto, seguido inmediatamente de un fallo a nivel de stage o un OOM del driver en los logs de la aplicación, en lugar de un fallo a nivel de tarea. Un OOM de shuffle join, en cambio, se ve como muchas tareas fallando en un stage de tamaño normal - una firma completamente distinta.
Si no estás seguro de si está ocurriendo un broadcast: revisa el plan físico buscando
BroadcastHashJoin frente a SortMergeJoin - es el único lugar donde Spark te
dice directamente qué estrategia eligió, en lugar de dejarte inferirlo por el tiempo.
Mira cómo se ve esto en tu propio pipeline.
Sube un event log real de Spark, un run_results.json de dbt, o una exportación de
métricas de Flink, y recibe recomendaciones concretas que requieren tu aprobación - no otra regla
general.