如何计算火花流中每秒的项目数?

时间:2016-09-10 03:12:25

标签: apache-spark spark-streaming

我得到了一个json流,我希望计算机上每秒状态为“待定”的项目数。我怎么做?到目前为止我有下面的代码和1)我不确定它是否正确。 2)它返回一个Dstream,但我的目标是每秒存储一个数字到cassandra或队列,或者你可以想象有函数public void store(Long number){}

  // #1
 jsonMessagesDStream
        .filter(new Function<String, Boolean>() {
        @Override
        public Boolean call(String v1) throws Exception {
            JsonParser parser = new JsonParser();
            JsonObject jsonObj = parser.parse(v1).getAsJsonObject();
            if (jsonObj != null && jsonObj.has("status")) {
                return jsonObj.get("status").getAsString().equalsIgnoreCase("Pending");
            }
            return false;
        }
    }).countByValue().foreachRDD(new VoidFunction<JavaPairRDD<String, Long>>() {
        @Override
        public void call(JavaPairRDD<String, Long> stringLongJavaPairRDD) throws Exception {
            store(stringLongJavaPairRDD.count());
        }
    });

尝试以下操作:仍然无法正常工作,因为它一直打印为零,不确定是否正确?

     // #2
    jsonMessagesDStream
        .filter(new Function<String, Boolean>() {
        @Override
        public Boolean call(String v1) throws Exception {
            JsonParser parser = new JsonParser();
            JsonObject jsonObj = parser.parse(v1).getAsJsonObject();
            if (jsonObj != null && jsonObj.has("status")) {
                return jsonObj.get("status").getAsString().equalsIgnoreCase("Pending");
            }
            return false;
        }
    }).foreachRDD(new VoidFunction<JavaRDD<String>>() {
        @Override
        public void call(JavaRDD<String> stringJavaRDD) throws Exception {
            store(stringJavaRDD.count());
        }
    });

堆栈跟踪的一部分

16/09/10 17:51:39 INFO SparkContext: Starting job: count at Consumer.java:88
16/09/10 17:51:39 INFO DAGScheduler: Got job 17 (count at Consumer.java:88) with 4 output partitions
16/09/10 17:51:39 INFO DAGScheduler: Final stage: ResultStage 17 (count at Consumer.java:88)
16/09/10 17:51:39 INFO DAGScheduler: Parents of final stage: List()
16/09/10 17:51:39 INFO DAGScheduler: Missing parents: List()
16/09/10 17:51:39 INFO DAGScheduler: Submitting ResultStage 17 (MapPartitionsRDD[35] at filter at Consumer.java:72), which has no missing parents

BAR被打印但不是FOO

//Debug code
jsonMessagesDStream
        .filter(new Function<String, Boolean>() {
        @Override
        public Boolean call(String v1) throws Exception {
            System.out.println("****************FOO******************");
            JsonParser parser = new JsonParser();
            JsonObject jsonObj = parser.parse(v1).getAsJsonObject();
            if (jsonObj != null && jsonObj.has("status")) {
                return jsonObj.get("status").getAsString().equalsIgnoreCase("Pending");
            }
            return false;
        }
    }).foreachRDD(new VoidFunction<JavaRDD<String>>() {
        @Override
        public void call(JavaRDD<String> stringJavaRDD) throws Exception {
            System.out.println("*****************BAR******************");
            store(stringJavaRDD.count());
        }
    });

2 个答案:

答案 0 :(得分:1)

由于您已经过滤了结果集,因此您可以在DStream / RDD上执行count()。

另外,我不认为你需要在这里使用窗口,如果你每秒都从源头阅读。当微批次间隔与聚合频率不匹配时,需要窗口化。您是否在寻找不到一秒的微批次频率?

  

它返回给我一个Dstream,但我的目标是每秒存储一个数字到cassandra或队列

Spark的工作方式是每次在现有DStream上进行计算时都会提供DStream。这样你就可以轻松地将功能链接在一起。您还应该了解Spark中的转换和操作之间的区别。像filter(),count()等函数是转换,就像它们在DStream上运行并给出一个新的DStream一样。但是如果你需要副作用(比如打印,推送到数据库等),你应该看看Spark的动作。

如果你需要将DStream推送到cassandra,你应该看看cassandra连接器,这些连接器将显示可用于将数据推送到cassandra中的函数(Spark术语中的操作)。

答案 1 :(得分:1)

无论批次间隔如何,您都可以使用1秒的滑动窗口和reduceByKey功能。选择1秒幻灯片间隔后,您将每秒收到一次商店电话会议。