Spark有状态算子
Spark有状态算子
不仅可以计算当前批次的结果,还可以结合上一次的结果,并对两次结果进行汇总
package com.streaming import org.apache.spark.sql.SparkSession import org.apache.spark.streaming.dstream.{DStream, ReceiverInputDStream} import org.apache.spark.streaming.{Durations, StreamingContext} object Demo02updateStateByKey { def main(args: Array[String]): Unit = { val spark: SparkSession = SparkSession .builder() .appName("Demo02updateStateByKey") .master("local[2]") .getOrCreate() val ssc: StreamingContext = new StreamingContext(spark.sparkContext, Durations.seconds(5)) ssc.checkpoint("bigdata19-spark/data/ssc/ck1") //通过Socket的方式模拟消息队列 val lineDS: DStream[String] = ssc.socketTextStream("master", 8888) val wordKVDS: DStream[(String, Int)] = lineDS .flatMap(_.split(",")) .map(word => (word, 1)) /** * updateStateByKey有状态算子: * 需要接受一个函数f * 函数f:总共有两个参数,类型分别是Seq和Option,返回值类型是Option * 不仅可以计算当前批次的结果,还可以结合上一次的结果,并对两次结果进行汇总 * 在使用有状态时需要设置Checkpoint的目录 */ def updateStateFunc(seq:Seq[Int],opt:Option[Int]):Option[Int]={ /** * seq参数:保存某个批次的某个Key的所有的value * opt参数:保存上一次某个Key的状态 */ // 计算当前批次某个Key对应的Value之和 再加上之前的状态 返回新的状态 opt match { case Some(v)=> Some(seq.sum+v) case None=> Some(seq.sum) } } wordKVDS.updateStateByKey(updateStateFunc).print() //使用匿名函数简化 wordKVDS.updateStateByKey((seq:Seq[Int],opt:Option[Int])=>{ opt match { case Some(v)=> Some(seq.sum+v) case None=> Some(seq.sum) } }) ssc.start() ssc.awaitTermination() ssc.stop() } }