spark streaming的业务场景(无状态、有状态、窗口操作)

本文详细介绍了Spark Streaming支持的业务场景,包括无状态操作(如map、filter)、有状态操作(如updateStateByKey、mapWithState)及其应用场景,并重点讨论了窗口操作,如window、countByWindow等,展示了如何利用这些操作进行实时数据处理和统计分析,如热点搜索词的滑动统计。此外,还提到了Transform操作在DStream中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

spark streaming支持的业务场景:

1、无状态操作:

每个批次处理都不依赖于先前批次的数据,只关注当前的DStream中的实时数据,例如 只对当前的DStream中的数据做正确性校验。

每个DStream在内部是由许多个RDD(也叫批次)组成,且无状态转化操作是分别应用到每个RDD上的。

无状态转化操作的例子map、filter等等,操作都是每个批次中的数据,但是DStream如果使用join,union等基于健的操作的话,那么所传的RDD就必须同样也是DStream才行。

SparkStreaming中无状态操作的算子:

Map
filter 
flatMap
repartition 
reduceByKey 
groupByKey

2、有状态操作:

依赖之前的批次数据或者中间结果来计算当前批次的数据
状态管理函数:

  • updateStateByKey
  • mapWithState

Spark Streaming中状态管理函数包括updateStateByKey和mapWithState,都是用来统计全局key的状态的变化的。它们以DStream中的数据进行按key做reduce操作,然后对各个批次的数据进行累加,在有新的数据信息进入或更新时。能够让用户保持想要的不论任何状状。

1)UpdateStateByKey

概念:
会统计全局的key的状态,不管有没有数据输入,它会在每一个批次间隔返回之前的key的状态。会对已存在的key进行state的状态更新,同时还会对每个新出现的key执行相同的更新函数操作。如果通过更新函数对state更新后返回回来为none,此时key对应的state状态会被删除(state可以是任意类型的数据的结构).

updateStateByKey()的结果会是一个新的DStream,其内部的RDD序列是由每个时间区间对应的(键,状态)对组成的。updateStateByKey操作使得我们可以在用新信息进行更新时保持任意的状态。

条件:
定义状态,状态可以是一个任意的数据类型。
定义状态更新函数,用此函数阐明如何使用之前的状态和来自输入流的新值对状态进行更新。
使用updateStateByKey需要对检查点目录进行配置,会使用检查点来保存状态

适用场景:
updateStateByKey可以用来统计历史数据,每次输出所有的key值。例如统计不同时间段用户平均消费金额,消费次数,消费总额,网站的不同时间段的访问量等指标.

代码:

package com.atguigu.bigdata.spark.streaming
import org.apache.spark.SparkConf
import org.apache.spark.streaming.dstream.{DStream, ReceiverInputDStream}
import org.apache.spark.streaming.kafka.KafkaUtils
import org.apache.spark.streaming.{Seconds, StreamingContext}
 
// 有状态数据统计
object SparkStreaming_UpdateState {
 
    def main(args: Array[String]): Unit = {
 
        // 使用SparkStreaming完成WordCount
 
        // Spark配置对象
        val sparkConf = new SparkConf().setMaster("local[*]").setAppName("SparkStreaming01_WordCount")
 
        // 实时数据分析环境对象
        // 采集周期:以指定的时间为周期采集实时数据
        val streamingContext = new StreamingContext(sparkConf, Seconds(5))
 
        // 保存数据的状态,需要设定检查点路径
        streamingContext.sparkContext.setCheckpointDir("cp")
 
        // 从Kafka中采集数据
        //streamingContext.receiverStream(new MyReceiver("linux1", 9999))
        val kafkaDStream: ReceiverInputDStream[(String, String)] = KafkaUtils.createStream(
            streamingContext,
            "linux1:2181",
            "atguigu",
            Map("atguigu" -> 3)
        )
 
        // 将采集的数据进行分解(扁平化)
        val wordDStream: DStream[String] = kafkaDStream.flatMap(t=>t._2.split(" "))
 
        // 将数据进行结构的转换方便统计分析
        val mapDStream: DStream[(String, Int)] = wordDStream.map((_, 1))
 
        // 将转换结构后的数据进行聚合处理
        val wordToSumDStream: DStream[(String, Int)] = mapDStream.reduceByKey(_+_)
        /*
        val stateDStream: DStream[(String, Int)] = mapDStream.updateStateByKey {
            case (seq, buffer) => {
                val sum = buffer.getOrElse(0) + seq.sum
                Option(sum)
            }
        }
        */
        //value
 
        // 将结果打印出来
        wordToSumDStream.print()
 
        // 不能停止采集程序</
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值