在spark Streaming中如何在n批次之后重新加载查找非流rdd

时间:2016-04-29 18:11:34

标签: apache-spark spark-streaming

假设我有一个流式上下文,它执行了很多步骤,然后最后微批处理查找或加入预加载的RDD。我必须每12小时更新一次预加载的RDD。我怎样才能做到这一点。我做的任何与流式上下文无关的事情都没有重播到我的理解,我如何得到这个称为流式RDD的形式之一。我需要只进行一次调用,无论流dstream有多少分区

1 个答案:

答案 0 :(得分:3)

这可以通过在需要重新加载时重新创建外部RDD来实现。它需要定义一个可变变量来保存在给定时刻活动的RDD引用。在dstream.foreachRDD中,我们可以检查RDD参考需要刷新的时刻。

这是一个如何看起来的例子:

val stream:DStream[Int] = ??? //let's say that we have some DStream of Ints

// Some external data as an RDD of (x,x)
def externalData():RDD[(Int,Int)] = sparkContext.textFile(dataFile)
   .flatMap{line => try { Some((line.toInt, line.toInt)) } catch {case ex:Throwable => None}}
   .cache()

// this mutable var will hold the reference to the external data RDD
var cache:RDD[(Int,Int)] = externalData() 
// force materialization - useful for experimenting, not needed in reality
cache.count()
// a var to count iterations -- use to trigger the reload in this example 
var tick = 1
// reload frequency
val ReloadFrequency = 5  

stream.foreachRDD{ rdd => 
    if (tick == 0) { // will reload the RDD every 5 iterations
     // unpersist the previous RDD, otherwise it will linger in memory, taking up resources.
     cache.unpersist(false)
     // generate a new RDD  
     cache = externalData() 
    }
    // join the DStream RDD with our reference data, do something with it...
    val matches = rdd.keyBy(identity).join(cache).count() 
    updateData(dataFile, (matches + 1).toInt) // so I'm adding data to the static file in order to see when the new records become alive
    tick = (tick + 1) % ReloadFrequency
}
streaming.start

在此解决方案之前,我研究了在RDD中使用persist标志的可能性,但它没有按预期工作。看起来unpersist()在重新使用时不会强制重新实现RDD。