Streaming的重要算子

本文深入探讨了Apache Spark Streaming中的关键操作,包括Transform、UpdateStateByKey、ForeachRDD及Windows等,展示了如何通过这些操作处理实时流数据,实现数据聚合、状态更新、外部数据源保存及窗口计算等功能。

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

Transform

transform操作,应用在DStream上时,可以用于执行任意的RDD到RDD的转换操作。它可以用于实现,DStream API中所没有提供的操作。比如说,DStream API中,并没有提供将一个DStream中的每个batch,与一个特定的RDD进行join的操作。但是我们自己就可以使用transform操作来实现该功能,返回值还是Dstream。

package com.ruozedata.bigdata.streaming03

import org.apache.spark.SparkConf
import org.apache.spark.streaming.{Seconds, StreamingContext}

import scala.collection.mutable.ListBuffer

object TransformApp {
  def main(args: Array[String]): Unit = {
    val conf=new SparkConf().setMaster("local[2]").setAppName("TransformApp")
    val ssc = new StreamingContext(conf,Seconds(10))

    val blackTuple=new ListBuffer[(String,Boolean)]
    blackTuple.append(("doudou",true))
    blackTuple.append(("huahua",true))
    val blacksRDD=ssc.sparkContext.parallelize(blackTuple)


    val lines=ssc.socketTextStream("hadoop000",9999)
    //xx,xx info => (xx,(xx,xx info))
    //返回Dstream
    lines.map(x=>(x.split(",")(0),x)).transform(rdd=>{
      rdd.leftOuterJoin(blacksRDD).filter(x=>{
        x._2._2.getOrElse(false) !=true
      }).map(_._2._1)
    }).print()


    ssc.start()
    ssc.awaitTermination()
  }
}

UpdateStateByKey

相当于对不同批次的累加和更新,可以下一批次把之前批次的数据都参与计算。需要开启checkpoint记录批次数据。

package com.ruozedata.bigdata.streaming03

import org.apache.spark.SparkConf
import org.apache.spark.streaming.{Seconds, StreamingContext}


import scala.collection.mutable.ListBuffer

object UpdateStateByKeyApp {
  def main(args: Array[String]): Unit = {
    val conf=new SparkConf().setMaster("local[2]").setAppName("UpdateStateByKeyApp")
    val ssc = new StreamingContext(conf,Seconds(10))

    //记录以前批次的,指定到当前目录
    ssc.checkpoint("hdfs://hadoop000:9000/ss/logs")

    val lines=ssc.socketTextStream("hadoop000",9999)
    val results=lines.flatMap(_.split(",")).map((_,1))

    val state = results.updateStateByKey(updateFunction)
    state.print()

    ssc.start()
    ssc.awaitTermination()
  }

  def updateFunction(currentValues:Seq[Int],preValues:Option[Int]):Option[Int] = {
    val curr = currentValues.sum
    val pre = preValues.getOrElse(0)

    Some(curr + pre)
  }

}

ForeachRDDApp

保存Dstream的所有rdd的数据到外部数据源。
流数据主要是存放在外部数据源上,而不是hadoop上。


package com.ruozedata.bigdata.streaming03

import java.sql.DriverManager

import org.apache.spark.SparkConf
import org.apache.spark.streaming.{Seconds, StreamingContext}

object ForeachRDDApp {
  def main(args: Array[String]): Unit = {
    val conf = new SparkConf().setMaster("local[2]").setAppName("ForeachRDDApp")
    val ssc = new StreamingContext(conf,Seconds(10))


    val lines=ssc.socketTextStream("hadoop000",9999)
    val results=lines.flatMap(_.split(",")).map((_,1)).reduceByKey(_+_)

    //(ruoze,2)(jepson,1)
    results.foreachRDD(rdd =>{
      rdd.foreachPartition(partition=>{
        val connection = createConnection()

        partition.foreach(pair=>{
                  val sql=s"insert into wc(word,count) values('${pair._1}',${pair._2})"
                  connection.createStatement().execute(sql)
                  connection.close()
        })
      })


//      rdd.foreach(pair =>{
//        //connection必须在worker端创建,但是会导致每条rdd都会创建一次,所以应当用foreachpartition
//        val connection = createConnection()
//        val sql=s"insert into wc(word,count) values('${pair._1}',${pair._2})"
//        connection.createStatement().execute(sql)
//        connection.close()
//      })
    })

    ssc.start()
    ssc.awaitTermination()
  }

  def createConnection() ={
    Class.forName("com.mysql.jdbc.Driver")
    DriverManager.getConnection("jdbc:mysql://hadoop000:3306/g5_spark","root","123456")
  }
}

WindowsApp

实现一阶段内的累加 ,而不是程序启动时
假设每隔5s 1个batch,上图中窗口长度为15s,窗口滑动间隔10s。窗口长度和滑动间隔必须是batchInterval的整数倍。如果不是整数倍会检测报错。
在这里插入图片描述

package com.ruozedata.bigdata.streaming03

import org.apache.spark.SparkConf
import org.apache.spark.streaming.{Seconds, StreamingContext}

object WindowsApp {
  def main(args: Array[String]): Unit = {
    val conf = new SparkConf().setMaster("local[2]").setAppName("WindowsApp")
    val ssc = new StreamingContext(conf,Seconds(5))

    val lines = ssc.socketTextStream("hadoop000",9999)
    lines.flatMap(_.split(",")).map((_,1)).reduceByKeyAndWindow((a:Int,b:Int)=>(a+b),Seconds(10),Seconds(5)).print()

    ssc.start()
    ssc.awaitTermination()
  }
}
<dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.27</version>
    </dependency>

http://blog.51cto.com/xpleaf/2115343?source=dra

### SDF算子的定义与用途 #### 简介 SDF(Streaming Dataflow)是一种用于描述数据流图模型的抽象概念,在分布式计算框架中广泛使用。它主要用于表示和执行基于事件驱动的数据处理流程[^2]。 #### 定义 SDF算子通常指代 **Stream Dataflow Operator**,它是 Streaming 数据处理中的基本构建单元之一。每一个 SDF 算子代表了一个特定的操作逻辑,例如过滤、映射、聚合等操作。这些算子通过连接形成一个有向无环图 (DAG),从而实现复杂的数据流水线处理[^3]。 在 IT 领域中,SDF 的核心特性在于其能够动态调整资源分配并支持低延迟实时处理的能力。这种设计使得 SDF 成为了现代大数据平台的重要组成部分,尤其是在 Apache Beam 和 Flink 这样的流式处理引擎中得到了广泛应用[^4]。 #### 主要用途 以下是 SDF 算子的主要用途: 1. **数据转换**: 使用诸如 `map` 或者 `flatmap` 等函数来对输入记录应用自定义变换规则。这允许开发者轻松地修改字段或者生成新的结构化对象作为输出[^5]。 2. **窗口操作**: 当涉及到时间序列分析时,可以通过设置固定大小的时间窗或将多个连续到达的消息组合在一起进行批量运算[^6]。 3. **状态管理**: 对于某些需要记住历史上下文的应用场景来说,比如会话跟踪或者是异常检测,则可以利用内置的状态存储机制保存中间结果以便后续访问[^7]。 4. **容错保障**: 基于 checkpointing 技术,即使发生节点失败也能快速恢复到最近的一致点继续运行而不会丢失任何已提交的工作成果[^8]。 下面展示了一段简单的 Java 代码片段演示如何创建一个 map 类型的 SDF 算子: ```java import org.apache.flink.api.common.functions.MapFunction; import org.apache.flink.streaming.api.datastream.DataStream; // Assuming we have a stream of integers. DataStream<Integer> inputStream = ... ; // Define an SDF operator that squares each element in the input sequence. DataStream<Integer> squaredStream = inputStream.map(new MapFunction<Integer, Integer>() { @Override public Integer map(Integer value) throws Exception { return value * value; // Square operation applied here. } }); ``` 此示例展示了怎样将原始整数集合转化为它们各自的平方值形式的新集合作为下游消费者进一步消费的目标源材料[^9]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值