![](/img/trans.png)
[英]How to parse dynamic json formatted kafka message in spark streaming
[英]How to parse Json formatted Kafka message in spark streaming
我在Kafka上有這樣的JSON消息:
{"id_post":"p1", "message":"blablabla"}
我想解析消息,並打印(或用於進一步計算) message
元素。 用下面的代碼我打印json
val kafkaStream = KafkaUtils.createStream(ssc, zkQuorum, inputGroup, topicMap)
val postStream = kafkaStream.map(_._2)
postStream.foreachRDD((rdd, time) => {
val count = rdd.count()
if (count > 0){
rdd.foreach(record => {
println(record)
}
}
但我無法獲得一個要素。 我嘗試了一些JSON解析器,但是沒有運氣。 任何想法?
更新:使用不同的JSON解析器時會出現一些錯誤,這是circe解析器的代碼和輸出:
val parsed_record = parse(record)
和輸出:
14:45:00,676 ERROR Executor:95 - Exception in task 0.0 in stage 4.0 (TID 4)
java.lang.NoSuchMethodError: scala.Predef$.ArrowAssoc(Ljava/lang/Object;)Ljava/lang/Object;
at io.circe.jawn.CirceSupportParser$$anon$1$$anon$4.add(CirceSupportParser.scala:36)
at jawn.CharBasedParser$class.parseString(CharBasedParser.scala:90)
at jawn.StringParser.parseString(StringParser.scala:15)
at jawn.Parser.rparse(Parser.scala:397)
at jawn.Parser.parse(Parser.scala:338)
at jawn.SyncParser.parse(SyncParser.scala:24)
at jawn.SupportParser$$anonfun$parseFromString$1.apply(SupportParser.scala:15)
依此類推。在我使用parse(record)
的行上,它似乎無法訪問和/或解析字符串record
。
如果在parse(record)
處使用lift-json ,則相同,錯誤輸出或多或少是相同的:
16:58:20,425 ERROR Executor:95 - Exception in task 0.0 in stage 4.0 (TID 4)
java.lang.NoSuchMethodError: scala.runtime.ObjectRef.create(Ljava/lang/Object;)Lscala/runtime/ObjectRef;
at net.liftweb.json.JsonParser$$anonfun$2.apply(JsonParser.scala:144)
at net.liftweb.json.JsonParser$$anonfun$2.apply(JsonParser.scala:141)
at net.liftweb.json.JsonParser$.parse(JsonParser.scala:80)
at net.liftweb.json.JsonParser$.parse(JsonParser.scala:45)
at net.liftweb.json.package$.parse(package.scala:40)
at SparkConsumer$$anonfun$main$1$$anonfun$apply$1.apply(SparkConsumer.scala:98)
at SparkConsumer$$anonfun$main$1$$anonfun$apply$1.apply(SparkConsumer.scala:95)
at scala.collection.Iterator$class.foreach(Iterator.scala:727)
在scala.collection.AbstractIterator.foreach(Iterator.scala:1157)
我已經解決了這個問題,因此我在這里寫以供將來參考:
依賴,依賴,依賴!
我選擇使用lift-json ,但這適用於任何JSON解析器和/或框架。
我正在使用的SPARK版本( v1.4.1 )是與scala 2.10兼容的版本,這里是pom.xml的依賴項:
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-streaming_2.10</artifactId>
<version>1.4.1</version>
<scope>provided</scope>
</dependency>
和其他一些庫。 我正在使用scala 2.11的lift-json版本...這是WRONG 。
因此,為了將來,我以及如果您正在閱讀此主題:與scala版本和依賴關系保持一致。 在lift-json的情況下:
<dependency>
<groupId>net.liftweb</groupId>
<artifactId>lift-json_2.10</artifactId>
<version>3.0-M1</version>
</dependency>
你也有同樣的問題。
但是我通過使用fastjson
解決了這個問題。
SBT dependency : // http://mvnrepository.com/artifact/com.alibaba/fastjson libraryDependencies += "com.alibaba" % "fastjson" % "1.2.12"
或
Maven dependency : <!-- http://mvnrepository.com/artifact/com.alibaba/fastjson --> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.12</version> </dependency>
你可以試試看。 希望這會有所幫助。
在Scala / Apache Spark中從JSON字符串提取數據
import org.apache.spark.rdd.RDD
object JsonData extends serializable{
def main(args: Array[String]): Unit = {
val msg = "{ \"id_post\":\"21\",\"message\":\"blablabla\"}";
val m1 = msgParse(msg)
println(m1.id_post)
}
case class SomeClass(id_post: String, message: String) extends serializable
def msgParse(msg: String): SomeClass = {
import org.json4s._
import org.json4s.native.JsonMethods._
implicit val formats = DefaultFormats
val m = parse(msg).extract[SomeClass]
return m
}
}
以下是Maven體面
<dependency>
<groupId>org.json4s</groupId>
<artifactId>json4s-native_2.10</artifactId>
<version>3.3.0</version>
</dependency>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.