Spark Streaming相关内容

一、 Spark Streaming的概念

Spark Streaming是专门用来处理实时数据的计算框架,而Spark Streaming处理实时数据主要借助于一个核心数据抽象DStream,DStream本质上是由时间片段组成的一个离散化流式数据

Spark Streaming的程序执行入口为StreamingContext

二、 Spark Streaming的创建

1、 创建方式

  • 借助SparkConf对象创建 — 默认底层自动创建一个SparkContext
  • 借助已经创建好的SparkContext对象来创建
object Demo01 {
  def main(args: Array[String]): Unit = {
    /**
     * 1、 从sparkConf创建  这种创建方式底层会给我们自动创建一个sparkContext
     * 需要传递两个值   sparkconf以及一个Durations时间
     *                              seconds(long)
     *                              milliseconds(long)
     *                              minutes(long)
     */
    val sparkConf = new SparkConf().setMaster("local").setAppName("demo01")
    val context = new StreamingContext(sparkConf, Seconds(5))

    /**
     * 2、 自己手动创建SparkContext  同样也需要传入两个值,一个sparkconf  一个时间
     */
    val sparkContext = new SparkContext(sparkConf)
    val streamingContext = new StreamingContext(sparkContext, Seconds(5))
  }
}

2、 注意

1、 Spark Streaming严格意义上属于准实时框架,因为Spark Streaming处理数据时是按照时间来封装一批数据来进行处理,按照固定的时间来处理一批批数据,而这个时间取决于StreamingContext中设定的时间

2、 创建StreamingContext时必须指定运行模式的CPU核数大于等于二,因为它在计算时,最少需要两个线程,一个用来接收数据源的数据,一个用来处理封装好的一批次的数据

3、 在源数据启动后,不能够在源数据中添加任何操作

3、 StreamingContext支持的数据源

  • TCP网络端口(Socket)
object Demo02 {
  def main(args: Array[String]): Unit = {
    /**
     * 读取网络端口数据
     */
    val sparkConf = new SparkConf().setAppName("socket").setMaster("local[2]")
    val context = new StreamingContext(sparkConf, Seconds(5))

    /**
     * 读取网络端口的数据成为Dstream
     */
    val dstream = context.socketTextStream("node1", 44444, StorageLevel.MEMORY_ONLY)
    dstream.print()

    /**
     * 实时计算的程序必须手动启动
     */
    context.start()
    context.awaitTermination()

  }
}
  • HDFS分布式文件系统
    注意:如果在目录下有历史数据,这些数据不会参与运算
object Demo04 {
  def main(args: Array[String]): Unit = {
    val conf = new SparkConf().setAppName("demo04").setMaster("local[2]")
    val context = new StreamingContext(conf, Seconds(20))

    val ds = context.textFileStream("hdfs://node1:9000/stream")
    ds.print()

    context.start()
    context.awaitTermination()
  }
}
  • 整合Flume实现实时计算
    1、 推送式:将Flume采集的数据主动推送给Spark程序,这样的话容易导致Spark程序接受数据出问题,推送式整合是基于avro端口下沉底方式完成
    2、拉取式:将Flume采集的数据发送给sink了,sink并不是直接把数据立马给了Spark,而是先把数据缓冲,Spark接收器可以按照我的需求主动去sink中拉取数据,拉取式整合方式是基于Spark下沉地完成----建议大家使用
object Demo05 {
  def main(args: Array[String]): Unit = {
    val conf = new SparkConf().setAppName("demo05").setMaster("local[2]")
    val context = new StreamingContext(conf, Seconds(20))


    val ds:DStream[SparkFlumeEvent] = FlumeUtils.createStream(context, "node1", 8888, StorageLevel.MEMORY_ONLY)
    ds.print()

    context.start()
    context.awaitTermination()
  }
}
  • 整合Kafka实现实时计算

4、 相关算子操作

1、 转换算子

  • RDD支持的转换算子,DStream大部分支持
  • 特殊转换算子 —transform(允许我们对DStream中的RDD直接操作)
object Demo07 {
  def main(args: Array[String]): Unit = {
    val conf = new SparkConf().setAppName("demo07").setMaster("local[2]")
    val context = new StreamingContext(conf, Seconds(20))

    val ds = context.socketTextStream("node1", 44444, StorageLevel.MEMORY_ONLY)

    val rdd = ds.transform((rdd: RDD[String]) => {
      val value = rdd.flatMap(_.split(" ")).map((_, 1)).reduceByKey(_ + _)
      value
    })
    rdd.print()

    context.start()
    context.awaitTermination()
  }
}
  • 有状态的转换算子updateStateByKey
object Demo08 {
  def main(args: Array[String]): Unit = {
    val conf = new SparkConf().setAppName("demo07").setMaster("local[2]")
    val context = new StreamingContext(conf, Seconds(20))
    //可以缓存中间计算结果的DStream,用来存储有状态算子的批次结果
    context.checkpoint("hdfs://node1:9000/sparkstreaming")

    val ds = context.socketTextStream("node1", 44444, StorageLevel.MEMORY_ONLY)
    val rdd = ds.transform((rdd: RDD[String]) => {
      val value = rdd.flatMap(_.split(" ")).map((_, 1)).reduceByKey(_ + _)
      value
    })

    /**
     * array:Seq[Int] 当前批次中相同key对应的value结果
     * stat:Option[Int]  以前批次相同key对应的value结果
     */
    val value = rdd.updateStateByKey((array: Seq[Int], stat: Option[Int]) => {
      //以前积攒的状态值
      var i = stat.getOrElse(0)
      for (elem <- array) {
        i += elem
      }
      Option(i)
    })
  }
}
  • 窗口函数 window
countByWindow 对每个滑动窗口的数据执行count操作
reduceByWindow 对每个滑动窗口的数据执行reduce操作
reduceByKeyAndWindow 对每个滑动窗口的数据执行reduceByKey操作
countByValueAndWindow 对每个滑动窗口的数据执行countByValue操作

同时需要传入两个参数
windowDuration: Duration,  窗口时间长度--一般是batchSize(批次时间)的整数倍
slideDuration: Duration:  滑动时间长度----一般是batchSize(批次时间)的整数倍

2、 行动算子

  • print(num) 显示DStream当前批次的前num条数据,如果num没有传递,那默认显示前十条
  • saveAsTextFile(用来保存数据的)
  • saveAsObjectFile(同样用来保存数据的)
  • foreachRDD算子:我们可以在foreachRDD算子中,实现对DStream每一批次RDD数据保存操作,保存到数据库、保存到结构化文件中等等,通过还可以在foreachRDD算子中将RDD转换为DataFrame或者Dataset实现结构化数据SQL处理操作
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值