PySpark
DataFrame distribuiti, join che non fanno esplodere il cluster, e le parti di Spark che mordono.
-
Lezione 1
Big data, in parole povere
Quando i dati diventano 'big' nel senso tecnico, perché una macchina sola prima o poi non basta, e dove si colloca Spark nello stack.
-
Lezione 2
L'idea di MapReduce, e perché ha contato
Il paper di Google del 2004, il modello che ha reso trattabile il processing distribuito, e perché tutti l'hanno superato nel giro di un decennio.
-
Lezione 3
Cos'è Spark e perché ha sostituito Hadoop MapReduce
Il paper di Matei Zaharia del 2010, l'esecuzione in memoria, il DAG, la lazy evaluation e la dichiarazione del '100x più veloce': cosa significa davvero e cosa no.
-
Lezione 4
L'architettura di Spark: driver, executor, cluster manager
Come gira davvero un job Spark su più macchine. Il driver, gli executor, il cluster manager, e il modello di risorse che li tiene insieme.
-
Lezione 5
RDD, DataFrame, Dataset: tre API, un motore
Perché Spark ha tre API, in cosa è bravo ognuno, quando usare quale, e perché i DataFrame hanno vinto la partita per quasi tutti.
-
Lezione 6
PySpark vs Scala Spark: cosa attraversa il filo
Come PySpark parla con la JVM, dove vive l'overhead di performance, e quando (raramente) scenderesti davvero a Scala.
-
Lezione 7
Installare PySpark in locale
Installare PySpark con pip, il requisito di Java che inciampa sempre tutti, e la gotcha di winutils di Hadoop solo su Windows.
-
Lezione 8
La tua prima SparkSession
Il punto di ingresso di ogni job PySpark. Cos'è una SparkSession, le configurazioni che contano, e cosa significa davvero `local[*]`.
-
Lezione 9
Leggere dati: CSV, JSON, Parquet, e il tradeoff dello schema-on-read
Tre formati di file, tre comportamenti di default, e perché fare bene le letture all'inizio ti risparmia cento problemi dopo.
-
Lezione 10
Show, count, collect: le action che ogni principiante esegue per prime
Le tre action con cui inizia ogni notebook PySpark, la differenza tra loro, e perché confonderle a scala è pericoloso.
-
Lezione 11
Scrivere dati: mode, partizioni e il problema del numero di file
Save mode, write partizionate, la differenza tra molti file piccoli e un file gigante, e perché Parquet è il default per un motivo.
-
Lezione 12
Local contro cluster: workflow di sviluppo che non ti mente
Quando local mode basta, quando ti serve un cluster vero, e i bug che si presentano solo quando ci sono executor veri in scena.
-
Lezione 13
Schema: espliciti vs inferiti
Quando lasciare che Spark inferisca, quando dichiarare il proprio, e perché il codice di produzione dichiara praticamente sempre.
-
Lezione 14
Select e filter: le due operazioni che farai migliaia di volte
select, where, filter, e i quattro modi di riferirsi a una colonna, incluso quello che si rompe quando hai spazi nei nomi delle colonne.
-
Lezione 15
Aggiungere colonne: withColumn, lit, e la trappola della concatenazione
Come aggiungere o modificare colonne, perché le chiamate withColumn in un loop sono una trappola di performance nota, e quando usare select invece.
-
Lezione 16
Aggregazioni 101: groupBy, agg e il catalogo delle funzioni di sintesi
groupBy + agg, le funzioni di aggregazione di base, le aggregazioni multi-colonna in un'unica passata, e perché agg è una wide transformation.
-
Lezione 17
Ordinamento alla scala: orderBy, sort e il costo del sort globale
Come funziona l'ordinamento in un motore distribuito, perché un sort globale è costoso, e la scappatoia sortWithinPartitions.
-
Lezione 18
Rinominare, droppare, fare cast: gli operatori di pulizia di tutti i giorni
withColumnRenamed, drop, cast e le operazioni piccole-ma-frequenti che costituiscono metà di qualsiasi ETL reale.
-
Lezione 19
Lazy evaluation: perché non succede niente finché non lo chiedi
Perché la tua catena di transformation non calcola davvero quando la chiami, cosa significa veramente 'lazy' in Spark, e l'aggiustamento mentale rispetto a Pandas che ogni nuovo arrivato deve fare.
-
Lezione 20
Transformation contro action: la dicotomia e il catalogo
Ogni operazione PySpark è o una transformation o un'action. Sapere qual è qual è metà del debug.
-
Lezione 21
Narrow contro wide transformation: il concetto più importante di Spark
Perché alcune transformation sono praticamente gratis e altre richiedono di shuffle l'intero cluster. La singola distinzione che spiega ogni domanda di performance su Spark.
-
Lezione 22
Il DAG: come Spark organizza il job in stage
Visualizzare il job come grafo aciclico diretto, leggere la tab Stages della Spark UI e la relazione tra stage e shuffle.
-
Lezione 23
Caching e persistence: storage level, quando ognuno ha senso
df.cache() e df.persist(): cosa fanno davvero, gli storage level offerti da Spark e i pattern tipici in cui il caching ripaga.
-
Lezione 24
.cache() non è gratis — quando usarlo e quando è una trappola
Il cache e il persist di Spark sembrano bottoni magici per le performance. Non lo sono. Ecco quando il caching aiuta davvero, quando peggiora le cose, e come capire la differenza.
-
Lezione 25
Cos'è davvero uno shuffle, in termini fisici
L'operazione di rete al cuore del calcolo distribuito, cosa succede durante uno shuffle e perché tutti lo temono.
-
Lezione 26
Join in PySpark: i sette tipi e quando usare ciascuno
Inner, left, right, full outer, semi, anti, cross: cosa fa ciascuno, la sintassi e i casi d'uso quotidiani.
-
Lezione 27
Broadcast join: quando le tabelle piccole viaggiano su ogni executor
Come i broadcast join saltano lo shuffle, quando Spark ne sceglie uno automaticamente, e come forzare o disabilitare il comportamento.
-
Lezione 28
Il problema dello skew: quando una chiave ha 100 volte le righe
Come lo skew dei dati rallenta i job anche quando il lavoro totale è poco, come individuarlo nella Spark UI, e che aspetto hanno i sintomi in produzione.
-
Lezione 29
Salting: la soluzione standard quando una chiave domina
Come spezzare una hot key aggiungendo un suffisso casuale sintetico, l'esempio pratico, e il costo del trucco.
-
Lezione 30
Join PySpark che non fanno saltare il cluster
Perché le join sono la principale fonte di dolore in Spark, cosa fa davvero lo shuffle, e i trucchi del broadcast e del salting che trasformano un job da 40 minuti in uno da 4.
-
Lezione 31
Cos'è una partition, fisicamente
Le partition in memoria, le partition su disco, e la relazione tra partition e task.
-
Lezione 32
spark.sql.shuffle.partitions = 200 e perché è quasi sempre sbagliato
Il singolo default più consequenziale in Spark, perché non si adatta al tuo cluster, e come tunarlo per il job che hai per le mani.
-
Lezione 33
repartition vs coalesce: due modi per cambiare il numero di partizioni
Quando usare l'uno e quando l'altro, il costo di ciascuno, e la trappola di serializzare per sbaglio l'intero job a un singolo task.
-
Lezione 34
Scritture partizionate: layout di directory, predicate pushdown, e quando farle
Colonne di partizione in stile Hive su disco, come Spark le usa in lettura per saltare file, e la trappola della cardinalità da evitare.
-
Lezione 35
Il partitioning: la cosa che silenziosamente ammazza il tuo job Spark
Come i dati vengono distribuiti tra gli executor, perché il default è quasi sempre sbagliato, e la danza repartition/coalesce che ogni job Spark prima o poi deve affrontare.
-
Lezione 36
Bucketing: quando il partitioning non basta
Hash-partitioning in un numero fisso di bucket in fase di scrittura, l'ottimizzazione del bucket join, e perché il bucketing è sottoutilizzato.
-
Lezione 37
PySpark SQL: quando SQL batte la sintassi DataFrame
Registrare temp view, chiamare spark.sql() e i casi in cui la stringa SQL è davvero più pulita della catena DataFrame.
-
Lezione 38
Window function: ranking, lag/lead, totali progressivi
Window.partitionBy().orderBy(), la famiglia delle window function e perché sono lo strumento secondo per utilità dopo groupBy.
-
Lezione 39
Pivot e unpivot: da wide a long e ritorno
Rimodellare i dati con pivot(), il trucco per fare unpivot prima di Spark 3.4 e il costo delle tabelle wide.
-
Lezione 40
UDF: quando ti servono, perché evitarle
La tassa di serializzazione Python delle UDF normali, perché pandas_udf ti salva, e i rari casi in cui Scala è l'unica risposta.
-
Lezione 41
Catalyst: il cervello dietro ogni DataFrame
Come Spark trasforma il tuo codice in un query plan, le quattro fasi di ottimizzazione, e come leggere .explain(True).
-
Lezione 42
Tungsten: code generation e layout di memoria colonnare
Come Spark fonde le operazioni in codice compilato, il formato colonnare off-heap, e perché DataFrame Spark è veloce.
-
Lezione 43
Parquet: perché è il default per un buon motivo
Lo storage columnar spiegato, codec di compressione, predicate pushdown e la struttura a row-group che rende veloci le letture selettive.
-
Lezione 44
ORC, Avro, Delta: le alternative e quando ognuna vince
Tre famiglie di formati che non sono Parquet, quando ognuna è la scelta giusta, e perché Delta sta silenziosamente prendendo il sopravvento.
-
Lezione 45
Leggere da JDBC: estrarre da Postgres, MySQL, SQL Server
Il connettore source JDBC, il trucco di partitionColumn, e perché una lettura ingenua manda al tappeto il database sorgente.
-
Lezione 46
Scrivere su JDBC: parallelismo, batch, idempotenza
Come riscrivere l'output di Spark in un database relazionale senza schiacciarlo, rompere transazioni o perdere dati al retry.
-
Lezione 47
Cloud storage: S3, GCS, Azure Blob, cosa cambia
Le note in piccolo sulla consistency, il problema del rename, e perche' esistono i committer direct-write.
-
Lezione 48
Schema evolution: quando le colonne ti cambiano sotto
Perché i formati schema-on-read gestiscono male il cambiamento, perché Avro+registry lo gestisce bene, e il modo Delta/Iceberg di avere entrambe le cose.
-
Lezione 49
Perché lo streaming, e cosa significa davvero 'streaming' in Spark
Dati bounded vs unbounded, batch e streaming come continuum, e perché i DStreams sono deprecati a favore di Structured Streaming.
-
Lezione 50
Structured Streaming: le basi di readStream, writeStream, trigger
Gli entry point per lo streaming, la semantica dei trigger, e il checkpoint da cui dipende tutto.
-
Lezione 51
Kafka source: l'ingest di produzione più comune
Come Spark legge da Kafka, la semantica degli offset, e la questione at-least-once vs exactly-once.
-
Lezione 52
Watermark ed event time: la parte che quasi tutti i principianti sbagliano
Perché l'event time conta più del processing time, cosa fa davvero un watermark, e l'esempio guidato con timestamp concreti.
-
Lezione 53
Operazioni stateful: aggregazioni, sessioni e lo state store
Dove Spark Streaming tiene lo stato tra micro-batch, i pattern stateful standard, e quando scendere a mapGroupsWithState.
-
Lezione 54
Output mode e sink idempotenti: foreachBatch e il pattern di upsert
Append vs update vs complete, i sink che Spark fornisce, e l'escape hatch foreachBatch per tutto il resto.
-
Lezione 55
La Spark UI: lo strumento più importante che imparerai
Un giro guidato di ogni tab (Jobs, Stages, Tasks, SQL, Storage, Executors) e cosa ti dice ognuno quando qualcosa va storto.
-
Lezione 56
Leggere gli execution plan: .explain(True), dal parsed al physical
Come leggere ogni riga dell'output di .explain(), gli operatori che contano, e i passi dell'optimizer che li producono.
-
Lezione 57
Memory tuning: executor memory, overhead, diagnostica degli OOM
I quattro config che davvero contano, cosa significa spill, come si legge uno stack trace di OOM, e la regola per dimensionare gli executor.
-
Lezione 58
Debug di job Spark lenti: la checklist da 30 minuti
Il loop sistematico per capire cosa non va in un job lento: leggi la UI, trova lo stage lento, guarda lo skew dei task, GC, volume di shuffle, in quest'ordine.
-
Lezione 59
Adaptive Query Execution: la killer feature di Spark 3.x
Dynamic partition coalescing, gestione dello skew a runtime e switch della strategia di join: le config da conoscere e i casi in cui AQE non può aiutarti.
-
Lezione 60
Un health check da 30 minuti su un cluster Spark che non hai mai visto
La checklist di chiusura: ti consegnano il portatile, hai tempo fino alle 17 per capire cosa non va.
