繁体   English   中英

Spark 2.0.2,Kafka源和scalapb实现结构化流

[英]structured streaming with Spark 2.0.2, Kafka source and scalapb

我正在使用结构化流(Spark 2.0.2)来使用kafka消息。 使用scalapb,protobuf中的消息。 我收到以下错误。 请帮忙..

线程“主”中的异常scala.ScalaReflectionException:在scala.reflect.internal.Symbols $ SymbolContextApiImpl.asTerm(Symbols.scal.reflect.api.Symbols $ SymbolApi $ class.asTerm(Symbols.scala:199)处不是术语。 scala:84)位于org.apache.spark.sql.catalyst.ScalaReflection $ class.constructParams(ScalaReflection.scala:811)位于org.apache.spark.sql.catalyst.ScalaReflection $ .constructParams(ScalaReflection.scala:39) org.apache.spark.sql.catalyst.ScalaReflection $ class.getConstructorParameters(ScalaReflection.scala:800)在org.apache.spark.sql.catalyst.ScalaReflection $ .getConstructorParameters(ScalaReflection.scala:39)在org.apache.spark .sql.catalyst.ScalaReflection $ .org $ apache $ spark $ sql $ catalyst $ ScalaReflection $$ serializerFor(ScalaReflection.scala:582)在org.apache.spark.sql.catalyst.ScalaReflection $ .org $ apache $ spark $ sql org.apache.spark.sql.catalyst.ScalaReflection $$ anonfun $ 9.apply(ScalaReflection.scala:592)上的$ catalyst $ ScalaReflection $$ serializerFor(ScalaReflection.scala:460)在org.ap上 ache.spark.sql.catalyst.ScalaReflection $$ anonfun $ 9.apply(ScalaReflection.scala:583)在scala.collection.TraversableLike $$ anonfun $ flatMap $ 1.apply(TraversableLike.scala:252)在scala.collection.TraversableLike $在scala处的$ anonfun $ flatMap $ 1.apply(TraversableLike.scala:252)在scala.collection.immutable.List.foreach(List.scala:381)在scala.collection.TraversableLike $ class.flatMap(TraversableLike.scala:252)在scala .collection.immutable.List.flatMap(List.scala:344)在org.apache.spark.sql.catalyst.ScalaReflection $ .org $ apache $ spark $ sql $ catalyst $ ScalaReflection $$ serializerFor(ScalaReflection.scala:583)在org.apache上的org.apache.spark.sql.catalyst.encoders.ExpressionEncoder $ .apply(ExpressionEncoder.scala:61)在org.apache.spark.sql.catalyst.ScalaReflection $ .serializerFor(ScalaReflection.scala:425)位于PersonConsumer的PersonConsumer $ .main(PersonConsumer.scala:33)的org.apache.spark.sql.SQLImplicits.newProductEncoder(SQLImplicits.scala:47)的.spark.sql.Encoders $ .product(Encoders.scala:274)。主要(PersonCon sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)处sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)处sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)处的本地方法.reflect.Method.invoke(Method.java:498)位于com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)

以下是我的代码...

object PersonConsumer {
  import org.apache.spark.rdd.RDD
  import com.trueaccord.scalapb.spark._
  import org.apache.spark.sql.{SQLContext, SparkSession}
  import com.example.protos.demo._

  def main(args : Array[String]) {

    def parseLine(s: String): Person =
      Person.parseFrom(
        org.apache.commons.codec.binary.Base64.decodeBase64(s))

    val spark = SparkSession.builder.
      master("local")
      .appName("spark session example")
      .getOrCreate()

    import spark.implicits._

    val ds1 = spark.readStream.format("kafka").option("kafka.bootstrap.servers","localhost:9092").option("subscribe","person").load()

    val ds2 = ds1.selectExpr("CAST(value AS STRING)").as[String]

    val ds3 = ds2.map(str => parseLine(str)).createOrReplaceTempView("persons")

    val ds4 = spark.sqlContext.sql("select name from persons")

    val query = ds4.writeStream
      .outputMode("append")
      .format("console")
      .start()
    query.awaitTermination()
  }
}

val ds3的行应为:

val ds3 = ds2.map(str => parseLine(str))

sqlContext.protoToDataFrame(ds3).registerTempTable("persons")

在将RDD保存为临时表之前,需要先将其转换为数据帧。

在“人”类中,性别是一个枚举,这是导致此问题的原因。 删除该字段后,它可以正常工作。 以下是我从DataBricks的Shixiong(Ryan)那里得到的答案。

问题是“可选性别= 3;”。 生成的类“性别”是一个特征,Spark无法知道如何创建特征,因此不受支持。 您可以定义SQL Encoder支持的类,并将此生成的类转换为parseLine的新类。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM