在scala spark流中使用foreach时不希望字符串作为类型?
代码段:在scala spark流中使用foreach时不希望字符串作为类型?,scala,utf-8,deserialization,spark-streaming,avro,Scala,Utf 8,Deserialization,Spark Streaming,Avro,代码段: val lines = KafkaUtils.createStream(ssc, zkQuorum, group, topicMap) val write2hdfs = lines.filter(x => x._1 == "lineitem").map(_._2) write2hdfs.foreachRDD(rdd => { rdd.foreach(avroRecord => { println(avroRecord) //val rawByte = avroRec
val lines = KafkaUtils.createStream(ssc, zkQuorum, group, topicMap)
val write2hdfs = lines.filter(x => x._1 == "lineitem").map(_._2)
write2hdfs.foreachRDD(rdd => {
rdd.foreach(avroRecord => {
println(avroRecord)
//val rawByte = avroRecord.getBytes("UTF-8")
面临的问题>
avroRecord保存从卡夫卡流接收的avro编码的消息。
默认情况下,当使用上述代码时,avroRecord是一个字符串。
字符串在scala中默认使用UTF-16编码
由于这种反序列化是不正确的,并且面临一些问题。
当发送到kafka流时,消息用utf-8编码到avro中
我需要avroRecord是纯字节,而不是作为字符串获取,然后转换为字节(内部字符串将进行utf-16编码)
或者一种在utf-8中获取avroRecord的方法。卡在这里,死路一条
需要一个解决此问题的方法
提前谢谢
更新:
代码片段已更改>
val ssc = new StreamingContext(sparkConf, Seconds(5))
//val ssc = new JavaStreamingContext(sparkConf, Seconds(5))
val topicMap = topics.split(",").map((_, numThreads.toInt)).toMap
val kafkaParams = Map[String, String]("zookeeper.connect" ->
zkQuorum,"group.id" -> group,"zookeeper.connection.timeout.ms" -> "10000")
//val lines = KafkaUtils.createStream(ssc, zkQuorum, group, topicMap)
val lines =
KafkaUtils.createStream[String,Message,StringDecoder,DefaultDecoder]
(ssc,kafkaParams,topics,StorageLevel.NONE)
已完成的导入:
import org.apache.spark.streaming._
import org.apache.spark.streaming.api.java.JavaStreamingContext
import org.apache.spark.streaming.kafka._
import org.apache.spark.SparkConf
import org.apache.spark.storage.StorageLevel
import org.apache.spark.streaming.dstream.DStream.toPairDStreamFunctions
import org.apache.avro
import org.apache.avro.Schema
import org.apache.avro.generic.{GenericDatumReader, GenericRecord,
GenericDatumWriter, GenericData}
import org.apache.avro.io.{DecoderFactory, DatumReader, DatumWriter,
BinaryDecoder}
import org.apache.avro.file.{DataFileReader, DataFileWriter}
import java.io.{File, IOException}
//import java.io.*
import org.apache.commons.io.IOUtils;
import _root_.kafka.serializer.{StringDecoder, DefaultDecoder}
import _root_.kafka.message.Message
import scala.reflect._
编译错误:
正在将1个Scala源代码编译到/home/spark\u Scala/spark\u stream\u project/target/Scala-2.10/classes。。。
[错误]/home/spark\u scala/spark\u stream\u project/src/main/scala/sparkStreaming.scala:34:重载的方法值createStream和可选项:
[错误](jssc:org.apache.spark.streaming.api.java.JavaStreamingContext,keyTypeClass:Class[String],valueTypeClass:Class[kafka.message.message],keyDecoderClass:Class[kafka.serializer.StringDecoder],valueDecoderClass:Class[kafka.serializer.DefaultDecoder],Kafkaaparams:java.util.Map[String,String],主题:java.util.Map[String,Integer],storageLevel:org.apache.spark.storage.storageLevel)org.apache.spark.streaming.api.java.javapairReceiverInputStream[String,kafka.message.message]
[错误](ssc:org.apache.spark.streaming.StreamingContext,kafkaParams:scala.collection.immutable.Map[String,String],主题:scala.collection.immutable.Map[String,Int],storageLevel:org.apache.spark.storage.storageLevel)(隐式证据$1:scala.reflect.ClassTag[String],隐式证据$2:scala.reflect.ClassTag[kafka.message.message],隐式证据$3:scala.reflect.ClassTag[kafka.serializer.StringDecoder],隐式证据$4:scala.reflect.ClassTag[kafka.serializer.DefaultDecoder])org.apache.spark.stream.dstream.ReceiverInputDStream[(String,kafka.message.message)]
[错误]无法应用于(org.apache.spark.streaming.StreamingContext,scala.collection.immutable.Map[String,String],String,org.apache.spark.storage.StorageLevel)
[错误]val lines=KafkaUtils.createStreamString、消息、StringDecoder、DefaultDecoder
[错误]^
[错误]发现一个错误
这里出了什么问题。
此外,我没有看到kafkaUtils API文档中定义的正确构造函数。
API文件参考am参考:
?
org/apache/spark/streaming/kafka/KafkaUtils.html
期待支持
谢谢
更新2:
尝试更正建议
代码片段>
val lines =
KafkaUtils.createStream[String,Message,StringDecoder,DefaultDecoder]
(ssc,kafkaParams,topicMap,StorageLevel.MEMORY_AND_DISK_2)
val write2hdfs = lines.filter(x => x._1 == "lineitem").map(_._2)
面临运行时异常>
java.lang.ClassCastException: [B cannot be cast to kafka.message.Message
On line :
KafkaUtils.createStream[String,Message,StringDecoder,DefaultDecoder]
(ssc,kafkaParams,topicMap,StorageLevel.MEMORY_AND_DISK_2)
val write2hdfs = lines.filter(x => x._1 == "lineitem").map(_._2)
理想情况下,过滤此数据流(字符串、消息)也应该正常工作?
在进行映射之前,是否需要从消息中提取有效负载
需要输入。
谢谢您可以这样做:
import kafka.serializer.{StringDecoder, DefaultDecoder}
import kafka.message.Message
val kafkaParams = Map[String, String](
"zookeeper.connect" -> zkQuorum, "group.id" -> group,
"zookeeper.connection.timeout.ms" -> "10000")
val lines = KafkaUtils.createStream[String, Message, StringDecoder, DefaultDecoder](
ssc, kafkaParams, topics, storageLevel)
这将获得一个
DStream[(String,kafka.message.message)]
,您应该能够检索原始字节并从那里转换为Avro。您可以执行以下操作:
import kafka.serializer.{StringDecoder, DefaultDecoder}
import kafka.message.Message
val kafkaParams = Map[String, String](
"zookeeper.connect" -> zkQuorum, "group.id" -> group,
"zookeeper.connection.timeout.ms" -> "10000")
val lines = KafkaUtils.createStream[String, Message, StringDecoder, DefaultDecoder](
ssc, kafkaParams, topics, storageLevel)
这将为您获得一个DStream[(String,kafka.message.message)]
,您应该能够检索原始字节并从那里转换为Avro。这对我很有用:
val lines =
KafkaUtils.createStream[String,Array[Byte],StringDecoder,DefaultDecoder]
(ssc,kafkaParams,topicMap,StorageLevel.MEMORY_AND_DISK_2)
我的要求是获取字节数组,因此改为Array[Byte],而不是kafka.message.message这对我很有效:
val lines =
KafkaUtils.createStream[String,Array[Byte],StringDecoder,DefaultDecoder]
(ssc,kafkaParams,topicMap,StorageLevel.MEMORY_AND_DISK_2)
我的要求是获取字节数组,因此改为Array[Byte],而不是kafka.message.message非常感谢joe的输入。我会用结果更新原始帖子。我已经用建议的最新代码更改结果更新了原始帖子。请帮助理解实现中的错误。看起来您需要将
topicMap
,而不是topics
传递给createStream。此外,您链接的文档是旧的。我看到的是:谢谢乔,这是我的错误。监督topics变量。使用最新结果更新。仍然有一个classcastexception。再次更新了原来的帖子。需要你的宝贵见解。乔,谢谢你的支持。只是做了一个小小的调整,将消息更改为Array[Byte],解决了我的问题。如果您能够深入了解如何将kafka.message.message转换为字节数组,或者在需要时如何使用它,那就太好了。非常感谢joe的输入。我会用结果更新原始帖子。我已经用建议的最新代码更改结果更新了原始帖子。请帮助理解实现中的错误。看起来您需要将topicMap
,而不是topics
传递给createStream。此外,您链接的文档是旧的。我看到的是:谢谢乔,这是我的错误。监督topics变量。使用最新结果更新。仍然有一个classcastexception。再次更新了原来的帖子。需要你的宝贵见解。乔,谢谢你的支持。只是做了一个小小的调整,将消息更改为Array[Byte],解决了我的问题。如果您能够深入了解如何将kafka.message.message转换为字节数组,或者在需要时如何使用它,那就太好了。