Optimieren Ihres Spark-Clusters mit interaktiven Spark-Aufträgen

In diesem Artikel erfahren Sie:
- So verkürzen Sie die Ausführungszeit für Spark-Jobs
- Was ist ein interaktiver Job in Ilum?
- Ausführen eines interaktiven Spark-Auftrags
- Unterschiede zwischen der Ausführung eines Spark-Jobs mit der Ilum API und der Spark API
Ilum-Jobtypen
Es gibt drei Arten von Jobs, die Sie in Ilum ausführen können: Einzelauftrag , Interaktiver Job und Interaktiver Code . In diesem Artikel konzentrieren wir uns auf die Interaktiver Job Art. Es ist jedoch wichtig, die Unterschiede zwischen den drei Arten von Jobs zu kennen, also lassen Sie uns einen kurzen Überblick über jeden einzelnen geben.
Mit Einzelne Aufträge können Sie codeähnliche Programme einreichen. Sie ermöglichen es Ihnen, eine Spark-Anwendung mit vorkompiliertem Code ohne Interaktion während der Laufzeit an den Cluster zu übermitteln. In diesem Modus müssen Sie eine kompilierte JAR-Datei an Ilum senden, die zum Starten eines einzelnen Jobs verwendet wird. Sie können es entweder direkt senden oder AWS-Anmeldeinformationen verwenden, um es von einem S3-Bucket abzurufen. Ein typisches Beispiel für die Verwendung eines einzelnen Auftrags wäre eine Art Datenaufbereitungsaufgabe.
Ilum bietet auch eine interaktiv Code-Modus , mit der Sie Befehle zur Laufzeit übergeben können. Dies ist nützlich für Aufgaben, bei denen Sie mit den Daten interagieren müssen, z. B. bei der explorativen Datenanalyse.
Interaktiver Job
Interaktive Aufträge verfügen über Sitzungen mit langer Ausführungszeit, in denen Sie Auftragsinstanzdaten senden können, die sofort ausgeführt werden sollen. Das Killer-Feature eines solchen Modus ist, dass Sie nicht warten müssen, bis der Funkenkontext initialisiert ist. Wenn Benutzer auf dieselbe Job-ID verweisen, interagieren sie mit demselben Spark-Kontext. Ilum verpackt die Spark-Anwendungslogik in einen lang laufenden Spark-Auftrag, der in der Lage ist, Berechnungsanforderungen sofort zu verarbeiten, ohne auf die Initialisierung des Spark-Kontexts warten zu müssen.

Starten eines interaktiven Auftrags
Werfen wir einen Blick darauf, wie die interaktive Sitzung von Ilum gestartet werden kann. Das erste, was wir tun müssen, ist, Ilum einzurichten. Mit dem minikube kannst du das ganz einfach machen. Ein Tutorial mit der Ilum-Installation finden Sie unter diesem verbinden . Im nächsten Schritt müssen wir eine JAR-Datei erstellen, die eine Implementierung der Job-Schnittstelle von Ilum enthält. Um die Ilum-Job-API zu verwenden, müssen wir sie dem Projekt mit einigen Abhängigkeitsmanagern wie Maven oder Gradle hinzufügen. In diesem Beispiel verwenden wir Scala-Code mit einem Gradle, um PI zu berechnen.
Das vollständige Beispiel finden Sie auf unserer GitHub (Englisch) .
Wenn Sie es vorziehen, es nicht selbst zu erstellen, können Sie die kompilierte JAR-Datei finden hier .
Der erste Schritt besteht darin, einen Ordner für unser Projekt zu erstellen und das Verzeichnis in diesen zu ändern.
$ mkdir interaktives-job-beispiel
$ cd interaktives-job-beispiel
Wenn Sie nicht die neueste Version von Gradle auf Ihrem Computer installiert haben, können Sie überprüfen, wie es geht hier . Führen Sie dann den folgenden Befehl in einem Terminal aus dem Projektverzeichnis aus:
$ gradle init
Wählen Sie eine Scala-Anwendung mit Groovy als DSL. Die Ausgabe sollte wie folgt aussehen:
Starten eines Gradle-Daemons (nachfolgende Builds werden schneller sein)
Wählen Sie den Typ des zu generierenden Projekts aus:
1: Grundlegend
2: Anwendung
3: Bibliothek
4: Gradle-Plugin
Auswahl eingeben (Standard: basic) [1..4] 2
Wählen Sie die Implementierungssprache aus:
1: C++
2: Groovy
3: Java
4: Kotlin
5: Scala
6: Schnell
Auswahl eingeben (Standard: Java) [1..6] 5
Funktionalität auf mehrere Teilprojekte aufteilen?:
1: Nein - nur ein Anwendungsprojekt
2: Ja - Anwendungs- und Bibliotheksprojekte
Auswahl eingeben (Standard: nein - nur ein Anwendungsprojekt) [1..2] 1
Wählen Sie die Buildskript-DSL aus:
1: Groovy
2: Kotlin
Auswahl eingeben (Standard: Groovy) [1..2] 1
Generieren Sie einen Build mit neuen APIs und neuem Verhalten (einige Funktionen können sich in der nächsten Nebenversion ändern)? (Standard: nein) [ja, nein] nein
Projektname (Standard: interactive-job-example):
Quellpaket (Standard: interactive.job.example):
> Aufgabe :init
Holen Sie sich weitere Hilfe für Ihr Projekt: https://docs.gradle.org/7.5.1/samples/sample_building_scala_applications_multi_project.html
ERFOLGREICH BAUEN in 30er Jahren
2 umsetzbare Aufgaben: 2 ausgeführt
Nun müssen wir das Ilum-Repository und die notwendigen Abhängigkeiten in Ihre bauen.gradle Datei. In diesem Tutorial werden wir Scala 2.12 verwenden.
Abhängigkeiten {
Implementierung 'org.scala-lang:scala-library:2.12.16'
Implementierung 'cloud.ilum:ilum-job-api:5.0.1'
compileOnly 'org.apache.spark:spark-sql_2.12:3.1.2'
}
Nun können wir eine Scala-Klasse erstellen, die Ilums Job erweitert und PI berechnet:
Paket interactive.job.example
importieren cloud.ilum.job.job
Importieren org.apache.spark.sql.SparkSession
Importieren Sie scala.math.random
class InteractiveJobExample extends Job {
override def run(sparkSession: SparkSession, config: Map[Zeichenfolge, beliebig]): Option[Zeichenfolge] = {
val slices = config.getOrElse("slices", "2").toString.toInt
val n = math.min(100000L * Scheiben, Int.MaxValue).toInt
val count = sparkSession.sparkContext.parallelize(1 until n, slices).map { i =>
val x = zufällig * 2 - 1
Wert y = zufällig * 2 - 1
if (x * x + y * y <= 1) 1 else 0
}.reduce(_ + _)
Some(s"Pi ist ungefähr ${4.0 * count / (n - 1)}")
}
}
Wenn Gradle einige Haupt- oder Testklassen generiert hat, entfernen Sie sie einfach aus dem Projekt, und erstellen Sie einen Build.
$ Gradle Build
Die generierte JAR-Datei sollte sich in ' ./interactive-job-example/app/build/libs/app.jar ", können wir dann wieder auf Ilum umschalten. Sobald alle Pods laufen, machen Sie bitte eine Portweiterleitung für ilum-ui:
kubectl port-forward svc/ilum-ui 9777:9777
Öffnen Sie die Ilum UI in Ihrem Browser und erstellen Sie eine neue Gruppe:

Geben Sie einen Namen für eine Gruppe ein, wählen Sie einen Cluster aus oder erstellen Sie einen Cluster, laden Sie Ihre JAR-Datei hoch und übernehmen Sie die Änderungen:

Ilum erstellt einen Spark-Treiber-Pod und Sie können die Anzahl der Spark-Executor-Pods steuern, indem Sie sie skalieren. Nachdem der Spark-Container fertig ist, führen wir die Aufträge aus:

Jetzt müssen wir den kanonischen Namen unserer Scala-Klasse eingeben
interactive.job.example.InteractiveJobExample
und definieren Sie den Parameter slices im JSON-Format:
{
"config": {
"Scheiben": "10"
}
}
Das Ergebnis sollte sofort nach dem Start des Auftrags angezeigt werden

Sie können Parameter ändern und einen Auftrag erneut ausführen, und Ihre Berechnungen werden sofort ausgeführt.
Interaktiver und Einzeljob-Vergleich
In Ilum können Sie auch einen einzelnen Job ausführen. Der wichtigste Unterschied zum interaktiven Modus besteht darin, dass Sie die Job-API nicht implementieren müssen. Wir können das SparkPi-Jar aus Spark-Beispielen verwenden:

Das Ausführen eines solchen Auftrags ist ebenfalls schnell, aber interaktive Aufträge sind 20-mal schneller (4s vs 200ms) . Wenn Sie einen ähnlichen Job mit anderen Parametern starten möchten, müssen Sie einen neuen Job vorbereiten und die JAR-Datei erneut hochladen.
Vergleich von Ilum und Apache Spark
Ich habe Apache Spark lokal mit einem bitnami/spark docker-Image verwenden. Wenn Sie Spark auch auf Ihrem Computer ausführen möchten, können Sie docker-compose verwenden:
$ curl -LO https://raw.githubusercontent.com/bitnami/containers/main/bitnami/spark/docker-compose.yml
$ docker-compose nach oben
Sobald Spark ausgeführt wird, sollten Sie in der Lage sein, zu localhost:8080 zu wechseln und die Admin-Benutzeroberfläche anzuzeigen. Wir müssen die Spark-URL aus dem Browser abrufen:
Dann müssen wir den Spark-Container im interaktiven Modus mit
$ docker exec -it <containerid> -- bash
Und jetzt können wir im Container den sparkPi-Job einreichen. In diesem Fall wird SparkiPi aus der Beispiel-JAR-Datei verwendet und als Master-Parameter die URL aus dem Browser eingefügt:
$ ./bin/spark-submit --class org.apache.spark.examples.SparkPi\
--master spark://78c84485d233:7077 \
/opt/bitnami/spark/beispiele/jars/spark-examples_2.12-3.3.0.jar\
10
Zusammenfassung
Wie Sie im obigen Beispiel sehen können, können Sie die komplizierte Konfiguration und Installation Ihres Spark-Clients durch den Einsatz von Ilum vermeiden. Ilum übernimmt die Arbeit und stellt Ihnen eine einfache und komfortable Oberfläche zur Verfügung. Darüber hinaus können Sie die Einschränkungen von Apache Spark überwinden, deren Initialisierung sehr lange dauern kann. Wenn Sie viele Jobausführungen mit ähnlicher Logik, aber unterschiedlichen Parametern durchführen müssen und Berechnungen sofort durchführen lassen möchten, sollten Sie unbedingt den interaktiven Job-Modus verwenden.

Ähnlichkeiten mit Apache Livy
Ilum ist ein Cloud-natives Tool zur Verwaltung von Apache Spark-Bereitstellungen auf Kubernetes. Es ähnelt Apache Livy in Bezug auf die Funktionalität - es kann eine Spark-Sitzung über die REST-API steuern und eine Echtzeit-Interaktion mit einem Spark-Cluster aufbauen. Ilum ist jedoch speziell für moderne, Cloud-native Umgebungen konzipiert.
Wir haben in der Vergangenheit Apache Livy verwendet, aber wir sind an einem Punkt angelangt, an dem Livy einfach nicht mehr für moderne Umgebungen geeignet war. Livius ist obsolet im Vergleich zu Ilum. Im Jahr 2018 haben wir damit begonnen, alle unsere Umgebungen auf Kubernetes umzustellen, und wir mussten einen Weg finden, Apache Spark auf Kubernetes bereitzustellen, zu überwachen und zu warten. Dies war die perfekte Gelegenheit, um Ilum zu bauen.