Apache spark 在数据流驱动程序中从RDD收集结果

Apache spark 在数据流驱动程序中从RDD收集结果,apache-spark,spark-streaming,rdd,dstream,Apache Spark,Spark Streaming,Rdd,Dstream,我在驱动程序中有这个函数,它将RDD的结果收集到一个数组中并发送回。然而,即使RDD(在数据流中)有数据,函数也返回一个空数组…我做错了什么 def runTopFunction() : Array[(String, Int)] = { val topSearches = some function.... val summary = new ArrayBuffer[(String,Int)]() topSearches.foreachRDD(rd

我在驱动程序中有这个函数,它将RDD的结果收集到一个数组中并发送回。然而,即使RDD(在数据流中)有数据,函数也返回一个空数组…我做错了什么

def runTopFunction() : Array[(String, Int)] = {
        val topSearches = some function....
        val summary = new ArrayBuffer[(String,Int)]()
        topSearches.foreachRDD(rdd => {
            summary = summary.++(rdd.collect())
        })    

    return summary.toArray
}

因此,虽然
foreachRDD
将执行您希望执行的操作,但它也是非阻塞的,这意味着它不会等到处理完所有流。由于您在调用
foreachRDD
后立即在缓冲区上校准
toArray
,因此尚未处理任何元素。

DStream。foreachRDD
是给定的
DStream
上的一个操作,将计划在每个流式批处理间隔上执行。它是稍后执行的作业的声明性构造

不支持以这种方式对值进行累加,因为当Dstream.forEachRDD只是说“在每次迭代中执行此操作”时,会立即执行周围的累加代码,从而生成一个空数组

根据计算后
摘要
数据的情况,关于如何实现这一点,有几个选项:

  • 如果数据需要由另一个进程检索,请使用共享的线程安全结构。优先级队列对于top-k用途非常有用
  • 如果数据将被存储(fs,db),您只需在对数据流应用
    topsearchs
    功能后写入存储器即可

计算不是“非阻塞”,而是延迟的,并安排在稍后的时刻。因此,这个答案在术语上是不正确的。foreachrdd的惰性与在数据流或RDD上的转换不同,它是一个操作,而不是一个转换。@user2888475但是在
streamingContext.start()之前不会发生任何事情
被调用,并且在每个
流媒体间隔
时间段都会安排一些事情发生。Spark Streaming中的操作导致调度的方式与Spark中的操作导致执行的方式相同。i、 e.没有动作的数据流不会做任何事情。