我试图通过Spark Streaming从Kafka主题获取信息,然后解析我在主题中得到的json。 为了在DStream中获取主题,我使用stringReader,然后使用foreach从DStream中获取每个RDD:
myRDD.collect().foreach(println)
为了将myRDD转换为json(当我打印myRDD时,json的格式是正确的)并提取我需要的两个字段,我尝试使用json4s并尝试了这个:
val jsonEvent = Json.parse(myRDD)
val srcIp = (jsonEvent / "src_ip")
val dstIp = (jsonEvent / "dst_ip")
我也尝试过这样使用json4:
val jsonEvent = parse(myRDD).asInstanceOf[JObject]
val srcIp = jsonEvent / "src_ip"
但它也无法正常工作。
这是输出:
java.lang.NoSuchMethodError: rg.json4s.jackson.JsonMethods$.parse$default$3()Z
这些是我使用的版本:
<dependency>
<groupId>org.json4s</groupId>
<artifactId>json4s-native_2.10</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>org.json4s</groupId>
<artifactId>json4s-jackson_2.10</artifactId>
<version>3.5.1</version>
</dependency>
我认为问题在于我不知道如何将RDD中的每条记录转换为json对象来解析它。有人可以请我更深入地解释一下,以便我能理解它是如何工作的吗? 我的代码是否正确?
谢谢。
答案 0 :(得分:1)
Spark为您提供了API来读取数据集/数据帧的输入JSON。
如果您正在从文件中读取JSON。您可以使用SparkSession
read().json()
方法
SparkSession spark = SparkSession.builder().appName("Test App").master("local[*]")
.getOrCreate();
Dataset<Row> inputfileDataset = spark.read().option("multiLine", true).option("mode", "PERMISSIVE")
.json("C:\path-to-file\inputfile.json");
如果您正在阅读KAFKA Streams。您可以通过将每个RDD转换为List
String
来迭代每个RDD,然后将它们转换为数据集/数据帧
JavaPairInputDStream<String, String> directKafkaStream = KafkaUtils.createDirectStream(ssc, String.class,
String.class, StringDecoder.class, StringDecoder.class, kafkaParams, topics);
JavaDStream<String> inputJsonStream = directKafkaStream.map(rdd -> {
return rdd._2;
});
inputJsonStream.foreachRDD(inputRDD -> {
SparkSession spark = JavaSparkSessionSingleton.getInstance(inputRDD.context().getConf());
List<String> strings = inputRDD.collect();
strings.forEach(x -> {
Dataset<Row> inputDataset = spark.read().option("multiLine",true).option("mode", "PERMISSIVE").json(inputRDD);
inputDataset.printSchema();
});
要查询数据集/数据帧,您可以使用数据集上的Select()
函数,然后将其转换为您想要的数据类型。