Kafka主题为Spark Streaming DStream,如何获取Json

时间:2017-05-02 13:37:47

标签: json scala apache-kafka spark-streaming dstream

我试图通过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对象来解析它。有人可以请我更深入地解释一下,以便我能理解它是如何工作的吗? 我的代码是否正确?

谢谢。

1 个答案:

答案 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()函数,然后将其转换为您想要的数据类型。