Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Apache spark 如何在JavaPairDStream中使用countByKey而不使用foreachRDD?_Apache Spark_Spark Streaming - Fatal编程技术网

Apache spark 如何在JavaPairDStream中使用countByKey而不使用foreachRDD?

Apache spark 如何在JavaPairDStream中使用countByKey而不使用foreachRDD?,apache-spark,spark-streaming,Apache Spark,Spark Streaming,这可能是一个非常琐碎的问题,但我不知道是什么错了 我有一个JavaPairDStream,对于每个批处理间隔,我希望获得流中RDD中的键数,以便稍后在应用程序中使用这个数字 问题是,我可以通过执行以下操作获得密钥数: streamGiveKey.foreachRDD(new Function<JavaPairRDD<String, String>, Void>() { @Override public Void call(JavaPairR

这可能是一个非常琐碎的问题,但我不知道是什么错了

我有一个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);
streamGiveKey.foreachRDD(新函数(){
@凌驾
公共Void调用(JavaPairdd StringJavaPairdd)引发异常{
int a=stringjavapairdd.countByKey().size();
countPartitions=a;
系统输出打印(a+“\r\n”);
返回null;
}
});
JavaPairDStreamgroupingEachBoilerValues=streamGiveKey.groupByKey(countPartitions);
其中,
countPartitions
是一个全局变量,用于存储一个批处理间隔的密钥数

问题是,应用程序永远不会到达
groupingEachBoilerValues
,它只是在forEachRDD中无休止地打印

我还有别的办法吗?
非常感谢。

您可以在驱动程序中保留全局计数。这里

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)
 }

如果我在Main()方法中声明此变量,则在foreachRDD中无法识别它。我应该将其声明为全局变量吗?同样的情况也会发生。我声明了
private static long globalCount=0L
,将其替换为countPartitions,但它不起作用。在spark群集上部署代码时,这将不起作用。它只在分布式任务将在同一jvm实例上运行时才起作用。@YoYo它确实适用于流式处理。我现在已经开始工作了-将放置代码。即使它可以工作,它也没有并发访问变量的基本保护机制。您将能够让它编译,甚至运行,但很可能您会看到全局变量没有改变,除非您在本地上下文中执行它。