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