我有火花串设置,以便它从套接字读取,在将数据发布到兔子队列之前对数据进行一些丰富。 在设置流式上下文之前,通过读取常规文本文件(Source.fromFile ...)实例化的Map可以查找富集信息。
我有一种感觉,这不是应该做的事情。另一方面,当使用StreamingContext时,我只能读取流,而不能读取静态文件,因为我可以使用SparkContext。
我可以尝试允许多个上下文,但我不确定这是否也是正确的方法。
非常感谢任何建议。
答案 0 :(得分:7)
假设用于浓缩的地图相对较小而不能保存在内存中,建议在Spark作业中使用该数据的方法是通过广播变量。这个变量的内容将被发送到每个执行器一次,从而避免了序列化闭包中捕获的数据集的开销。
广播变量是在驱动程序中实例化的包装器,数据被解包'在闭包中使用broadcastVar.value
方法。
这将是如何将广播变量与DStream一起使用的示例:
// could replace with Source.from File as well. This is just more practical
val data = sc.textFile("loopup.txt").map(toKeyValue).collectAsMap()
// declare the broadcast variable
val bcastData = sc.broadcast(data)
... initialize streams ...
socketDStream.map{ elem =>
// doing every step here explicitly for illustrative purposes. Usually, one would typically just chain these calls
// get the map within the broadcast wrapper
val lookupMap = bcastData.value
// use the map to lookup some data
val lookupValue = lookupMap.getOrElse(elem, "not found")
// create the desired result
(elem, lookupValue)
}
socketDStream.saveTo...
答案 1 :(得分:4)
如果您的文件很小而不在分布式文件系统上,Source.fromFile
就可以了(无论做什么工作)。
如果您想通过SparkContext读取文件,您仍然可以通过streamingContext.sparkContext
访问它,并将其与transform
或foreachRDD
中的DStream结合使用。