这可能是一个非常微不足道的问题,但我不知道出了什么问题。
我有一个JavaPairDStream,并且对于每个批处理间隔,我想在流中获取RDD中的键数,以便稍后我可以在应用程序中使用此数字。
问题是,我可以通过以下方式获得密钥数量:
streamGiveKey.foreachRDD(new Function<JavaPairRDD<String, String>, Void>() {
@Override
public Void call(JavaPairRDD<String, String> stringStringJavaPairRDD) throws Exception {
int a= stringStringJavaPairRDD.countByKey().size();
countPartitions=a;
System.out.print(a + "\r\n");
return null;
}
});
JavaPairDStream<String,Iterable<String>>groupingEachBoilerValues= streamGiveKey.groupByKey(countPartitions);
其中countPartitions
是一个全局变量,用于存储一个批处理间隔的键数。
问题是,应用程序永远不会到达groupingEachBoilerValues
,它只会在forEachRDD中无限循环地打印。
我还有另一种方式吗? 非常感谢你。
答案 0 :(得分:1)
您可以在驱动程序中保留全局计数。在这里
long globalCount = 0L;
.. foreachRDD(
.. globalCount += rdd.count();
此globalCount变量将驻留在驱动程序中,并将在每批次后继续更新。
更新怀疑论者啊!以上代码特定于流式传输。我很清楚它不适用于标准的非流式RDD代码。
我创建了包含上述方法的测试代码,并且计数器工作正常。将在几分钟内发布此代码。
import org.apache.spark._
import org.apache.spark.streaming._
var globalCount = 0L
val ssc = new StreamingContext(sc, Seconds(4))
val lines = ssc.socketTextStream("localhost", 19999)
val words = lines.flatMap(_.split(" "))
val pairs = words.map(word => (word, 1))
val wordCounts = pairs.reduceByKey(_ + _)
wordCounts.print()
lines.count().foreachRDD(rdd => { globalCount += rdd.count; println(globalCount) } )
ssc.start
ssc.awaitTermination
这里正在运行
scala> ssc.awaitTermination
-------------------------------------------
Time: 1466366660000 ms
-------------------------------------------
1
-------------------------------------------
Time: 1466366664000 ms
-------------------------------------------
2
-------------------------------------------
Time: 1466366668000 ms
-------------------------------------------
3
这是一个微小的数据生成器程序,用于测试:
import java.net._
import java.io._
case class ClientThread(sock: Socket) {
new Thread() {
override def run() {
val bos = new BufferedOutputStream(sock.getOutputStream)
while (true) {
bos.write(s"Hello there it is ${new java.util.Date().toString}\n".getBytes)
Thread.sleep(3000)
}
}
}.start
}
val ssock = new ServerSocket(19999)
while (true) {
val sock = ssock.accept()
ClientThread(sock)
}