Spark Streaming

Spark Streaming

Spark Streaming 概述

Spark Streaming 是什么

Spark Streaming 使得构建可扩展的容错流应用程序变得更加容易
Spark Streaming 无法实现真正的流式数据处理。使用了微批次数据处理。
Spark Streaming 是一个准实时数据处理引擎。

  • 实时:数据处理的延迟在毫秒级进行响应

  • 离线:数据处理的延迟在小时,天,月,年进行响应

  • 批处理:数据处理的方式

  • 流式:数据处理的方式

Spark Streaming 支持的数据输入源很多,例如:Kafka,Flume,Twitter,ZeroMQ和简单的TCP Socket等等。
数据输入后,可以用Spark的高度抽象原语进行运算,如map,reduce,join,window。
结果也能保存在很多地方,如HDFS,数据库等。

在这里插入图片描述

和Spark基于RDD的概念很相似,Spark Streaming使用离散化流(discretized stream)作为抽象表示,叫做DStream。
DStream是随时间推移而收到的数据的序列。在内部,每个时间区间收到的数据都作为RDD存在,而DStream是由这些RDD所组成的序列(因此得名"散列化")。所以简单来讲,DStream就是对RDD在实时数据处理场景的一种封装。

Spark Streaming 架构

架构图
  • 整体架构图
    在这里插入图片描述

  • Spark Streaming 架构图
    在这里插入图片描述

背压机制

Spark 1.5以前版本,用户如果要限制Receiver的数据接收速率,可以通过设置静态配制参数“spark.streaming.receiver.maxRate”的值来实现,此举虽然可以通过限制接收速率,来适配当前的处理能力,防止内存溢出,但也会引入其它问题。比如:producer数据生产高于maxRate,当前集群处理能力也高于maxRate,这就会造成资源利用率下降等问题。

为了更好的协调数据接收速率与资源处理能力,1.5版本开始Spark Streaming可以动态控制数据接收速率来适配集群数据处理能力。背压机制(即Spark Streaming
Backpressure): 根据JobScheduler反馈作业的执行信息来动态调整Receiver数据接收率。

通过属性“spark.streaming.backpressure.enabled”来控制是否启用backpressure机制,默认值false,即不启用。

DStream 入门

WordCount案例实操

需求:使用netcat工具向9999端口不断的发送数据,通过SparkStreaming读取端口数据并统计不同单词出现的次数。

  • 添加依赖

  • 编写代码

  def main(args: Array[String]): Unit = {
    // 1.初始化Spark配置信息
    // SparkStreaming使用核数最少是两个:driver,receiver
    val conf: SparkConf = new SparkConf().setMaster("local[*]").setAppName("SparkStreaming WordCount")

    // 2.初始化SparkStreamingContext
    // conf: SparkConf, batchDuration: Duration - 采集周期
    val ssc = new StreamingContext(conf, Seconds(3))

    // 3.通过监控端口创建DStream,读进来的数据为一行行
    val lineStreams: ReceiverInputDStream[String] = ssc.socketTextStream("localhost", 9999)

    // 将每一行数据做切分,形成一个个单词
    val wordStreams: DStream[String] = lineStreams.flatMap(_.split(" "))

    // 将单词映射成元组(word, 1)
    val wordToOneStreams: DStream[(String, Int)] = wordStreams.map((_, 1))

    // 将相同的单词次数做统计
    val wordToCountStreams: DStream[(String, Int)] = wordToOneStreams.reduceByKey(_+_)

    // 打印
    wordToCountStreams.print()

    // 启动SparkStreamingContext
    ssc.start() // 启动采集器
    ssc.awaitTermination() // 等待采集器的结束
  }
  • 启动程序并通过netcat发送数据
E:\DeveloperTools\netcat-win32-1.12>nc -lp 9999
dsy sarah dongsaiyuan
hello word

-------------------------------------------
Time: 1592056995000 ms
-------------------------------------------
(dongsaiyuan,1)
(dsy,1)
(sarah,1)

-------------------------------------------
Time: 1592056998000 ms
-------------------------------------------
(word,1)
(hello,1)

WordCount 解析

Discretized Stream 是 Spark Streaming 的基础抽象,代表持续性的数据流和经过各种Spark原语操作后的结果数据流。在内部实现上,DStream是一系列连续的RDD来表示。每个RDD含有一段时间间隔内的数据。
在这里插入图片描述

对数据的操作也是按照RDD为单位来进行的
在这里插入图片描述

计算过程由 Spark Engine 来完成
在这里插入图片描述

DStream 创建

RDD 队列

用法及说明

测试过程中,可以通过使用ssc.queueStream(queueOfRDDs)来创建DStream。

案例实操
  • 需求:循环创建几个RDD,将RDD放入队列。通过Spark Streaming创建DStream,计算WordCount。
  def main(args: Array[String]): Unit = {
    // 1.初始化 Spark 配置信息
    val conf: SparkConf = new SparkConf().setMaster("local[*]").setAppName("RDD Stream")

    // 2.初始化 SparkStreamingContext
    val ssc = new StreamingContext(conf, Seconds(3))

    // 3.创建 RDD 队列
    val rddQueue = new mutable.Queue[RDD[Int]]()

    // 4.创建 QueueInputDStream
    val inputStream: InputDStream[Int] = ssc.queueStream(rddQueue, oneAtATime = false)

    // 5.处理队列中的 RDD 数据
    val mappedStream: DStream[(Int, Int)] = inputStream.map((_, 1))
    val reducedStream: DStream[(Int, Int)] = mappedStream.reduceByKey(_+_)

    // 6.打印结果
    reducedStream.print()

    // 7.启动任务
    ssc.start()

    // 8.循环创建并向 RDD 队列中放入 RDD
    for(i <- 1 to 5) {
      rddQueue += ssc.sparkContext.makeRDD(List(i))
      Thread.sleep(1000)
    }

    ssc.awaitTermination()
  }
-------------------------------------------
Time: 1592094957000 ms
-------------------------------------------
(1,1)
(2,1)
(3,1)

-------------------------------------------
Time: 1592094960000 ms
-------------------------------------------
(4,1)
(5,1)

自定义数据源

用法及说明

需要继承 Receiver,并实现 onStart,onStop 方法来自定义数据源采集

案例实操

需求:自定义数据源,实现监控某个端口号,获取该端口号内容

  def main(args: Array[String]): Unit = {
    // 1.初始化 Spark 配置信息
    val conf: SparkConf = new SparkConf().setMaster("local[*]").setAppName("custom receiver")

    // 2.初始化 SparkStreamingContext
    val ssc = new StreamingContext(conf, Seconds(3))

    // 3.创建自定义 receiver 的 Streaming
    val lineStream: ReceiverInputDStream[String] = ssc.receiverStream(new CustomReceiver("localhost", 9999))

    /
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值