wqy1027

eeee

 

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()

  }

}

 

posted on 2022-10-30 21:37  不想写代码的小玉  阅读(22)  评论(0编辑  收藏  举报

导航