如何在java中处理Apache spark流中的Json数据

如何在java中处理Apache spark流中的Json数据,java,apache-spark,apache-kafka,spark-streaming,Java,Apache Spark,Apache Kafka,Spark Streaming,嗨,我是Apache Spark的新手。我正在学习的路上。 我已经为kafka主题中的json数据编写了spark流。下面是连续传输的json数据。 但现在我不知道如何处理这些json数据。我使用DataSet和DataFrame来处理Json数据,我遇到了一些错误。 请帮我举几个例子,说明我如何处理流媒体传输的数据 注意:我使用的是Apache spark 1.6.3版本 (null{"time":"2017/08/21 18:25:11","model":"20E84fb","speed":

嗨,我是Apache Spark的新手。我正在学习的路上。 我已经为kafka主题中的json数据编写了spark流。下面是连续传输的json数据。 但现在我不知道如何处理这些json数据。我使用DataSet和DataFrame来处理Json数据,我遇到了一些错误。 请帮我举几个例子,说明我如何处理流媒体传输的数据

注意:我使用的是Apache spark 1.6.3版本

(null{"time":"2017/08/21 18:25:11","model":"20E84fb","speed":"20E84fb","cellId":"0605d822E84fb","course":"146.37E84fb","header":"ST600ALTE84fb","deviceId":206675884,"distance":"166E84fb","longitude":"-099.168493E84fb","latitude":"19.428616E84fb","payload":"ST600ALT+number+;206675884;20;376;20161005;16:26:59;0605d822;334;20;2ee5;63;+19.428616;-099.168493;000.213;146.37;6;1;166;12.21;000000;34;000887;4.4;1;0.00E84fb","date":"2017/08/21 18:25:11E84fb"})
代码:

package datapipeline;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.spark.SparkConf;
import org.apache.spark.SparkContext;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.function.Function;
import org.apache.spark.api.java.function.Function2;
import org.apache.spark.sql.DataFrame;
import org.apache.spark.sql.Dataset;
import org.apache.spark.sql.SQLContext;
import org.apache.spark.storage.StorageLevel;
import org.apache.spark.streaming.Duration;
import org.apache.spark.streaming.Time;
import org.apache.spark.streaming.api.java.JavaDStream;
import org.apache.spark.streaming.api.java.JavaPairReceiverInputDStream;
import org.apache.spark.streaming.api.java.JavaStreamingContext;
import org.apache.spark.streaming.kafka.KafkaUtils;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.onosproject.net.Device;

import scala.Tuple2;

public final class SparkConsumer {
    //private static SparkContext sc = new SparkContext();
    private static final Pattern SPACE = Pattern.compile(" ");


    private static void setLogLevels() {
        boolean log4jInitialized = Logger.getRootLogger().getAllAppenders().hasMoreElements();
        if (!log4jInitialized) {
            // We first log something to initialize Spark's default logging, then we override the
            // logging level.
            Logger.getLogger(SparkConsumer.class).info("Setting log level to [WARN] for streaming example." +
                    " To override add a custom log4j.properties to the classpath.");
            Logger.getRootLogger().setLevel(Level.WARN);
        }
    }

    public static void main(String[] args) throws Exception {

        String jars[]={"C:\\DeviceStreaming-1.0.0.jar"};


        setLogLevels();


        SparkConf sparkConf = new SparkConf().setAppName("CustomerKafkaConsumerThread")
                .set("spark.local.ip","localhost:9092")
                .setMaster("local[*]").setJars(jars);
        JavaStreamingContext jssc = new JavaStreamingContext(sparkConf, new Duration(3000));
        JavaSparkContext ctx = JavaSparkContext.fromSparkContext(SparkContext.getOrCreate(sparkConf));

        SQLContext sqlContext = new SQLContext(ctx);

        Map<String, Integer> topicMap = new HashMap<>();

        topicMap.put("iot", 10);


        JavaPairReceiverInputDStream<String, String> messages = KafkaUtils.createStream(jssc,"localhost:2181","SparkConsumer", topicMap,StorageLevel.MEMORY_ONLY());
        messages.print();


        JavaDStream<String> json = messages.map(
                new Function<Tuple2<String, String>, String>() {
                    public String call(Tuple2<String, String> message) {

                        return message._2();
                    }
                }
            );

        json.foreachRDD(rdd -> {

            //DataFrame df = sqlContext.read().json(rdd);
            DataFrame df=sqlContext.createDataFrame(rdd, Device.class);
            df.registerTempTable("rdd");
            df.filter("cellId");
            /*DataFrame deviceFrame= sqlContext.sql("SELECT cellID FROM rdd where cellId=206675884");
            df.show();
            df.printSchema();

            List<String> list=  deviceFrame.javaRDD().map(row -> row.getString(0)).collect();*/

        });

        jssc.start();
        jssc.awaitTermination();
    }
}
包数据管道;
导入java.util.array;
导入java.util.HashMap;
导入java.util.List;
导入java.util.Map;
导入java.util.regex.Pattern;
导入org.apache.log4j.Level;
导入org.apache.log4j.Logger;
导入org.apache.spark.SparkConf;
导入org.apache.spark.SparkContext;
导入org.apache.spark.api.java.JavaRDD;
导入org.apache.spark.api.java.JavaSparkContext;
导入org.apache.spark.api.java.function.function;
导入org.apache.spark.api.java.function.Function2;
导入org.apache.spark.sql.DataFrame;
导入org.apache.spark.sql.Dataset;
导入org.apache.spark.sql.SQLContext;
导入org.apache.spark.storage.StorageLevel;
导入org.apache.spark.streaming.Duration;
导入org.apache.spark.streaming.Time;
导入org.apache.spark.streaming.api.java.JavaDStream;
导入org.apache.spark.streaming.api.java.javapairReceiverInputStream;
导入org.apache.spark.streaming.api.java.JavaStreamingContext;
导入org.apache.spark.streaming.kafka.KafkaUtils;
导入org.json.simple.JSONObject;
导入org.json.simple.parser.JSONParser;
导入org.onosproject.net.Device;
导入scala.Tuple2;
公共最终类SparkConsumer{
//私有静态SparkContext sc=新SparkContext();
私有静态最终模式空间=Pattern.compile(“”);
私有静态void setLogLevels(){
boolean log4jInitialized=Logger.getRootLogger().getAllAppenders().hasMoreElements();
如果(!log4jInitialized){
//我们首先记录一些东西来初始化Spark的默认日志记录,然后重写
//日志记录级别。
getLogger.getLogger(SparkConsumer.class).info(“将日志级别设置为[警告](例如流媒体)。”+
“覆盖将自定义log4j.properties添加到类路径。”);
Logger.getRootLogger().setLevel(Level.WARN);
}
}
公共静态void main(字符串[]args)引发异常{
字符串jars[]={“C:\\DeviceStreaming-1.0.0.jar”};
setLogLevels();
SparkConf SparkConf=新的SparkConf().setAppName(“CustomerKafkCaponSumerThread”)
.set(“spark.local.ip”,“localhost:9092”)
.setMaster(“本地[*]”)。setJars(jars);
JavaStreamingContext jssc=新的JavaStreamingContext(sparkConf,新的持续时间(3000));
JavaSparkContext ctx=JavaSparkContext.fromSparkContext(SparkContext.getOrCreate(sparkConf));
SQLContext SQLContext=新的SQLContext(ctx);
Map topicMap=newhashmap();
topicMap.put(“物联网”,10);
JavaPairReceiverInputStream messages=KafkaUtils.createStream(jssc,“localhost:2181”,“SparkConsumer”,topicMap,StorageLevel.MEMORY_ONLY());
messages.print();
JavaDStream json=messages.map(
新函数(){
公共字符串调用(Tuple2消息){
返回消息。_2();
}
}
);
json.foreachRDD(rdd->{
//DataFrame df=sqlContext.read().json(rdd);
DataFrame df=sqlContext.createDataFrame(rdd,Device.class);
df.寄存器可清空(“rdd”);
df.过滤器(“cellId”);
/*DataFrame deviceFrame=sqlContext.sql(“从rdd中选择cellID,其中cellID=206675884”);
df.show();
printSchema();
List List=deviceFrame.javaRDD().map(行->行.getString(0)).collect()*/
});
jssc.start();
jssc.aittimination();
}
}

您可以使用get\u JSON\u对象函数从JSON中提取数据

根据指定的json路径从json字符串中提取json对象,并返回提取的json对象的json字符串。如果输入的json字符串无效,它将返回null

尝试以下方法:

df.withCoulmn(“已解析的”、…函数。来自_json(新列(“原始的_json)))。printSchema

这将为您提供它生成的模式,然后您可以根据需要执行操作

编辑: 也许这不是1.6.3的最佳解决方案,也许您需要UDF对解析的对象执行操作


请参阅:

您可以使用get\u JSON\u对象函数从JSON提取数据

根据指定的json路径从json字符串中提取json对象,并返回提取的json对象的json字符串。如果输入的json字符串无效,则返回null

尝试以下方法:

df.withCoulmn(“已解析的”、…函数。来自_json(新列(“原始的_json)))。printSchema

这将为您提供它生成的模式,然后您可以根据需要执行操作

编辑: 也许这不是1.6.3的最佳解决方案,也许您需要UDF对解析的对象执行操作


请参阅:

谢谢您的解决方案。但是您提到的过程在spark的2.1.0版本中起作用。我正在编写1.6.3。为此,我没有注意到版本。我更新了一个新的答案谢谢你的解决方案。但是您提到的过程在spark的2.1.0版本中起作用。我正在编写1.6.3。为此,我没有注意到版本。我用一个新的答案更新了它