在JavaSparkStreamingContext中执行查询

时间:2017-06-16 09:07:53

标签: java apache-spark neo4j spark-streaming

我有一个与Spark JavaStreamingContext一起使用的程序。我已经了解到,在使用DStream时,只有少数输出操作被允许为print()。 这是一段代码

private static void analyzeHashtags() throws InterruptedException {
    JavaPairDStream<String, String> messages =  KafkaUtils.createStream(jssc, zookeeper_server, kafka_consumer_group, topics);
    JavaPairDStream<String, Integer> lines = messages.mapToPair((x)->(new Tuple2<String, Integer>(x._2, 1))).reduceByKey(sumFunc);
    lines.print();
    jssc.start();
    jssc.awaitTermination();

}

现在我想在此代码中添加查询操作,如下所示:

private static void analyzeHashtags() throws InterruptedException, SQLException {
    JavaPairDStream<String, String> messages =  KafkaUtils.createStream(jssc, zookeeper_server, kafka_consumer_group, topics);
    JavaPairDStream<String, Integer> lines = messages.mapToPair((x)->(new Tuple2<String, Integer>(x._2, 1))).reduceByKey(sumFunc);
    lines.print();
    String hashtag = "#dummy"; int frequencies = 59;
    String cql = " CREATE (n:Hashtag {name:'"+hashtag+"', freq:"+frequencies+"})";
    st.executeUpdate(cql);
    jssc.start();
    jssc.awaitTermination();
}

但是这段代码只执行一次查询。我希望它每次循环时执行它。 怎么可能做到这一点?提前谢谢。

1 个答案:

答案 0 :(得分:2)

要对DStream执行任意操作,我们使用foreachRDD。它提供了每个批处理间隔的数据访问,由底层的rdd。

表示

Java / Scala伪(混合)代码:

JavaPairDStream<String, Integer> lines = messages.mapToPair((x)->(new 
Tuple2<String, Integer>(x._2, 1))).reduceByKey(sumFunc);
lines.foreachRDD{ rdd => 
    .. do something with the RDD here...
}

通常,do something对RDD上的数据进行操作。 我们可以使用诸如foreachPartition之类的RDD函数以分布式方式对该数据进行操作。

但是,考虑到你在这里使用本地neo4j连接,并且如果每个流间隔的数据不是很大,我们可以将数据收集到驱动程序并在本地执行操作。在这种情况下似乎是合适的,因为数据已经通过了分布式减少阶段(reduceBykey

因此,foreachRDD部分将成为:

lines.foreachRDD{ rdd => 
    val localDataCollection = rdd.collect
    localDataCollection.foreach{ keywordFreqPair => 
      val cql = "CREATE (n:Hashtag {name:'"+keywordFreqPair._1+"', freq:"+keywordFreqPair._2+"})"
      st.executeUpdate(cql)
}