Tutorial: architettura e cluster dell'applicazione Spark

Ottieni il libro completo
Analisi dei dati con Spark utilizzando Python (serie di dati e analisi di Addison-Wesley) Prezzo consigliato $ 44,99 Guardalo

Questo articolo è un estratto dal libro di Pearson Addison-Wesley "Analisi dei dati con Spark utilizzando Python" di Jeffrey Aven. Ristampato qui con il permesso di Pearson © 2018. Per ulteriori informazioni, visitare informit.com/aven/infoworld.

Prima di iniziare il tuo viaggio come programmatore Apache Spark, dovresti avere una solida conoscenza dell'architettura dell'applicazione Spark e del modo in cui le applicazioni vengono eseguite su un cluster Spark. Questo articolo esamina da vicino i componenti di un'applicazione Spark, esamina il modo in cui questi componenti funzionano insieme e guarda come le applicazioni Spark vengono eseguite su cluster autonomi e YARN.

Anatomia di un'applicazione Spark

Un'applicazione Spark contiene diversi componenti, tutti presenti sia che tu stia eseguendo Spark su una singola macchina o su un cluster di centinaia o migliaia di nodi.

Ogni componente ha un ruolo specifico nell'esecuzione di un programma Spark. Alcuni di questi ruoli, come i componenti client, sono passivi durante l'esecuzione; altri ruoli sono attivi nell'esecuzione del programma, inclusi i componenti che eseguono funzioni di calcolo.

I componenti di un'applicazione Spark sono:

  • l'autista
  • Il capo
  • il cluster manager
  • gli esecutori

Funzionano tutti sui nodi di lavoro, ovvero i lavoratori.

La Figura 1 mostra tutti i componenti Spark nel contesto di un'applicazione Spark autonoma.

Pearson Addison-Wesley

Tutti i componenti Spark, inclusi i processi driver, master ed esecutore, vengono eseguiti su Java virtual machine. Una JVM è un motore runtime multipiattaforma in grado di eseguire istruzioni compilate in bytecode Java. Scala, in cui è scritto Spark, compila in bytecode e gira su JVM.

È importante distinguere tra i componenti dell'applicazione runtime di Spark e le posizioni e i tipi di nodo su cui vengono eseguiti. Questi componenti vengono eseguiti in luoghi diversi utilizzando diverse modalità di distribuzione, quindi non pensare a questi componenti in termini di nodo fisico o istanza. Ad esempio, quando si esegue Spark su YARN, ci sarebbero diverse varianti della Figura 1. Tuttavia, tutti i componenti raffigurati sono ancora coinvolti nell'applicazione e hanno gli stessi ruoli.

Spark driver

La vita di un'applicazione Spark inizia e finisce con il driver Spark. Il driver è il processo utilizzato dai client per inviare le applicazioni in Spark. L'autista è anche responsabile della pianificazione e del coordinamento dell'esecuzione del programma Spark e della restituzione dello stato e / o dei risultati (dati) al cliente. Il driver può risiedere fisicamente su un client o su un nodo del cluster, come vedrai in seguito.

SparkSession

Il driver Spark è responsabile della creazione di SparkSession. L'oggetto SparkSession rappresenta una connessione a un cluster Spark. SparkSession viene istanziato all'inizio di un'applicazione Spark, incluse le shell interattive, e viene utilizzato per l'intero programma.

Prima di Spark 2.0, i punti di ingresso per le applicazioni Spark includevano SparkContext, utilizzato per le applicazioni principali di Spark; SQLContext e HiveContext, utilizzati con le applicazioni Spark SQL; e StreamingContext, utilizzato per le applicazioni Spark Streaming. L'oggetto SparkSession introdotto in Spark 2.0 combina tutti questi oggetti in un unico punto di ingresso che può essere utilizzato per tutte le applicazioni Spark.

Attraverso i suoi oggetti figlio SparkContext e SparkConf, l'oggetto SparkSession contiene tutte le proprietà di configurazione di runtime impostate dall'utente, incluse le proprietà di configurazione come il master, il nome dell'applicazione e il numero di esecutori. La figura 2 mostra l'oggetto SparkSession e alcune delle sue proprietà di configurazione in una pysparkshell.

Pearson Addison-Wesley

Nome SparkSession

Il nome dell'oggetto per l'istanza di SparkSession è arbitrario. Per impostazione predefinita, viene denominata l'istanza di SparkSession nelle shell interattive di Spark spark. Per coerenza, si crea sempre un'istanza di SparkSession come spark; tuttavia, il nome è a discrezione dello sviluppatore.

Il codice seguente mostra come creare una SparkSession in un'applicazione Spark non interattiva, ad esempio un programma inviato utilizzando spark-submit.

da pyspark.sql importa SparkSession

spark = SparkSession.builder \

  .master ("spark: // sparkmaster: 7077") \

  .appName ("La mia applicazione Spark") \

  .config ("spark.submit.deployMode", "client") \

  .getOrCreate ()

numlines = spark.sparkContext.textFile ("file: /// opt / spark / licenze") \

  .contare()

print ("Il numero totale di righe è" + str (numlines))

Pianificazione dell'applicazione

Una delle funzioni principali del driver è la pianificazione dell'applicazione. Il driver prende l'input di elaborazione dell'applicazione e pianifica l'esecuzione del programma. Il driver prende tutte le trasformazioni richieste (operazioni di manipolazione dei dati) e le azioni (richieste di output o prompt per eseguire programmi) e crea un grafo aciclico diretto (DAG) di nodi, ognuno dei quali rappresenta un passaggio di trasformazione o di calcolo.

Grafico aciclico diretto (DAG)

Un DAG è un costrutto matematico comunemente utilizzato in informatica per rappresentare i flussi di dati e le loro dipendenze. I gruppi di disponibilità del database contengono vertici (o nodi) e bordi. I vertici in un contesto di flusso di dati sono passaggi nel flusso di processo. I bordi in un DAG collegano i vertici tra loro in un orientamento diretto e in modo tale che sia impossibile avere riferimenti circolari.

Un DAG dell'applicazione Spark è costituito da attività e fasi . Un'attività è la più piccola unità di lavoro pianificabile in un programma Spark. Una fase è un insieme di attività che possono essere eseguite insieme. Le fasi dipendono l'una dall'altra; in altre parole, ci sono dipendenze di fase .

In un senso di pianificazione del processo, i DAG non sono esclusivi di Spark. Ad esempio, vengono utilizzati in altri progetti dell'ecosistema di big data, come Tez, Drill e Presto per la pianificazione. I DAG sono fondamentali per Spark, quindi vale la pena conoscere il concetto.

Orchestrazione delle applicazioni

Il driver coordina anche l'esecuzione delle fasi e delle attività definite nel DAG. Le attività chiave del conducente coinvolte nella pianificazione e nell'esecuzione delle attività includono quanto segue:

  • Tenere traccia delle risorse disponibili per eseguire le attività.
  • Pianificazione delle attività da eseguire "vicino" ai dati ove possibile (il concetto di località dei dati).

Altre funzioni

Oltre a pianificare e orchestrare l'esecuzione di un programma Spark, il driver è anche responsabile della restituzione dei risultati da un'applicazione. Questi potrebbero essere codici di ritorno o dati nel caso di un'azione che richiede la restituzione dei dati al client (ad esempio, una query interattiva).

Il driver serve anche l'interfaccia utente dell'applicazione sulla porta 4040, come mostrato nella Figura 3. Questa interfaccia utente viene creata automaticamente; è indipendente dal codice inviato o da come è stato inviato (ovvero, utilizzo interattivo pyspark o utilizzo non interattivo spark-submit).

Pearson Addison-Wesley

Se le applicazioni successive vengono avviate sullo stesso host, le porte successive vengono utilizzate per l'interfaccia utente dell'applicazione (ad esempio, 4041, 4042 e così via).

Spark lavoratori ed esecutori

Gli esecutori Spark sono i processi in cui vengono eseguite le attività del DAG Spark. gli esecutori riservano la CPU e le risorse di memoria sui nodi slave, o worker, in un cluster Spark. Un esecutore è dedicato a una specifica applicazione Spark e viene terminato al completamento dell'applicazione. Un programma Spark normalmente è costituito da molti esecutori, che spesso lavorano in parallelo.

In genere, un nodo di lavoro, che ospita il processo esecutore, ha un numero finito o fisso di esecutori allocati in qualsiasi momento. Pertanto, un cluster, essendo un numero noto di nodi, ha un numero finito di esecutori disponibili per l'esecuzione in un dato momento. Se un'applicazione richiede esecutori in eccesso rispetto alla capacità fisica del cluster, è pianificato per l'avvio quando gli altri esecutori completano e rilasciano le proprie risorse.

Come accennato in precedenza, le JVM ospitano gli esecutori Spark. Alla JVM per un esecutore viene allocato un heap , che è uno spazio di memoria dedicato in cui memorizzare e gestire gli oggetti.

La quantità di memoria impegnato all'heap JVM per un esecutore è impostato dalla proprietà spark.executor.memoryo come --executor-memoryargomento per le pyspark, spark-shello spark-submitcomandi.

Gli esecutori archiviano i dati di output dalle attività in memoria o su disco. È importante notare che i lavoratori e gli esecutori sono consapevoli solo dei compiti loro assegnati, mentre il conducente è responsabile della comprensione della serie completa di compiti e delle rispettive dipendenze che compongono un'applicazione.

Utilizzando l'interfaccia utente dell'applicazione Spark sulla porta 404 x dell'host del driver, è possibile esaminare gli esecutori dell'applicazione, come mostrato nella Figura 4.

Pearson Addison-Wesley

Per le distribuzioni di cluster autonomi di Spark, un nodo di lavoro espone un'interfaccia utente sulla porta 8081, come mostrato nella Figura 5.

Pearson Addison-Wesley

Il master Spark e il gestore cluster

Il driver Spark pianifica e coordina il set di attività richieste per eseguire un'applicazione Spark. Le attività stesse vengono eseguite negli esecutori, che sono ospitati sui nodi di lavoro.

Il master e il cluster manager sono i processi centrali che monitorano, riservano e allocano le risorse del cluster distribuito (o contenitori, nel caso di YARN o Mesos) su cui vengono eseguiti gli esecutori. Il master e il gestore cluster possono essere processi separati oppure possono essere combinati in un unico processo, come nel caso di Spark in modalità standalone.

Spark master

Il master Spark è il processo che richiede risorse nel cluster e le rende disponibili al driver Spark. In tutte le modalità di distribuzione, il master negozia risorse o contenitori con nodi di lavoro o nodi slave e tiene traccia del loro stato e monitora il loro progresso.

Quando si esegue Spark in modalità autonoma, il processo master Spark serve un'interfaccia utente Web sulla porta 8080 nell'host master, come mostrato nella Figura 6.

Pearson Addison-Wesley

Spark master contro Spark driver

È importante distinguere le funzioni di runtime del driver e del master. Si può dedurre che il nome master significhi che questo processo governa l'esecuzione dell'applicazione, ma non è questo il caso. Il master richiede semplicemente risorse e le rende disponibili al conducente. Sebbene il master monitori lo stato e l'integrità di queste risorse, non è coinvolto nell'esecuzione dell'applicazione e nel coordinamento delle sue attività e fasi. Questo è il lavoro dell'autista.

Gestore cluster

Il gestore cluster è il processo responsabile del monitoraggio dei nodi di lavoro e della prenotazione delle risorse su questi nodi su richiesta del master. Il master rende quindi queste risorse del cluster disponibili al driver sotto forma di esecutori.

Come notato in precedenza, il gestore cluster può essere separato dal processo master. Questo è il caso in cui si esegue Spark su Mesos o YARN. Nel caso di Spark in esecuzione in modalità standalone, il processo master esegue anche le funzioni del gestore cluster. In effetti, agisce come il proprio cluster manager.

Un buon esempio della funzione di gestione del cluster è il processo YARN ResourceManager per le applicazioni Spark in esecuzione su cluster Hadoop. Il ResourceManager pianifica, alloca e monitora l'integrità dei contenitori in esecuzione su YARN NodeManagers. Le applicazioni Spark usano quindi questi contenitori per ospitare i processi esecutori, nonché il processo master se l'applicazione è in esecuzione in modalità cluster.

Spark applicazioni che utilizzano lo scheduler autonomo

Nel capitolo 2, "Distribuzione di Spark", ho spiegato lo scheduler autonomo come opzione di distribuzione per Spark. Lì, ho distribuito un cluster autonomo Spark multinodo completamente funzionante in uno degli esercizi nel Capitolo 2. Come notato in precedenza, in un cluster Spark in esecuzione in modalità standalone, il processo principale Spark esegue anche la funzione di gestore cluster, governando le risorse disponibili sul cluster e concedendoli al processo master per l'utilizzo in un'applicazione Spark.

Applicazioni Spark in esecuzione su YARN

Hadoop è una piattaforma di distribuzione molto popolare e comune per Spark. Alcuni esperti del settore ritengono che Spark sostituirà presto MapReduce come piattaforma di elaborazione principale per le applicazioni in Hadoop. Le applicazioni Spark su YARN condividono la stessa architettura di runtime ma presentano alcune lievi differenze nell'implementazione.

ResourceManager come gestore del cluster

A differenza dello scheduler autonomo, il gestore cluster in un cluster YARN è il ResourceManager YARN. Il ResourceManager monitora l'utilizzo e la disponibilità delle risorse su tutti i nodi di un cluster. I client inviano le applicazioni Spark a YARN ResourceManager. Il ResourceManager alloca il primo contenitore per l'applicazione, un contenitore speciale chiamato ApplicationMaster.

ApplicationMaster come master Spark

ApplicationMaster è il processo principale di Spark. Come fa il processo master in altre distribuzioni cluster, ApplicationMaster negozia le risorse tra il driver dell'applicazione e il gestore cluster (o ResourceManager in questo caso); quindi rende queste risorse (contenitori) disponibili al driver per essere utilizzate come esecutori per eseguire attività e archiviare dati per l'applicazione.

ApplicationMaster rimane per tutta la durata dell'applicazione.

Modalità di distribuzione per le applicazioni Spark in esecuzione su YARN

Quando si inviano applicazioni Spark a un cluster YARN, è possibile utilizzare due modalità di distribuzione: modalità client e modalità cluster. Vediamoli adesso.

Modalità client

In modalità client, il processo del driver viene eseguito sul client che invia l'applicazione. È essenzialmente non gestito; se l'host del driver non riesce, l'applicazione non riesce. Modalità client è supportata per entrambe le sessioni di shell interattive ( pyspark, spark-shelle così via) e presentazione applicazione non interattivo ( spark-submit). Il codice seguente mostra come avviare una pysparksessione utilizzando la modalità di distribuzione client.

$ SPARK_HOME / bin / pyspark \

--master filato-cliente \

--num-executors 1 \

--driver-memory 512m \

--executor-memory 512m \

--executor-core 1

# OR

$ SPARK_HOME / bin / pyspark \

- filo maestro \

- client in modalità distribuzione \

--num-executors 1 \

--driver-memory 512m \

--executor-memory 512m \

--executor-core 1

La figura 7 fornisce una panoramica di un'applicazione Spark in esecuzione su YARN in modalità client.

Pearson Addison-Wesley

I passaggi mostrati nella Figura 7 sono:

  1. Il client invia un'applicazione Spark al gestore cluster (YARN ResourceManager). Il processo driver, SparkSession e SparkContext vengono creati ed eseguiti nel client.
  2. Il ResourceManager assegna un ApplicationMaster (il master Spark) per l'applicazione.
  3. ApplicationMaster richiede l'utilizzo dei contenitori per gli esecutori dal ResourceManager. Con i contenitori assegnati, gli esecutori vengono generati.
  4. Il driver, situato sul client, comunica quindi con gli esecutori per eseguire il marshalling dell'elaborazione delle attività e delle fasi del programma Spark. Il driver restituisce l'avanzamento, i risultati e lo stato al client.

La modalità di distribuzione del client è la modalità più semplice da utilizzare. Tuttavia, manca della resilienza richiesta per la maggior parte delle applicazioni di produzione.

Modalità cluster

A differenza della modalità di distribuzione client, con un'applicazione Spark in esecuzione in modalità YARN Cluster, il driver stesso viene eseguito sul cluster come sottoprocesso di ApplicationMaster. Ciò fornisce resilienza: se il processo ApplicationMaster che ospita il driver non riesce, può essere nuovamente istanziato su un altro nodo nel cluster.

Il codice seguente mostra come inviare un'applicazione utilizzando spark-submite la modalità di distribuzione del cluster YARN. Poiché il driver è un processo asincrono in esecuzione nel cluster, la modalità cluster non è supportata per le applicazioni shell interattive ( pysparke spark-shell).

$ SPARK_HOME / bin / spark-submit \

--master filato-cluster \

--num-executors 1 \

--driver-memory 512m \

--executor-memory 512m \

--executor-core 1

$ SPARK_HOME / examples / src / main / python / pi.py 10000

# O

- filo maestro \

- cluster in modalità distribuzione \

--num-executors 1 \

--driver-memory 512m \

--executor-memory 512m \

--executor-core 1

$ SPARK_HOME / examples / src / main / python / pi.py 10000

La figura 8 fornisce una panoramica di un'applicazione Spark in esecuzione su YARN in modalità cluster.

Pearson Addison-Wesley

I passaggi mostrati nella Figura 8 sono:

  1. Il client, un processo utente che richiama spark-submit, invia un'applicazione Spark al gestore cluster (il ResourceManager YARN).
  2. Il ResourceManager assegna un ApplicationMaster (il master Spark) per l'applicazione. Il processo driver viene creato sullo stesso nodo del cluster.
  3. ApplicationMaster richiede contenitori per gli esecutori dal ResourceManager. gli esecutori vengono generati nei contenitori allocati ad ApplicationMaster dal ResourceManager. Il driver quindi comunica con gli esecutori per eseguire il marshalling dell'elaborazione delle attività e delle fasi del programma Spark.
  4. Il driver, in esecuzione su un nodo del cluster, restituisce l'avanzamento, i risultati e lo stato al client.

L'interfaccia utente Web dell'applicazione Spark, come mostrato in precedenza, è disponibile dall'host ApplicationMaster nel cluster; un collegamento a questa interfaccia utente è disponibile dall'interfaccia utente di YARN ResourceManager.

Modalità locale rivisitata

In modalità locale, il driver, il master e l'esecutore vengono eseguiti in un'unica JVM. Come notato in precedenza in questo capitolo, ciò è utile per lo sviluppo, il test di unità e il debug, ma ha un uso limitato per l'esecuzione di applicazioni di produzione perché non è distribuito e non è scalabile. Inoltre, le attività non riuscite in un'applicazione Spark in esecuzione in modalità locale non vengono rieseguite per impostazione predefinita. Tuttavia, puoi ignorare questo comportamento.

Quando si esegue Spark in modalità locale, l'interfaccia utente dell'applicazione è disponibile in // localhost: 4040. Le interfacce utente master e worker non sono disponibili durante l'esecuzione in modalità locale.