以下测试代码:
object StreamTest {
def main(args: Array[String]) {
val sc = new SparkContext
val ssc = new StreamingContext(sc, Seconds(1))
ssc.checkpoint("./checkpoint")
val lines = ssc.socketTextStream("192.168.11.5", 9999, StorageLevel.MEMORY_ONLY_SER)
val accStream = lines.map((_ , "")).updateStateByKey(updateFunc)
accStream.print()
ssc.start()
ssc.awaitTermination()
}
def updateFunc: (Seq[String], Option[Int]) => Option[Int] = { case _ => Some(1) }
}
当我通过NetCat发送一个数据(仅一个)时,请参见屏幕截图:
结果是:
我的问题是:为什么结果一直打印?为什么不一次? (我只向socket客户端发送一个数据。)
我再次测试(将火花流间隔时间设置为5秒):
发送数据:
结果是:
使用ConstantInputDStream
进行测试,代码如下:
object SparkStreaming {
def main(args: Array[String]) {
val sc = new SparkContext
val ssc = new StreamingContext(sc, Seconds(1))
ssc.checkpoint("./checkpoint")
val seq = Seq("key") //every 1 second send a "key"
val rdd = ssc.sparkContext.parallelize(seq)
//using ConstantInputDStream as inputDStream
val inputDStream = new ConstantInputDStream(ssc, rdd)
val map = inputDStream.map((_, "")).updateStateByKey(updateFunc)
map.print
ssc.start
ssc.awaitTermination
}
def updateFunc: (Seq[String], Option[Int]) => Option[Int] = { case _ => Some(1) }
}
结果是:
第3次测试的结果与第1次测试的结果相同。
在第一次测试中,我只在第一个中发送“密钥”。
在第三次测试中,ConstantInputDStream每1秒发送一次“密钥” 。
但为什么结果是一样的?因此使用socketTextStream
时结果非常奇怪。
答案 0 :(得分:1)
这是因为updateStateByKey
保存您的状态,除非处理新的Feed,否则不会更新。
答案 1 :(得分:1)
updateStateByKey
的重点是在需要时保存和累积状态。在updateStateByKey
之后,您的流是一组元组,其中包含键和更新函数返回的值。它将保持密钥的状态,直到您从更新函数而不是None
返回Some
。
您可以参考此答案中的示例实现:How to process a subset of input records in a batch, i.e. the first second in 3-sec batch time?