Architettura degli Apache Spark pool

Un Apache Spark pool in Azure Synapse Analytics non è un cluster sempre acceso, ma una definizione: un template di configurazione che descrive dimensione dei nodi, autoscale e regole di pausa. Le risorse compute vengono effettivamente allocate solo quando lanci un notebook o un job Spark; questo modello serverless-on-demand è centrale per capire il controllo dei costi.

Node size e famiglie

Ogni pool ha una node size (Small, Medium, Large, XLarge…) che determina vCore e memoria per nodo. Un pool ha sempre un nodo driver e uno o più nodi worker. Regole pratiche a livello associate:

  • Workload con molte partizioni piccole o parallelismo elevato beneficiano di più nodi piccoli.
  • Operazioni memory-intensive (join di grandi tabelle, cache di DataFrame, ML) richiedono node size maggiori per evitare spill su disco e OutOfMemory.
  • Le Memory Optimized sono la famiglia di riferimento per la maggior parte dei carichi analitici.

Autoscale

Con l’autoscale definisci un intervallo minmax di nodi: Synapse aggiunge o rimuove worker in base al carico. È ideale quando i job hanno intensità variabile, perché eviti di dimensionare per il picco. Se disattivi l’autoscale devi indicare un numero fisso di nodi.

Auto-pause (il cardine dei costi)

L’auto-pause rilascia le risorse compute dopo un periodo di inattività configurabile (es. 15 minuti). Con il pool in pausa non paghi il compute: lo storage dei metadati resta, ma non ci sono vCore attivi. È la leva più importante per non bruciare budget. Ricorda che alla ripresa c’è un cold start (alcuni minuti) per riallocare i nodi.

PySpark su DataFrame verso ADLS Gen2

Il pattern tipico è leggere da Azure Data Lake Storage Gen2, trasformare con l’API DataFrame e riscrivere in formato colonnare, preferendo Parquet o Delta per performance e partizionamento.

df = spark.read.parquet("abfss://raw@stg.dfs.core.windows.net/sales/")
agg = df.groupBy("region").agg({"amount": "sum"})
agg.write.mode("overwrite").parquet(
    "abfss://curated@stg.dfs.core.windows.net/sales_by_region/")

Punti d’esame ricorrenti:

  • Lo schema abfss:// è quello corretto per ADLS Gen2 (non wasbs, legato al Blob storage flat).
  • L’autenticazione avviene tipicamente via linked service con Managed Identity del workspace o pass-through dell’identità utente, non con chiavi in chiaro nel notebook.
  • Il partitioning in scrittura (partitionBy) riduce i dati letti a valle: scelta architetturale, non estetica.

Integrazione con il dedicated SQL pool

Spark e dedicated SQL pool si scambiano dati tramite il Synapse Dedicated SQL Pool Connector for Apache Spark. Con synapsesql puoi leggere e scrivere tabelle SQL direttamente da PySpark; internamente il connettore usa un bulk load ottimizzato verso ADLS come area di staging, molto più efficiente di inserimenti riga per riga tramite JDBC.

df.write.synapsesql("mydwh.dbo.FactSales", Constants.INTERNAL)

Usa questo pattern quando Spark fa la trasformazione pesante e il dedicated SQL pool serve il modello dimensionale a Power BI. È l’esempio classico di pipeline: land → curate (Spark) → serve (SQL pool).

Spark pool vs SQL serverless vs Azure Databricks

  • Spark pool: trasformazioni complesse, dati semi/non strutturati, machine learning, logica in PySpark/Scala. Paghi il compute mentre gira.
  • Serverless SQL pool: esplorazione e query T-SQL ad-hoc su file nel data lake, pay-per-TB scansionato, nessun cluster da gestire. Ottimo per BI leggera e viste logiche, non per ETL stateful pesante.
  • Azure Databricks: piattaforma Spark più matura per collaborazione avanzata, MLflow, Delta Live Tables. Da preferire se il team è già investito in Databricks o serve un ecosistema ML completo; in un contesto puramente Synapse-centrico lo Spark pool integrato riduce l’attrito.

Trappole tipiche d’esame

  • Costi fuori controllo perché “il pool non si ferma” → verifica che auto-pause sia abilitata con un timeout basso; un pool senza pausa continua a fatturare vCore anche a idle.
  • Query T-SQL esplorativa ad-hoc su file Parquet, minimo overheadserverless SQL pool (pay-per-TB), non Spark pool.
  • Carico variabile con picchi imprevedibiliautoscale con range min–max, non un numero fisso di nodi dimensionato sul picco.
  • Scrivere risultati Spark in una tabella del dedicated SQL pool per Power BI → usa il connettore synapsesql (bulk via staging ADLS), non JDBC generico riga per riga.
  • Percorso storage per ADLS Gen2 → schema abfss:// con Managed Identity; wasbs:// è la trappola legata al Blob storage, non a Gen2.