我正在尝试在spark网站上给出的火花结构化流媒体的例子,但它正在抛出错误
1。无法找到存储在数据集中的类型的编码器。导入spark.implicits支持原始类型(Int,String等)和产品类型(case类)。将来版本中将添加对序列化其他类型的支持。
2。没有足够的方法参数:(隐式证据$ 2:org.apache.spark.sql.Encoder [data])org.apache.spark.sql.Dataset [data]。 未指定的值参数证据$ 2。 val ds:数据集[数据] = df.as [数据]
这是我的代码
import org.apache.spark.sql._
import org.apache.spark.sql.functions._
import org.apache.spark.sql.types.StructType
import org.apache.spark.sql.types._
import org.apache.spark.sql.Encoders
object final_stream {
def main(args: Array[String]): Unit = {
val spark = SparkSession
.builder()
.appName("kafka-consumer")
.master("local[*]")
.getOrCreate()
import spark.implicits._
spark.sparkContext.setLogLevel("WARN")
case class data(name: String, id: String)
val df = spark
.readStream
.format("kafka")
.option("kafka.bootstrap.servers", "172.21.0.187:9093")
.option("subscribe", "test")
.load()
println(df.isStreaming)
val ds: Dataset[data] = df.as[data]
val value = ds.select("name").where("id > 10")
value.writeStream
.outputMode("append")
.format("console")
.start()
.awaitTermination()
}
}
如何使这项工作得到任何帮助。 我想要这样的最终输出 我想要这样的输出
+-----+--------+
| name| id
+-----+--------+
|Jacek| 1
+-----+--------+
答案 0 :(得分:1)
错误的原因是您正在处理来自Kafka的Array[Byte]
,并且没有字段可以匹配data
案例类。
scala> println(schema.treeString)
root
|-- key: binary (nullable = true)
|-- value: binary (nullable = true)
|-- topic: string (nullable = true)
|-- partition: integer (nullable = true)
|-- offset: long (nullable = true)
|-- timestamp: timestamp (nullable = true)
|-- timestampType: integer (nullable = true)
将行df.as[data]
更改为以下内容:
df.
select($"value" cast "string").
map(value => ...parse the value to get name and id here...).
as[data]
我强烈建议您使用select
和functions
对象来处理传入的数据。
答案 1 :(得分:0)
错误是由于数据框中的列数与您的案例类不匹配。
您在dataframe中有[topic, timestamp, value, key, offset, timestampType, partition]
列
而您的案例类只有两列
case class data(name: String, id: String)
您可以将数据框的内容显示为
val display = df.writeStream.format("console").start()
睡几秒钟然后
display.stop()
并使用option("startingOffsets", "earliest")
然后根据您的数据创建一个案例类。
希望这有帮助!