Apache Spark è un framework per l’elaborazione dei dati in grado di eseguire rapidamente attività di elaborazione su insiemi di dati molto grandi e di distribuire le attività di elaborazione dei dati su più computer, da solo o in tandem con altri strumenti di calcolo distribuito. Queste due qualità sono fondamentali per i mondi dei big data e del machine learning, che richiedono l’impiego di un’enorme potenza di calcolo per elaborare grandi archivi di dati. Spark, inoltre, toglie agli sviluppatori alcuni degli oneri di programmazione di questi compiti, grazie a un’API facile da usare che astrae gran parte del lavoro di calcolo distribuito e di elaborazione dei big data.

Dalle sue umili origini nell’AMPLab dell’U.C. Berkeley nel 2009, Apache Spark è diventato uno dei principali framework di elaborazione distribuita dei big data al mondo. Spark può essere distribuito in diversi modi, offre binding nativi per i linguaggi di programmazione Java, Scala, Python e R e supporta SQL, streaming di dati, machine learning ed elaborazione di grafi. È utilizzato da banche, società di telecomunicazioni, governi e da tutti i principali colossi tecnologici come Apple, IBM, Meta e Microsoft.

Spark RDD

Il cuore di Apache Spark è il concetto di Resilient Distributed Dataset (RDD), un’astrazione di programmazione che rappresenta una collezione immutabile di oggetti che possono essere suddivisi in un cluster di calcolo. Anche le operazioni sugli RDD possono essere suddivise tra i cluster ed eseguite in un processo batch parallelo, per un’elaborazione parallela veloce e scalabile. Apache Spark trasforma i comandi di elaborazione dei dati dell’utente in un Directed Acyclic Graph, o DAG. Il DAG è il livello di pianificazione di Apache Spark e determina quali compiti vengono eseguiti su quali nodi e in quale sequenza.

Gli RDD possono essere creati da semplici file di testo, database SQL, archivi NoSQL (come Cassandra e MongoDB), bucket Amazon S3 e molto altro ancora. Gran parte dell’API di Spark Core è costruita su questo concetto di RDD, consentendo le tradizionali funzionalità di mappatura e riduzione, ma anche fornendo un supporto integrato per l’unione di set di dati, il filtraggio, il campionamento e l’aggregazione.

Spark funziona in modo distribuito grazie alla combinazione di un processo core driver che suddivide un’applicazione Spark in task e li distribuisce tra molti processi executor che svolgono il lavoro. Questi “esecutori” possono essere scalati verso l’alto o verso il basso in base alle esigenze dell’applicazione.

Spark SQL

Spark SQL è diventato sempre più importante per il progetto Apache Spark. È l’interfaccia più utilizzata dagli sviluppatori di oggi per creare applicazioni. Spark SQL si concentra sull’elaborazione di dati strutturati, utilizzando un approccio dataframe mutuato da R e Python (in Pandas). Ma come suggerisce il nome, Spark SQL fornisce anche un’interfaccia conforme a SQL2003 per l’interrogazione dei dati, portando la potenza di Apache Spark agli analisti e agli sviluppatori.

Oltre al supporto SQL standard, Spark SQL fornisce un’interfaccia standard per la lettura e la scrittura di altri archivi di dati, tra cui JSON, HDFS, Apache Hive, JDBC, Apache ORC e Apache Parquet, tutti supportati in modo immediato. Altri data store popolari come Apache Cassandra, MongoDB, Apache HBase e molti altri possono essere utilizzati usando connettori separati dell’ecosistema Spark Packages. Spark SQL permette di utilizzare in modo trasparente le funzioni definite dall’utente (UDF) nelle query SQL.

Selezionare alcune colonne da un dataframe è semplice come questa riga di codice: citiesDF.select(“nome”, “pop”). Utilizzando l’interfaccia SQL, registriamo il dataframe come tabella temporanea, dopodiché possiamo eseguire query SQL su di esso:

citiesDF.createOrReplaceTempView(“cities”)
spark.sql(“SELECT name, pop FROM cities”)

Dietro le quinte, Apache Spark utilizza un ottimizzatore di query chiamato Catalyst che esamina i dati e le query al fine di produrre un piano di query efficiente per la localizzazione dei dati e il calcolo che eseguirà i calcoli richiesti in tutto il cluster. Da Apache Spark 2.x, l’interfaccia Spark SQL di dataframe e dataset (essenzialmente un dataframe tipizzato che può essere controllato in fase di compilazione per verificarne la correttezza e sfruttare ulteriori ottimizzazioni di memoria e calcolo in fase di esecuzione) è l’approccio consigliato per lo sviluppo. L’interfaccia RDD è ancora disponibile, ma è consigliata solo se le vostre esigenze non possono essere soddisfatte all’interno del paradigma Spark SQL (ad esempio quando dovete lavorare a un livello più basso per spremete al massimo il sistema).

Spark MLlib e MLflow

Apache Spark include anche librerie per l’applicazione di tecniche di machine learning e di analisi dei grafi ai dati su scala. MLlib include un framework per la creazione di pipeline di machine learning, che consente di implementare facilmente l’estrazione di caratteristiche, le selezioni e le trasformazioni su qualsiasi set di dati strutturati. MLlib è dotato di implementazioni distribuite di algoritmi di clustering e classificazione, come il k-means clustering e le foreste casuali, che possono essere inserite e disinserite nelle pipeline personalizzate con estrema facilità. I modelli possono essere addestrati dai data scientist in Apache Spark utilizzando R o Python, salvati con MLlib e quindi importati in una pipeline basata su Java o Scala per l’uso in produzione.

La piattaforma open source per la gestione del ciclo di vita del machine learning MLflow non fa tecnicamente parte del progetto Apache Spark, ma è un prodotto di Databricks e di altri membri della comunità Apache Spark. La comunità ha lavorato all’integrazione di MLflow con Apache Spark per fornire funzionalità MLOps come il monitoraggio degli esperimenti, i registri dei modelli, il packaging e le UDF che possono essere facilmente importate per l’inferenza su scala Apache Spark e con le tradizionali istruzioni SQL.

Structured Streaming

Structured Streaming è un’API di alto livello che consente agli sviluppatori di creare dataframe e dataset in streaming infinito. A partire da Spark 3.0, lo Structured Streaming è il modo consigliato per gestire i dati in streaming in Apache Spark, sostituendo il precedente approccio Spark Streaming. Spark Streaming (ora classificato come componente legacy) era pieno di problemi per gli sviluppatori, soprattutto quando si trattava di aggregazioni in tempo reale e di consegna tardiva dei messaggi.

Tutte le query sui flussi strutturati passano attraverso l’ottimizzatore di query Catalyst e possono essere eseguite anche in modo interattivo, consentendo agli utenti di eseguire query SQL sui dati in streaming in diretta. In Spark 3.1 e successivi è possibile trattare i flussi come tabelle e le tabelle come flussi. La possibilità di combinare più flussi con un’ampia gamma di join stream-to-stream di tipo SQL crea potenti possibilità di ingestione e trasformazione. Ecco un semplice esempio di creazione di una tabella da una fonte di streaming:

val df = spark.readStream
.format(“rate”)
.option(“rowsPerSecond”, 20)
.load()

df.writeStream
.option(“checkpointLocation”, “checkpointPath”)
.toTable(“streamingTable”)

spark.read.table(“myTable”).show()

apache

Structured Streaming, per impostazione predefinita, utilizza uno schema di micro-batching per gestire i dati in streaming. Ma in Spark 2.3, il team di Apache Spark ha aggiunto la modalità Continuous Processing a bassa latenza allo Structured Streaming, consentendogli di gestire risposte con latenze impressionanti, fino a 1 ms, e rendendolo molto più competitivo rispetto a rivali come Apache Flink e Apache Beam. Continuous Processing limita le operazioni di tipo mappa e selezione e, sebbene supporti le query SQL contro gli stream, al momento non supporta le aggregazioni SQL. Inoltre, nonostante Spark 2.3 sia arrivato nel 2018, a partire da Spark 3.3.2 nel marzo 2023, Continuous Processing è ancora contrassegnato come sperimentale.

Structured Streaming è il futuro delle applicazioni di streaming con la piattaforma Apache Spark; se quindi state costruendo una nuova applicazione di streaming, dovresti utilizzare Structured Streaming. Le API di Spark Streaming tradizionali continueranno a essere supportate, ma il progetto consiglia di passare a Structured Streaming, in quanto il nuovo metodo rende la scrittura e la manutenzione del codice di streaming molto più sopportabile.

Delta Lake

Come MLflow, Delta Lake è tecnicamente un progetto separato da Apache Spark. Negli ultimi due anni, tuttavia, è diventato parte integrante dell’ecosistema Spark, costituendo il nucleo di quella che Databricks chiama Lakehouse Architecture. Delta Lake aumenta i data lake basati sul cloud con transazioni ACID, semantica di interrogazione unificata per l’elaborazione batch e stream e applicazione dello schema, eliminando di fatto la necessità di un data warehouse separato per gli utenti BI. Anche la cronologia completa degli audit e la scalabilità per gestire exabyte di dati fanno parte del pacchetto.

L’utilizzo del formato Delta Lake (costruito sulla base dei file Parquet) all’interno di Apache Spark è semplice come l’utilizzo del formato delta:

df = spark.readStream.format(“rate”).load()

stream = df
.writeStream
.format(“delta”)
.option(“checkpointLocation”, “checkpointPath”)
.start(“deltaTable”)

API Pandas su Spark

Lo standard industriale per la manipolazione e l’analisi dei dati in Python è la libreria Pandas. Con Apache Spark 3.2, è stata introdotta una nuova API che consente di utilizzare gran parte delle API di Pandas in modo trasparente con Spark. Ora i data scientist possono semplicemente sostituire le loro importazioni con import pyspark.pandas as pd ed essere certi che il loro codice continuerà a funzionare, sfruttando anche l’esecuzione multi-nodo di Apache Spark. Al momento è coperto circa l’80% dell’API di Pandas, con un obiettivo di copertura del 90% nelle prossime versioni.

Esecuzione di Apache Spark

A livello fondamentale, un’applicazione Apache Spark è costituita da due componenti principali: un driver, che converte il codice dell’utente in compiti multipli che possono essere distribuiti tra i nodi worker, e gli executor, che vengono eseguiti su questi nodi worker ed eseguono i compiti a loro assegnati. Per mediare tra i due è necessaria una forma di cluster manager.

Apache Spark può essere eseguito in modalità cluster stand-alone e richiede semplicemente il framework Apache Spark e una Java Virtual Machine su ogni nodo del cluster. Tuttavia, è più probabile che vogliate sfruttare un sistema di gestione delle risorse o di cluster più robusto che si occupi di allocare i lavoratori su richiesta.

In ambito aziendale, questo ha significato storicamente l’esecuzione su Hadoop YARN (YARN è il modo in cui le distribuzioni di Cloudera e Hortonworks eseguono i lavori Spark), ma poiché Hadoop è diventato meno radicato, sempre più aziende si sono orientate verso l’implementazione di Apache Spark su Kubernetes. Questo si è riflesso nelle versioni di Apache Spark 3.x, che hanno migliorato l’integrazione con Kubernetes, compresa la possibilità di definire modelli di pod per driver ed executor e di utilizzare scheduler personalizzati come Volcano.

Se cercate una soluzione gestita, le offerte di Apache Spark sono disponibili su tutti e tre i grandi cloud: Amazon EMR, Azure HDInsight e Google Cloud Dataproc.

Piattaforma Lakehouse di Databricks

Databricks, l’azienda che impiega i creatori di Apache Spark, ha adottato un approccio diverso rispetto a molte altre aziende fondate sui prodotti open source dell’era dei Big Data. Per molti anni, Databricks ha fornito un servizio cloud gestito completo che offre cluster Apache Spark, supporto per lo streaming e prestazioni I/O ottimizzate proprietarie rispetto a una distribuzione Apache Spark standard. Questo mix di servizi gestiti e professionali ha trasformato Databricks in un colosso nel settore dei Big Data, con una valutazione stimata in 38 miliardi di dollari nel 2021. La Databricks Lakehouse Platform è ora disponibile su tutti e tre i principali provider di cloud e sta diventando il modo in cui la maggior parte delle persone interagisce con Apache Spark.

Tutorial su Apache Spark

Siete pronti a immergervi in Apache Spark? Vi consigliamo di iniziare con il portale di apprendimento Databricks che fornisce una buona introduzione al framework, anche se è leggermente orientato verso la piattaforma Databricks. Per approfondire, vi suggeriamo lo Spark Workshop, un tour approfondito delle caratteristiche di Apache Spark attraverso l’ottica di Scala. Sono disponibili anche alcuni libri di eccellente fattura. Spark: The Definitive Guide è una splendida introduzione scritta da due manutentori di Apache Spark, mentre High Performance Spark è una guida essenziale per elaborare i dati con Apache Spark su larga scala e in modo performante.