用spark streamming统计单词数量时,reduceBykey只会统计局部的单词数量,每个batch的每个单词的数量,而不能统计每个key所有value值。
所以想要统计全局key的value值,就必须加入有状态计算updataStatusBykey,更新每一个key的状态。
在计算单词数量前,对spark streamming做checkpoint操作,目的时把之前batch的计算结果保存在checkpoint目录中。
1 object Demo02updataStateByKey { 2 def main(args: Array[String]): Unit = { 3 4 val conf = new SparkConf().setAppName("Demo02updataStateByKey").setMaster("local[2]") 5 6 val sc = new SparkContext(conf) 7 8 9 val ssc = new StreamingContext(sc, Durations.seconds(6)) 10 11 // 设置checkpoint的路径,hdfs路径 12 ssc.checkpoint("/spark/data/wc") 13 14 // 创建实时DStream 15 val linesDS: DStream[String] = ssc.socketTextStream("master", 8888) 16 17 val kvDS: DStream[(String, Int)] = linesDS 18 .flatMap(_.split(",")) 19 .map((_, 1)) 20 21 /** 22 * 有状态计算 23 * reduceByKey 只能进行局部统计 24 * 25 * 使用updataStateByKey 更新每一个key的状态 26 * 27 */ 28 29 def updataValue(seq: Seq[Int], count: Option[Int]): Option[Int] = { 30 //获取之前统计的结果 31 val last = count.getOrElse(0) 32 //获取当前batch单词取得的结果 33 val now = seq.sum 34 35 //更新之后的状态 36 Option(now + last) 37 } 38 39 // 累加统计单词数量 40 val countDS: DStream[(String, Int)] = kvDS.updateStateByKey(updataValue) 41 42 countDS.print() 43 44 ssc.start() 45 ssc.awaitTermination() 46 ssc.stop() 47 } 48 }