Почему приложение Spark терпит неудачу с "ClassNotFoundException: не удалось найти источник данных: kafka" как uber-jar с сборкой sbt?
Я пытаюсь запустить образец, как https://github.com/apache/spark/blob/master/examples/src/main/scala/org/apache/spark/examples/sql/streaming/StructuredKafkaWordCount.scala - ... Я начал с Spark Structured Streaming Programming guide в http://spark.apache.org/docs/latest/structured-streaming-programming-guide.html.
мой код
package io.boontadata.spark.job1
import org.apache.spark.sql.SparkSession
object DirectKafkaAggregateEvents {
val FIELD_MESSAGE_ID = 0
val FIELD_DEVICE_ID = 1
val FIELD_TIMESTAMP = 2
val FIELD_CATEGORY = 3
val FIELD_MEASURE1 = 4
val FIELD_MEASURE2 = 5
def main(args: Array[String]) {
if (args.length < 3) {
System.err.println(s"""
|Usage: DirectKafkaAggregateEvents <brokers> <subscribeType> <topics>
| <brokers> is a list of one or more Kafka brokers
| <subscribeType> sample value: subscribe
| <topics> is a list of one or more kafka topics to consume from
|
""".stripMargin)
System.exit(1)
}
val Array(bootstrapServers, subscribeType, topics) = args
val spark = SparkSession
.builder
.appName("boontadata-spark-job1")
.getOrCreate()
import spark.implicits._
// Create DataSet representing the stream of input lines from kafka
val lines = spark
.readStream
.format("kafka")
.option("kafka.bootstrap.servers", bootstrapServers)
.option(subscribeType, topics)
.load()
.selectExpr("CAST(value AS STRING)")
.as[String]
// Generate running word count
val wordCounts = lines.flatMap(_.split(" ")).groupBy("value").count()
// Start running the query that prints the running counts to the console
val query = wordCounts.writeStream
.outputMode("complete")
.format("console")
.start()
query.awaitTermination()
}
}
я добавил следующие файлы sbt:
построить.sbt:
name := "boontadata-spark-job1"
version := "0.1"
scalaVersion := "2.11.7"
libraryDependencies += "org.apache.spark" % "spark-core_2.11" % "2.0.2" % "provided"
libraryDependencies += "org.apache.spark" % "spark-streaming_2.11" % "2.0.2" % "provided"
libraryDependencies += "org.apache.spark" % "spark-sql_2.11" % "2.0.2" % "provided"
libraryDependencies += "org.apache.spark" % "spark-sql-kafka-0-10_2.11" % "2.0.2"
libraryDependencies += "org.apache.spark" % "spark-streaming-kafka-0-10_2.11" % "2.0.2"
libraryDependencies += "org.apache.kafka" % "kafka-clients" % "0.10.1.1"
libraryDependencies += "org.apache.kafka" % "kafka_2.11" % "0.10.1.1"
// META-INF discarding
assemblyMergeStrategy in assembly := {
{
case PathList("META-INF", xs @ _*) => MergeStrategy.discard
case x => MergeStrategy.first
}
}
Я также добавил проект/сборка.sbt
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.3")
это создает банку Uber с non provided
банок.
Я представляю со следующей строкой:
spark-submit boontadata-spark-job1-assembly-0.1.jar ks1:9092,ks2:9092,ks3:9092 subscribe sampletopic
но я получаю эту ошибку во время выполнения:
Exception in thread "main" java.lang.ClassNotFoundException: Failed to find data source: kafka. Please find packages at https://cwiki.apache.org/confluence/display/SPARK/Third+Party+Projects
at org.apache.spark.sql.execution.datasources.DataSource.lookupDataSource(DataSource.scala:148)
at org.apache.spark.sql.execution.datasources.DataSource.providingClass$lzycompute(DataSource.scala:79)
at org.apache.spark.sql.execution.datasources.DataSource.providingClass(DataSource.scala:79)
at org.apache.spark.sql.execution.datasources.DataSource.sourceSchema(DataSource.scala:218)
at org.apache.spark.sql.execution.datasources.DataSource.sourceInfo$lzycompute(DataSource.scala:80)
at org.apache.spark.sql.execution.datasources.DataSource.sourceInfo(DataSource.scala:80)
at org.apache.spark.sql.execution.streaming.StreamingRelation$.apply(StreamingRelation.scala:30)
at org.apache.spark.sql.streaming.DataStreamReader.load(DataStreamReader.scala:124)
at io.boontadata.spark.job1.DirectKafkaAggregateEvents$.main(StreamingJob.scala:41)
at io.boontadata.spark.job1.DirectKafkaAggregateEvents.main(StreamingJob.scala)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.spark.deploy.SparkSubmit$.org$apache$spark$deploy$SparkSubmit$$runMain(SparkSubmit.scala:736)
at org.apache.spark.deploy.SparkSubmit$.doRunMain(SparkSubmit.scala:185)
at org.apache.spark.deploy.SparkSubmit$.submit(SparkSubmit.scala:210)
at org.apache.spark.deploy.SparkSubmit$.main(SparkSubmit.scala:124)
at org.apache.spark.deploy.SparkSubmit.main(SparkSubmit.scala)
Caused by: java.lang.ClassNotFoundException: kafka.DefaultSource
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at org.apache.spark.sql.execution.datasources.DataSource$$anonfun$$anonfun$apply.apply(DataSource.scala:132)
at org.apache.spark.sql.execution.datasources.DataSource$$anonfun$$anonfun$apply.apply(DataSource.scala:132)
at scala.util.Try$.apply(Try.scala:192)
at org.apache.spark.sql.execution.datasources.DataSource$$anonfun.apply(DataSource.scala:132)
at org.apache.spark.sql.execution.datasources.DataSource$$anonfun.apply(DataSource.scala:132)
at scala.util.Try.orElse(Try.scala:84)
at org.apache.spark.sql.execution.datasources.DataSource.lookupDataSource(DataSource.scala:132)
... 18 more
16/12/23 13:32:48 INFO spark.SparkContext: Invoking stop() from shutdown hook
есть ли способ узнать, какой класс не найден, чтобы я мог искать maven.org РЕПО для этого класса.
на lookupDataSource
исходный код, похоже, на линии 543 на https://github.com/apache/spark/blob/83a6ace0d1be44f70e768348ae6688798c84343e/sql/core/src/main/scala/org/apache/spark/sql/execution/datasources/DataSource.scala но я не смог найти прямую связь с источником данных Кафки...
полный исходный код здесь: https://github.com/boontadata/boontadata-streams/tree/ad0d0134ddb7664d359c8dca40f1d16ddd94053f
6 ответов
я попробовал, как это работает для меня. Отправить, как это и дайте мне знать, как только у вас есть какие-либо вопросы
./spark-submit --packages org.apache.spark:spark-sql-kafka-0-10_2.11:2.1.0 --class com.inndata.StructuredStreaming.Kafka --master local[*] /Users/apple/.m2/repository/com/inndata/StructuredStreaming/0.0.1SNAPSHOT/StructuredStreaming-0.0.1-SNAPSHOT.jar
проблема заключается в следующем разделе в build.sbt
:
// META-INF discarding
assemblyMergeStrategy in assembly := {
{
case PathList("META-INF", xs @ _*) => MergeStrategy.discard
case x => MergeStrategy.first
}
}
там написано, что все META-INF
entires следует отбросить, включая "код", который делает псевдонимы источников данных (например,kafka
) работы.
но META-INF
файлы очень важны для kafka
(и другие псевдонимы источников потоковых данных) для работы.
на kafka
псевдоним для работы Spark SQL использует META-INF / services / org.апаш.искра.язык SQL.источники.DataSourceRegister С следующая запись:
org.apache.spark.sql.kafka010.KafkaSourceProvider
KafkaSourceProvider
отвечает за регистрацию kafka
псевдоним с соответствующим источником потоковых данных, т. е. KafkaSource.
просто чтобы проверить, что реальный код действительно доступен, но "код", который делает зарегистрированный псевдоним, нет, вы можете использовать kafka
источник данных по полному имени (не псевдоним) следующим образом:
spark.readStream.
format("org.apache.spark.sql.kafka010.KafkaSourceProvider").
load
вы увидите другие проблемы, из-за отсутствия вариантов как kafka.bootstrap.servers
, но...мы отвлеклись.
раствор для MergeStrategy.concat
все META-INF/services/org.apache.spark.sql.sources.DataSourceRegister
(это создаст uber-jar со всеми источниками данных, включая. the kafka
источник данных).
case "META-INF/services/org.apache.spark.sql.sources.DataSourceRegister" => MergeStrategy.concat
в моем случае я также получил эту ошибку при компиляции с sbt, и причиной было то, что sbt assembly
не включал spark-sql-kafka-0-10_2.11
артефакт, как часть сала банке.
(Я был бы очень рад комментариям здесь. В зависимости не была указана область, поэтому ее не следует считать "предоставленной").
поэтому я перешел к развертыванию нормальной (тонкой) банки и включению зависимостей с --jars
параметры для spark-submit.
для того, чтобы собрать все зависимости в одном месте, вы можете добавить retrieveManaged := true
к настройкам проекта sbt, или вы можете, в консоли sbt, выдать:
> set retrieveManaged := true
> package
это должно привести все зависимости к .
затем вы можете скопировать все эти файлы (с помощью команды bash, вы можете например использовать что-то вроде этого
cd /path/to/your/project
JARLIST=$(find lib_managed -name '*.jar'| paste -sd , -)
spark-submit [other-args] target/your-app-1.0-SNAPSHOT.jar --jars "$JARLIST"
Я решил это, загрузив файл jar в систему драйверов. Оттуда я поставил банку для spark submit с опцией --jar.
также следует отметить, что я упаковывал всю среду spark 2.1 в свою банку uber (так как мой кластер все еще находится на 1.6.1) по какой-то причине, его не подобрали при включении в банку uber.
spark-submit --jar / ur / path / spark-sql-kafka-0-10_2.11: 2.1.0 --class ClassNm --Другие-Варианты YourJar.Джар
Я использую spark 2.1 и сталкиваюсь с той же проблемой мой обходной путь
1) spark-shell --packages org.apache.spark:spark-sql-kafka-0-10_2.11:2.1.0
2) cd ~/.ivy2/jars
вот вы, все необходимые банки находятся в этой папке сейчас
3) скопируйте все банки в этой папке на все узлы (можно создать определенную папку, содержащую их)
4) Добавьте имя папки в spark.driver.extraClassPath
и spark.driver.extraClassPath
,например,spark.driver.extraClassPath=/opt/jars/*:your_other_jars
5 spark-submit --class ClassNm --Other-Options YourJar.jar
отлично работает сейчас
это ввиду ответа Яцека Ласковского.
те из вас, кто строит свой проект на maven, могут попробовать это. Добавьте строку, указанную ниже, в свой Maven-shade-plugin.
META-INF / services / org.апаш.искра.язык SQL.источники.DataSourceRegister
Я положил код плагина для файла pom в качестве примера, чтобы показать, где добавить строку.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>
META-INF/services/org.apache.spark.sql.sources.DataSourceRegister
</resource>
</transformer>
</transformers>
<finalName>${project.artifactId}-${project.version}-uber</finalName>
</configuration>
</execution>
</executions>
</plugin>
пожалуйста, извините мои навыки форматирования.