我正在尝试观察火花流如何使用DStream中的RDD来连接两个DStream,但看到奇怪的结果令人困惑。
在我的代码中,我从套接字流中收集数据,通过某种逻辑将它们分成2个PairedDStream。为了收集一些批次进行加入,我创建了一个窗口来收集最后三批。但是,加入的结果是无能为力的。请帮我理解。
object Join extends App {
val conf = new SparkConf().setMaster("local[4]").setAppName("KBN Streaming")
val sc = new SparkContext(conf)
sc.setLogLevel("ERROR")
val BATCH_INTERVAL_SEC = 10
val ssc = new StreamingContext(sc, Seconds(BATCH_INTERVAL_SEC))
val lines = ssc.socketTextStream("localhost", 8091)
//println(s"lines.slideDuration : ${lines.slideDuration}")
//lines.print()
val ds = lines.map(x => x)
import scala.util.Random
val randNums = List(1, 2, 3, 4, 5, 6)
val less = ds.filter(x => x.length <= 2)
val lessPairs = less.map(x => (Random.nextInt(randNums.size), x))
lessPairs.print
val greater = ds.filter(x => x.length > 2)
val greaterPairs = greater.map(x => (Random.nextInt(randNums.size), x))
greaterPairs.print
val join = lessPairs.join(greaterPairs).window(Seconds(30), Seconds(30))
join.print
ssc.start
ssc.awaitTermination
}
测试结果:
-------------------------------------------时间:1473344240000毫秒 -------------------------------------------(1,b)(4 ,S)
-------------------------------------------时间:1473344240000毫秒 -------------------------------------------(5,333)
-------------------------------------------时间:1473344250000毫秒 -------------------------------------------(2,x)
-------------------------------------------时间:1473344250000毫秒 -------------------------------------------(4,the)
-------------------------------------------时间:1473344260000毫秒 -------------------------------------------(2,a)(0 ,b)
-------------------------------------------时间:1473344260000毫秒 -------------------------------------------(2,ten)(1 ,一)(3,二)
-------------------------------------------时间:1473344260000毫秒 -------------------------------------------(4,(b,two ))
答案 0 :(得分:0)
当调用join时,将再次重新计算两个RDD,因此它们将包含与打印时显示的值不同的值。因此,我们需要在第一次计算两个RDD时进行缓存,因此稍后调用join时将使用相同的值(而不是再次重新计算两个RDD)。我尝试了多个例子,它工作正常。我错过了Spark的基本核心概念。
答案 1 :(得分:0)
摘自&#34;学习Spark&#34;书:
持久性(缓存)
如前所述,Spark RDD被懒惰地评估,有时我们可能希望多次使用相同的RDD。如果我们天真地这样做,Spark会在每次调用RDD上的操作时重新计算RDD及其所有依赖项。