Tutorial: Spark-Anwendungsarchitektur und Cluster

Holen Sie sich das vollständige Buch
Datenanalyse mit Funken unter Verwendung von Python (Addison-Wesley Data & Analytics-Reihe) UVP 44,99 USD Sehen Sie es

Dieser Artikel ist ein Auszug aus dem Pearson Addison-Wesley-Buch „Data Analytics with Spark Using Python“ von Jeffrey Aven. Nachdruck hier mit freundlicher Genehmigung von Pearson © 2018. Weitere Informationen finden Sie unter informit.com/aven/infoworld.

Bevor Sie Ihre Reise als Apache Spark-Programmierer beginnen, sollten Sie ein solides Verständnis der Spark-Anwendungsarchitektur und der Ausführung von Anwendungen in einem Spark-Cluster haben. In diesem Artikel werden die Komponenten einer Spark-Anwendung eingehend untersucht, wie diese Komponenten zusammenarbeiten und wie Spark-Anwendungen auf eigenständigen und YARN-Clustern ausgeführt werden.

Anatomie einer Spark-Anwendung

Eine Spark-Anwendung enthält mehrere Komponenten, die alle vorhanden sind, unabhängig davon, ob Sie Spark auf einem einzelnen Computer oder in einem Cluster von Hunderten oder Tausenden von Knoten ausführen.

Jede Komponente hat eine bestimmte Rolle bei der Ausführung eines Spark-Programms. Einige dieser Rollen, z. B. die Clientkomponenten, sind während der Ausführung passiv. Bei der Ausführung des Programms sind andere Rollen aktiv, einschließlich Komponenten, die Berechnungsfunktionen ausführen.

Die Komponenten einer Spark-Anwendung sind:

  • der Fahrer
  • der Meister
  • der Cluster-Manager
  • die Testamentsvollstrecker

Sie laufen alle auf Arbeiterknoten, auch bekannt als Arbeiter.

Abbildung 1 zeigt alle Spark-Komponenten im Kontext einer eigenständigen Spark-Anwendung.

Pearson Addison-Wesley

Alle Spark-Komponenten - einschließlich der Treiber-, Master- und Executor-Prozesse - werden in virtuellen Java-Maschinen ausgeführt. Eine JVM ist eine plattformübergreifende Laufzeit-Engine, die in Java-Bytecode kompilierte Anweisungen ausführen kann. Scala, in die Spark geschrieben ist, wird in Bytecode kompiliert und auf JVMs ausgeführt.

Es ist wichtig, zwischen den Laufzeitanwendungskomponenten von Spark und den Speicherorten und Knotentypen zu unterscheiden, auf denen sie ausgeführt werden. Diese Komponenten werden an verschiedenen Orten mit unterschiedlichen Bereitstellungsmodi ausgeführt. Denken Sie also nicht an diese Komponenten in Bezug auf physische Knoten oder Instanzen. Wenn Sie beispielsweise Spark auf YARN ausführen, gibt es verschiedene Variationen von Abbildung 1. Alle abgebildeten Komponenten sind jedoch weiterhin an der Anwendung beteiligt und haben dieselben Rollen.

Funkenfahrer

Die Lebensdauer einer Spark-Anwendung beginnt und endet mit dem Spark-Treiber. Der Treiber ist der Prozess, mit dem Clients Anträge in Spark senden. Der Fahrer ist auch dafür verantwortlich, die Ausführung des Spark-Programms zu planen und zu koordinieren und den Status und / oder die Ergebnisse (Daten) an den Kunden zurückzugeben. Der Treiber kann sich physisch auf einem Client oder einem Knoten im Cluster befinden, wie Sie später sehen werden.

SparkSession

Der Spark-Treiber ist für die Erstellung der SparkSession verantwortlich. Das SparkSession-Objekt repräsentiert eine Verbindung zu einem Spark-Cluster. Die SparkSession wird zu Beginn einer Spark-Anwendung einschließlich der interaktiven Shells instanziiert und für das gesamte Programm verwendet.

Vor Spark 2.0 enthielten die Einstiegspunkte für Spark-Anwendungen den SparkContext, der für Spark-Kernanwendungen verwendet wurde. der SQLContext und HiveContext, die mit Spark SQL-Anwendungen verwendet werden; und den StreamingContext, der für Spark-Streaming-Anwendungen verwendet wird. Das in Spark 2.0 eingeführte SparkSession-Objekt kombiniert alle diese Objekte zu einem einzigen Einstiegspunkt, der für alle Spark-Anwendungen verwendet werden kann.

Über seine untergeordneten SparkContext- und SparkConf-Objekte enthält das SparkSession-Objekt alle vom Benutzer festgelegten Laufzeitkonfigurationseigenschaften, einschließlich Konfigurationseigenschaften wie Master, Anwendungsname und Anzahl der Ausführenden. Abbildung 2 zeigt das SparkSession-Objekt und einige seiner Konfigurationseigenschaften in einer pysparkShell.

Pearson Addison-Wesley

SparkSession-Name

Der Objektname für die SparkSession-Instanz ist beliebig. Standardmäßig wird die SparkSession-Instanziierung in den interaktiven Spark-Shells benannt spark. Aus Gründen der Konsistenz instanziieren Sie die SparkSession immer als spark; Der Name liegt jedoch im Ermessen des Entwicklers.

Der folgende Code zeigt, wie eine SparkSession in einer nicht interaktiven Spark-Anwendung erstellt wird, z. B. in einem mit spark-submit.

aus pyspark.sql importieren SparkSession

spark = SparkSession.builder \

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

  .appName ("Meine Spark-Anwendung") \

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

  .getOrCreate ()

numlines = spark.sparkContext.textFile ("Datei: /// opt / spark / licenses") \

  .Anzahl()

print ("Die Gesamtzahl der Zeilen beträgt" + str (numlines))

Anwendungsplanung

Eine der Hauptfunktionen des Treibers besteht darin, die Anwendung zu planen. Der Treiber übernimmt die Eingabe für die Anwendungsverarbeitung und plant die Ausführung des Programms. Der Treiber führt alle angeforderten Transformationen (Datenmanipulationsoperationen) und Aktionen (Anforderungen für die Ausgabe oder Aufforderungen zur Ausführung von Programmen) aus und erstellt einen gerichteten azyklischen Graphen (DAG) von Knoten, die jeweils einen Transformations- oder Rechenschritt darstellen.

Gerichteter azyklischer Graph (DAG)

Eine DAG ist ein mathematisches Konstrukt, das in der Informatik häufig zur Darstellung von Datenflüssen und ihren Abhängigkeiten verwendet wird. DAGs enthalten Eckpunkte (oder Knoten) und Kanten. Scheitelpunkte in einem Datenflusskontext sind Schritte im Prozessfluss. Kanten in einer DAG verbinden Scheitelpunkte in einer gerichteten Ausrichtung miteinander und so, dass es unmöglich ist, kreisförmige Referenzen zu haben.

Eine Spark-Anwendungs-DAG besteht aus Aufgaben und Phasen . Eine Aufgabe ist die kleinste Einheit planbarer Arbeit in einem Spark-Programm. Eine Phase besteht aus einer Reihe von Aufgaben, die zusammen ausgeführt werden können. Stufen sind voneinander abhängig; Mit anderen Worten, es gibt Bühnenabhängigkeiten .

In Bezug auf die Prozessplanung sind DAGs nicht nur für Spark gültig. Sie werden beispielsweise in anderen Big-Data-Ökosystemprojekten wie Tez, Drill und Presto für die Planung verwendet. DAGs sind für Spark von grundlegender Bedeutung, daher lohnt es sich, mit dem Konzept vertraut zu sein.

Anwendungs-Orchestrierung

Der Fahrer koordiniert auch den Ablauf der in der DAG definierten Stufen und Aufgaben. Zu den wichtigsten Treiberaktivitäten bei der Planung und Ausführung von Aufgaben gehören:

  • Verfolgen Sie die verfügbaren Ressourcen, um Aufgaben auszuführen.
  • Planen Sie Aufgaben so, dass sie möglichst nahe an den Daten ausgeführt werden (das Konzept der Datenlokalität).

Andere Funktionen

Neben der Planung und Orchestrierung der Ausführung eines Spark-Programms ist der Treiber auch für die Rückgabe der Ergebnisse aus einer Anwendung verantwortlich. Dies können Rückkehrcodes oder Daten im Fall einer Aktion sein, bei der die Rückgabe von Daten an den Client angefordert wird (z. B. eine interaktive Abfrage).

Der Treiber bedient auch die Benutzeroberfläche der Anwendung an Port 4040, wie in Abbildung 3 dargestellt. Diese Benutzeroberfläche wird automatisch erstellt. Es ist unabhängig von dem eingereichten Code oder der Art und Weise, wie er übermittelt wurde ( pyspark dh interaktiv oder nicht interaktiv spark-submit).

Pearson Addison-Wesley

Wenn nachfolgende Anwendungen auf demselben Host gestartet werden, werden aufeinanderfolgende Ports für die Anwendungsbenutzeroberfläche verwendet (z. B. 4041, 4042 usw.).

Funkenarbeiter und Vollstrecker

Spark-Executoren sind die Prozesse, auf denen Spark-DAG-Tasks ausgeführt werden. Executoren reservieren CPU- und Speicherressourcen auf Slave-Knoten oder Workern in einem Spark-Cluster. Ein Executor ist einer bestimmten Spark-Anwendung zugeordnet und wird nach Abschluss der Anwendung beendet. Ein Spark-Programm besteht normalerweise aus vielen Executoren, die häufig parallel arbeiten.

In der Regel wird einem Worker-Knoten, der den Executor-Prozess hostet, zu jedem Zeitpunkt eine begrenzte oder feste Anzahl von Executoren zugewiesen. Daher steht einem Cluster - einer bekannten Anzahl von Knoten - eine begrenzte Anzahl von Executoren zur Verfügung, die zu einem bestimmten Zeitpunkt ausgeführt werden können. Wenn für eine Anwendung Executoren erforderlich sind, die die physische Kapazität des Clusters überschreiten, sollen sie gestartet werden, sobald andere Executoren ihre Ressourcen vervollständigen und freigeben.

Wie bereits erwähnt, hosten JVMs Spark-Executoren. Der JVM für einen Executor wird ein Heap zugewiesen , der ein dedizierter Speicherplatz zum Speichern und Verwalten von Objekten ist.

Die Größe des Speichers auf die Halde JVM begangen für einen Exekutor wird durch die Eigenschaft spark.executor.memoryoder als --executor-memoryArgument an die pyspark, spark-shelloder spark-submitBefehle.

Ausführende speichern Ausgabedaten von Aufgaben im Speicher oder auf der Festplatte. Es ist wichtig zu beachten, dass Mitarbeiter und Ausführende nur die ihnen zugewiesenen Aufgaben kennen, während der Fahrer dafür verantwortlich ist, den gesamten Satz von Aufgaben und die jeweiligen Abhängigkeiten zu verstehen, aus denen eine Anwendung besteht.

Mithilfe der Benutzeroberfläche der Spark-Anwendung an Port 404 x des Treiberhosts können Sie die Ausführenden auf die Anwendung untersuchen (siehe Abbildung 4).

Pearson Addison-Wesley

Bei eigenständigen Spark-Clusterbereitstellungen stellt ein Arbeitsknoten eine Benutzeroberfläche an Port 8081 bereit, wie in Abbildung 5 dargestellt.

Pearson Addison-Wesley

Der Spark-Master und Cluster-Manager

Der Spark-Treiber plant und koordiniert die Aufgaben, die zum Ausführen einer Spark-Anwendung erforderlich sind. Die Aufgaben selbst werden in Executoren ausgeführt, die auf Worker-Knoten gehostet werden.

Der Master und der Cluster-Manager sind die zentralen Prozesse, die die verteilten Cluster-Ressourcen (oder Container im Fall von YARN oder Mesos) überwachen, reservieren und zuweisen, auf denen die Executoren ausgeführt werden. Der Master und der Cluster-Manager können separate Prozesse sein oder zu einem Prozess kombiniert werden, wie dies beim Ausführen von Spark im Standalone-Modus der Fall ist.

Funkenmeister

Der Spark-Master ist der Prozess, der Ressourcen im Cluster anfordert und dem Spark-Treiber zur Verfügung stellt. In allen Bereitstellungsmodi handelt der Master Ressourcen oder Container mit Worker-Knoten oder Slave-Knoten aus, verfolgt deren Status und überwacht deren Fortschritt.

Wenn Spark im Standalone-Modus ausgeführt wird, bedient der Spark-Masterprozess eine Web-Benutzeroberfläche an Port 8080 auf dem Master-Host (siehe Abbildung 6).

Pearson Addison-Wesley

Spark Master versus Spark Treiber

Es ist wichtig, die Laufzeitfunktionen des Treibers und des Masters zu unterscheiden. Aus dem Namensmaster kann abgeleitet werden, dass dieser Prozess die Ausführung der Anwendung regelt - dies ist jedoch nicht der Fall. Der Master fordert einfach Ressourcen an und stellt diese Ressourcen dem Treiber zur Verfügung. Obwohl der Master den Status und den Zustand dieser Ressourcen überwacht, ist er nicht an der Ausführung der Anwendung und der Koordination ihrer Aufgaben und Phasen beteiligt. Das ist die Aufgabe des Fahrers.

Cluster-Manager

Der Cluster-Manager ist der Prozess, der auf Anfrage des Masters für die Überwachung der Arbeitsknoten und die Reservierung von Ressourcen auf diesen Knoten verantwortlich ist. Der Master stellt dem Treiber diese Clusterressourcen dann in Form von Executoren zur Verfügung.

Wie bereits erwähnt, kann der Cluster-Manager vom Master-Prozess getrennt sein. Dies ist der Fall, wenn Spark unter Mesos oder YARN ausgeführt wird. Wenn Spark im Standalone-Modus ausgeführt wird, führt der Master-Prozess auch die Funktionen des Cluster-Managers aus. Tatsächlich fungiert es als eigener Cluster-Manager.

Ein gutes Beispiel für die Cluster-Manager-Funktion ist der YARN ResourceManager-Prozess für Spark-Anwendungen, die auf Hadoop-Clustern ausgeführt werden. Der ResourceManager plant, ordnet und überwacht den Zustand von Containern, die auf YARN NodeManagers ausgeführt werden. Spark-Anwendungen verwenden diese Container dann zum Hosten von Executor-Prozessen sowie des Master-Prozesses, wenn die Anwendung im Cluster-Modus ausgeführt wird.

Spark-Anwendungen mit dem Standalone-Scheduler

In Kapitel 2, „Bereitstellen von Spark“, habe ich den eigenständigen Scheduler als Bereitstellungsoption für Spark erläutert. Dort habe ich in einer der Übungen in Kapitel 2 einen voll funktionsfähigen Standalone-Cluster mit mehreren Knoten bereitgestellt. Wie bereits erwähnt, führt der Spark-Master-Prozess in einem Spark-Cluster, der im Standalone-Modus ausgeführt wird, auch die Cluster-Manager-Funktion aus und regelt die verfügbaren Ressourcen auf dem Cluster und Gewährung an den Master-Prozess zur Verwendung in einer Spark-Anwendung.

Spark-Anwendungen, die auf YARN ausgeführt werden

Hadoop ist eine sehr beliebte und verbreitete Bereitstellungsplattform für Spark. Einige Branchenexperten glauben, dass Spark MapReduce bald als primäre Verarbeitungsplattform für Anwendungen in Hadoop ersetzen wird. Spark-Anwendungen auf YARN haben dieselbe Laufzeitarchitektur, weisen jedoch geringfügige Unterschiede in der Implementierung auf.

ResourceManager als Cluster-Manager

Im Gegensatz zum Standalone-Scheduler ist der Cluster-Manager in einem YARN-Cluster der YARN ResourceManager. Der ResourceManager überwacht die Ressourcennutzung und -verfügbarkeit auf allen Knoten in einem Cluster. Clients senden Spark-Anwendungen an den YARN ResourceManager. Der ResourceManager weist der Anwendung den ersten Container zu, einen speziellen Container namens ApplicationMaster.

ApplicationMaster als Spark-Master

Der ApplicationMaster ist der Spark-Master-Prozess. Wie der Master-Prozess in anderen Cluster-Bereitstellungen handelt der ApplicationMaster Ressourcen zwischen dem Anwendungstreiber und dem Cluster-Manager (oder in diesem Fall ResourceManager) aus. Anschließend werden diese Ressourcen (Container) dem Treiber zur Verwendung als Ausführende zum Ausführen von Aufgaben und Speichern von Daten für die Anwendung zur Verfügung gestellt.

Der ApplicationMaster bleibt für die Lebensdauer der Anwendung erhalten.

Bereitstellungsmodi für Spark-Anwendungen, die auf YARN ausgeführt werden

Beim Senden von Spark-Anwendungen an einen YARN-Cluster können zwei Bereitstellungsmodi verwendet werden: Client-Modus und Cluster-Modus. Schauen wir sie uns jetzt an.

Client-Modus

Im Client-Modus wird der Treiberprozess auf dem Client ausgeführt, der die Anwendung sendet. Es ist im Wesentlichen nicht verwaltet; Wenn der Treiberhost ausfällt, schlägt die Anwendung fehl. Client - Modus wird für beiden interaktiven Shell - Sitzungen unterstützt ( pyspark, spark-shell, usw.) und nicht - interaktive Anwendung Vorlage ( spark-submit). Der folgende Code zeigt, wie Sie eine pysparkSitzung im Clientbereitstellungsmodus starten .

$ SPARK_HOME / bin / pyspark \

--master Garn-Client \

--num-executors 1 \

--Treiberspeicher 512m \

--executor-memory 512m \

--Ausführerkerne 1

# ODER

$ SPARK_HOME / bin / pyspark \

- Meistergarn \

--deploy-mode client \

--num-executors 1 \

--Treiberspeicher 512m \

--executor-memory 512m \

--Ausführerkerne 1

Abbildung 7 bietet einen Überblick über eine Spark-Anwendung, die auf YARN im Client-Modus ausgeführt wird.

Pearson Addison-Wesley

Die in Abbildung 7 gezeigten Schritte sind:

  1. Der Client sendet eine Spark-Anwendung an den Cluster-Manager (den YARN ResourceManager). Der Treiberprozess, SparkSession und SparkContext werden erstellt und auf dem Client ausgeführt.
  2. Der ResourceManager weist der Anwendung einen ApplicationMaster (den Spark-Master) zu.
  3. Der ApplicationMaster fordert vom ResourceManager an, Container für Ausführende zu verwenden. Mit den zugewiesenen Containern erscheinen die Executoren.
  4. Der auf dem Client befindliche Treiber kommuniziert dann mit den Ausführenden, um die Verarbeitung von Aufgaben und Phasen des Spark-Programms zu verwalten. Der Treiber gibt den Fortschritt, die Ergebnisse und den Status an den Client zurück.

Der Client-Bereitstellungsmodus ist der am einfachsten zu verwendende Modus. Es fehlt jedoch die für die meisten Produktionsanwendungen erforderliche Ausfallsicherheit.

Cluster-Modus

Im Gegensatz zum Client-Bereitstellungsmodus wird bei einer Spark-Anwendung, die im YARN-Cluster-Modus ausgeführt wird, der Treiber selbst im Cluster als Unterprozess des ApplicationMaster ausgeführt. Dies bietet Ausfallsicherheit: Wenn der ApplicationMaster-Prozess, der den Treiber hostet, fehlschlägt, kann er auf einem anderen Knoten im Cluster erneut instanziiert werden.

Der folgende Code zeigt, wie Sie eine Anwendung mithilfe spark-submitdes YARN-Cluster-Bereitstellungsmodus senden. Da der Treiber ein asynchroner Prozess ist, der im Cluster ausgeführt wird, wird der Clustermodus für die interaktiven Shell-Anwendungen ( pysparkund spark-shell) nicht unterstützt .

$ SPARK_HOME / bin / spark-submit \

- Master Garn-Cluster \

--num-executors 1 \

--Treiberspeicher 512m \

--executor-memory 512m \

--Ausführerkerne 1

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

# ODER

- Meistergarn \

--deploy-mode cluster \

--num-executors 1 \

--Treiberspeicher 512m \

--executor-memory 512m \

--Ausführerkerne 1

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

Abbildung 8 bietet einen Überblick über eine Spark-Anwendung, die auf YARN im Cluster-Modus ausgeführt wird.

Pearson Addison-Wesley

Die in Abbildung 8 gezeigten Schritte sind:

  1. Der Client, ein Benutzerprozess, der aufruft spark-submit, sendet eine Spark-Anwendung an den Cluster-Manager (den YARN ResourceManager).
  2. Der ResourceManager weist der Anwendung einen ApplicationMaster (den Spark-Master) zu. Der Treiberprozess wird auf demselben Clusterknoten erstellt.
  3. Der ApplicationMaster fordert vom ResourceManager Container für Ausführende an. Executoren werden in den Containern erzeugt, die dem ApplicationMaster vom ResourceManager zugewiesen wurden. Der Fahrer kommuniziert dann mit den Ausführenden, um die Verarbeitung von Aufgaben und Phasen des Spark-Programms zu verwalten.
  4. Der Treiber, der auf einem Knoten im Cluster ausgeführt wird, gibt Fortschritt, Ergebnisse und Status an den Client zurück.

Die Web-Benutzeroberfläche der Spark-Anwendung ist, wie zuvor gezeigt, auf dem ApplicationMaster-Host im Cluster verfügbar. Ein Link zu dieser Benutzeroberfläche ist über die YARN ResourceManager-Benutzeroberfläche verfügbar.

Lokaler Modus überarbeitet

Im lokalen Modus werden der Treiber, der Master und der Executor in einer einzigen JVM ausgeführt. Wie bereits in diesem Kapitel erwähnt, ist dies nützlich für die Entwicklung, das Testen von Einheiten und das Debuggen. Es kann jedoch nur eingeschränkt zum Ausführen von Produktionsanwendungen verwendet werden, da es nicht verteilt und nicht skalierbar ist. Darüber hinaus werden fehlgeschlagene Aufgaben in einer Spark-Anwendung, die im lokalen Modus ausgeführt wird, standardmäßig nicht erneut ausgeführt. Sie können dieses Verhalten jedoch überschreiben.

Wenn Sie Spark im lokalen Modus ausführen, ist die Benutzeroberfläche der Anwendung unter // localhost: 4040 verfügbar. Die Master- und Worker-Benutzeroberflächen sind im lokalen Modus nicht verfügbar.