Les problèmes courants rencontrés lors de la création et du déploiement d'applications Spark sont les suivants:
Java.lang.ClassNotFoundException
.object x is not a member of package y
erreurs de compilation.Java.lang.NoSuchMethodError
Comment ceux-ci peuvent être résolus?
Lors de la création et du déploiement d'applications Spark, toutes les dépendances nécessitent des versions compatibles.
Version Scala . Tous les packages doivent utiliser la même version majeure de Scala (2.10, 2.11, 2.12).
Envisagez de suivre (incorrect) build.sbt
:
name := "Simple Project"
version := "1.0"
libraryDependencies ++= Seq(
"org.Apache.spark" % "spark-core_2.11" % "2.0.1",
"org.Apache.spark" % "spark-streaming_2.10" % "2.0.1",
"org.Apache.bahir" % "spark-streaming-Twitter_2.11" % "2.0.1"
)
Nous utilisons spark-streaming
pour Scala 2.10 tandis que les paquets restants sont pour Scala 2.11. Un valide fichier pourrait être
name := "Simple Project"
version := "1.0"
libraryDependencies ++= Seq(
"org.Apache.spark" % "spark-core_2.11" % "2.0.1",
"org.Apache.spark" % "spark-streaming_2.11" % "2.0.1",
"org.Apache.bahir" % "spark-streaming-Twitter_2.11" % "2.0.1"
)
mais il vaut mieux spécifier globalement la version et utiliser %%
:
name := "Simple Project"
version := "1.0"
scalaVersion := "2.11.7"
libraryDependencies ++= Seq(
"org.Apache.spark" %% "spark-core" % "2.0.1",
"org.Apache.spark" %% "spark-streaming" % "2.0.1",
"org.Apache.bahir" %% "spark-streaming-Twitter" % "2.0.1"
)
De même dans Maven:
<project>
<groupId>com.example</groupId>
<artifactId>simple-project</artifactId>
<modelVersion>4.0.0</modelVersion>
<name>Simple Project</name>
<packaging>jar</packaging>
<version>1.0</version>
<properties>
<spark.version>2.0.1</spark.version>
</properties>
<dependencies>
<dependency> <!-- Spark dependency -->
<groupId>org.Apache.spark</groupId>
<artifactId>spark-core_2.11</artifactId>
<version>${spark.version}</version>
</dependency>
<dependency>
<groupId>org.Apache.spark</groupId>
<artifactId>spark-streaming_2.11</artifactId>
<version>${spark.version}</version>
</dependency>
<dependency>
<groupId>org.Apache.bahir</groupId>
<artifactId>spark-streaming-Twitter_2.11</artifactId>
<version>${spark.version}</version>
</dependency>
</dependencies>
</project>
Version Spark Tous les packages doivent utiliser la même version majeure de Spark (1.6, 2.0, 2.1, ...).
Pensez à suivre build.sbt (incorrect):
name := "Simple Project"
version := "1.0"
libraryDependencies ++= Seq(
"org.Apache.spark" % "spark-core_2.11" % "1.6.1",
"org.Apache.spark" % "spark-streaming_2.10" % "2.0.1",
"org.Apache.bahir" % "spark-streaming-Twitter_2.11" % "2.0.1"
)
Nous utilisons spark-core
1.6 tandis que les composants restants sont dans Spark 2.0. Un valide fichier pourrait être
name := "Simple Project"
version := "1.0"
libraryDependencies ++= Seq(
"org.Apache.spark" % "spark-core_2.11" % "2.0.1",
"org.Apache.spark" % "spark-streaming_2.10" % "2.0.1",
"org.Apache.bahir" % "spark-streaming-Twitter_2.11" % "2.0.1"
)
mais il vaut mieux utiliser une variable:
name := "Simple Project"
version := "1.0"
val sparkVersion = "2.0.1"
libraryDependencies ++= Seq(
"org.Apache.spark" % "spark-core_2.11" % sparkVersion,
"org.Apache.spark" % "spark-streaming_2.10" % sparkVersion,
"org.Apache.bahir" % "spark-streaming-Twitter_2.11" % sparkVersion
)
De même dans Maven:
<project>
<groupId>com.example</groupId>
<artifactId>simple-project</artifactId>
<modelVersion>4.0.0</modelVersion>
<name>Simple Project</name>
<packaging>jar</packaging>
<version>1.0</version>
<properties>
<spark.version>2.0.1</spark.version>
<scala.version>2.11</scala.version>
</properties>
<dependencies>
<dependency> <!-- Spark dependency -->
<groupId>org.Apache.spark</groupId>
<artifactId>spark-core_${scala.version}</artifactId>
<version>${spark.version}</version>
</dependency>
<dependency>
<groupId>org.Apache.spark</groupId>
<artifactId>spark-streaming_${scala.version}</artifactId>
<version>${spark.version}</version>
</dependency>
<dependency>
<groupId>org.Apache.bahir</groupId>
<artifactId>spark-streaming-Twitter_${scala.version}</artifactId>
<version>${spark.version}</version>
</dependency>
</dependencies>
</project>
La version de Spark utilisée dans les dépendances de Spark doit correspondre à la version de Spark de l'installation de Spark. Par exemple, si vous utilisez 1.6.1 sur le cluster, vous devez utiliser 1.6.1 pour créer des fichiers JAR. Les versions mineures ne sont pas toujours acceptées.
La version de Scala utilisée pour construire jar doit correspondre à la version de Scala utilisée pour générer Spark déployé. Par défaut (fichiers binaires téléchargeables et versions par défaut):
Des packages supplémentaires doivent être accessibles sur les nœuds de travail s'ils sont inclus dans le fichier Fat jar. Il existe plusieurs options, notamment:
--jars
argument pour spark-submit
- pour distribuer les fichiers jar
locaux.--packages
argument pour spark-submit
- pour extraire les dépendances du référentiel Maven.Lors de la soumission dans le nœud du cluster, vous devez inclure application jar
dans --jars
.
En plus de la réponse très détaillée déjà fournie par l'utilisateur7337271, si le problème résulte de l'absence de dépendances externes, vous pouvez créer un fichier jar avec vos dépendances, par exemple avec. plugin maven Assembly
Dans ce cas, veillez à marquer toutes les dépendances d'étincelles principales comme "fournies" dans votre système de génération et, comme indiqué plus haut, assurez-vous qu'elles sont en corrélation avec votre version d'étincelle d'exécution.
Les classes de dépendance de votre application doivent être spécifiées dans l'option application-jar de votre commande de lancement.
Plus de détails peuvent être trouvés à la Documentation Spark
Tiré de la documentation:
application-jar: chemin d'accès à un fichier jar groupé comprenant votre application et toutes les dépendances. L'URL doit être globalement visible à l'intérieur de votre cluster, par exemple, un chemin hdfs: // ou un fichier: // chemin qui est présent sur tous les nœuds
Ajoutez tous les fichiers jar de spark-2.4.0-bin-hadoop2.7\spark-2.4.0-bin-hadoop2.7\jars du projet. Spark-2.4.0-bin-hadoop2.7 peut être téléchargé à partir de https://spark.Apache.org/downloads.html
J'ai le build.sbt suivant
lazy val root = (project in file(".")).
settings(
name := "spark-samples",
version := "1.0",
scalaVersion := "2.11.12",
mainClass in Compile := Some("StreamingExample")
)
libraryDependencies ++= Seq(
"org.Apache.spark" %% "spark-core" % "2.4.0",
"org.Apache.spark" %% "spark-streaming" % "2.4.0",
"org.Apache.spark" %% "spark-sql" % "2.4.0",
"com.couchbase.client" %% "spark-connector" % "2.2.0"
)
// META-INF discarding
assemblyMergeStrategy in Assembly := {
case PathList("META-INF", xs @ _*) => MergeStrategy.discard
case x => MergeStrategy.first
}
J'ai créé un gros fichier de mon application à l'aide du plugin sbt Assembly, mais lors de l'exécution de spark-submit, il échoue avec l'erreur suivante:
Java.lang.NoClassDefFoundError: rx/Completable$OnSubscribe
at com.couchbase.spark.connection.CouchbaseConnection.streamClient(CouchbaseConnection.scala:154)
Je peux voir que la classe existe dans mon gros pot:
jar tf target/scala-2.11/spark-samples-Assembly-1.0.jar | grep 'Completable$OnSubscribe'
rx/Completable$OnSubscribe.class
pas sûr de ce que je manque ici, des indices?
Je pense que ce problème doit résoudre un plugin Assembly. Vous devez construire un gros pot. Par exemple en sbt:
$PROJECT_ROOT/project/Assembly.sbt
avec le code addSbtPlugin("com.eed3si9n" % "sbt-Assembly" % "0.14.0")
added some libraries
libraryDependencies ++ = Seq ("com.some.company" %% "une-lib"% "1.0.0") ` Si vous avez besoin de plus d’informations, allez sur https://github.com/sbt/sbt-Assembly