文章目录

  • 前言:
    • 什么是Spark Streaming
    • SparkStreaming的原理介绍
    • SparkStreaming的优点
    • SparkStreaming获取kafka数据有两种方式
    • DStream的概念
    • DataStream
      • DStream的Transformation(转换)
      • DStream的Output(输出)
    • SparkStreaming程序WordCount
      • 窗口操作案例实现
      • 窗口函数
    • SparkStreaming的背压机制
    • 反压(背压Back Pressure)机制
    • 流量控制
    • 令牌桶机制
    • Spark的maven依赖
    • Spark Streaming与Storm对比

前言:

十年生死两茫茫,千行代码,Bug何处藏。
纵使产品经理祭苍天,又怎样?
朝令改,夕断肠。
相顾无言,惟有泪千行。
每晚灯火阑珊处,夜难寐,加班狂

什么是Spark Streaming

Spark Streaming类似于Apache Storm,用于流式数据的处理。

根据其官方文档介绍,SparkStreaming有高吞吐量和容错能力强等特点。Spark Streaming支持的数据输入源很多,例如:Kafka、Flume、Twitter、ZeroMQ和简单的TCP套接字等等。数据输入后可以用Spark的高度抽象原语如:map、reduce、join、window等进行运算。而结果也能保存在很多地方,如HDFS,数据库等。另外Spark Streaming也能和MLlib(机器学习)以及Graphx完美融合。

SparkStreaming的原理介绍

SparkStreaming使用的是"微批次"的架构,把流式计算当作一些列的小规模批次处理来对待,SparkStreaming从各种输入源中读取数据,并把数据分组为小的批次,新的批次按均匀的时间间隔创建出来.在每个时间区间开始的时候,一个新的批次就创建出来,在改区间内收到的数据都会被添加到这个批次中,在时间区间结束时,批次停止增长,时间区间的大小是由批次间隔参数决定此

批次间隔一般设置在500毫秒起到几秒之间,由开大人员来进行配置

ps:人类间隔批次可读时间5s

每个输入批次都会形成一个RDD以Spark作业的方式会处理并生成其他的RDD处理的结果可以以批次处理并发送和给外部存储系统

SparkStreaming的优点

  1. 易用
    SparkStreaming将ApacheSpark的语言集成API引入到流处理中,使您可以像编写批处理作业一样编写流式作业。它支持Java、Scala和Python。
  2. 容错
    Spark Streaming可以从盒子中恢复丢失的工作和操作员状态(如滑动窗口),而不需要任何额外的代码。
  3. 易整合到spark体系
    ps: SparkStreming可以保证每条数据只会被处理一次
    通过在Spark上运行,Spark流允许您重用相同的代码进行批处理、根据历史数据连接流,或者对流状态运行即席查询。构建强大的交互式应用程序,而不仅仅是分析。

SparkStreaming获取kafka数据有两种方式

Receiver(接收器)

Receiver方式是通过zookeeper来维护偏移量的,Kafka的topic分区和Spark Streaming中生成的RDD分区没有关系。在KafkaUtils.createStream中增加分区数量只会增加单个receiver的线程数,不会增加Spark的并行度。可以创建多个的Kafka节点输入DStream,使用不同的group和topic,使用多个receiver并行接收数据。

Direct(直连)

简化的并行性:不需要创建多个流输入Kafka并将其合并。 使用directStream,Spark Streaming将创建与使用Kafka分区一样多的RDD分区,这些分区将全部从Kafka并行读取数据。 所以在Kafka和RDD分区之间有一对一的映射关系。

效率:
在第一种方法中实现零数据丢失需要将数据存储在预写日志中,这会进一步复制数据。这实际上是效率低下的,因为数据被有效地复制了两次 一次是Kafka,另一次是由预先写入日志(Write Ahead Log)复制。

第二种方法消除了这个问题,因为没有接收器,因此不需要预先写入日志。

SparkCore中提供一个概念叫做RDD来用存储和处理数据
SparkSQL中提供一个概念叫做DataFrame和DataSet用来存储和处理数据
SparkStreaming中提供了一个叫做DStream用存储和处理数据

DStream的概念

SparkCore中提供一个概念叫做RDD来用存储和处理数据
SparkSQL中提供一个概念叫做DataFrame和DataSet用来存储和处理数据
SparkStreaming中提供了一个叫做DStream用存储和处理数据

SparkStreaming使用离散化流(discretized Stream)作为抽象表示,作为SparkStreaming中存储数据的抽象,和Spark中RDD有着类似概念,DStream是随着时间他推移而可以得到不同数据序列,在其内部,每个时间区间接收到的数据都作为RDD存在,而DStream是由这个些RDD所组成的(因为此得名"离散化流")

DataStream

DStream的Transformation(转换)

DStream的Output(输出)

SparkStreaming程序WordCount

package SparkStreaming_01
import org.apache.spark.streaming.dstream.ReceiverInputDStream
import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.streaming.{Seconds, StreamingContext}
/*
写SparkStreaming程序的时候不能使用local作为本地程序开启模式,原因在于它需要使用一个线程进行
接收
还需要一个线程进行任务执行,所以不能使用local单线程模式
我们开启SparkStreaming执行的时候需要使用 local[值]形式 或 local[*]形式
*/
object SparkStreamingWC {
def main(args: Array[String]): Unit = {
//创建SparkStreaming对象
//1.需要创建SparkConf
val conf = new
SparkConf().setAppName("SparkStreamingWC").setMaster("local[*]")
//2.创建SparkStreaming对象 第一个参数是conf配置,第二个参数批次间隔
val ssc = new StreamingContext(conf,Seconds(5))
//第二种. 使用SparkContext对象
// val sc = new SparkContext(conf)
// val ssc1 = new StreamingContext(sc,Seconds(5))
//获取实时数据, 从netcat服务器中获取数据
//第一个参数是节点名称(没有配置hosts就需要些IP地址),第二个参数是端口号从什么端口获取数据
val dStream: ReceiverInputDStream[String] =
ssc.socketTextStream("hadoop01",6666)
//处理DStream和RDD处理是没有什么区别的
//但是需要注意含义不用当前这里调用算子的时候返回的是一个DStream
val sumed = dStream.flatMap(_.split(" ")).map((_,1)).reduceByKey(_+_)
//将结果打到控制台上
sumed.print()
//开启任务(将任务提交到集群)
ssc.start()
//等待任务,处理下一个批次(线程等待)
ssc.awaitTermination()
}
}

无状态转换

操作就是把简单的RDD转换为操作应用在每个批次上,也就是将DStream中每一个RDD进行转换,转换过程中所产生的数据结果,不会影响下一个批次中的数据进行计算,批次和批次之间不会产生影响

有状态转换

批次数据计算的结果会直接影响下一个批次的计算结果,因为使用是实时流,数据是不断输入的,所以需要计算上一个批次和当前批次的结果,那么就需要将上一个批次的计算结果进行保存,保存数据无非就是两种
1.保存在内存中
2.保存在磁盘中(磁盘)

窗口操作案例实现


SparkStreaming中也提供了这样的操作叫做Window Operations

Window Operations可以设置窗口的大小和滑动窗口的间隔来动态的获取当前Steaming的允许状态。基于窗口的操作会在一个比StreamingContext的批次间隔更长的时间范围内,通过整合多个批次的结果,计算出整个窗口的结果。

窗口函数

SparkStreaming的背压机制

在默认情况下,Spark Streaming 通过 receivers (或者是 Direct(直连) 方式) 以生产者生产数据的速率接收数据。当 batch processing time > batch interval 的时候,也就是每个批次数据处理的时间要比Spark Streaming 批处理间隔时间长;越来越多的数据被接收,但是数据的处理速度没有跟上,导致系统开始出现数据堆积,可能进一步导致 Executor 端出现 OOM 问题而出现失败的情况。

而在 Spark 1.5 版本之前,为了解决这个问题,对于 Receiver-based 数据接收器,我们可以通过配置spark.streaming.receiver.maxRate 参数来限制每个 receiver 每秒最大可以接收的记录的数据;对于Direct Approach 的数据接收,我们可以通过置spark.streaming.kafka.maxRatePerPartition 参数来限制每次作业中每个 Kafka 分区最多读取的记录条数。这种方法虽然可以通过限制接收速率,来适配当前的处理能力,但这种方式存在以下几个问题:

  1. 我们需要事先估计好集群的处理速度以及消息数据的产生速度;
  2. 这两种方式需要人工参与,修改完相关参数之后,我们需要手动重启 Spark Streaming 应用程序;

如果当前集群的处理能力高于我们配置的 maxRate,而且 producer 产生的数据高于 maxRate,这会导致集群资源利用率低下,而且也会导致数据不能够及时处理。

反压(背压Back Pressure)机制

那么有没有可能不需要人工干预,Spark Streaming 系统自动处理这些问题呢?

当然有了!Spark 1.5引入了反压(Back Pressure)机制,其通过动态收集系统的一些数据来自动地适配集群数据处理能力。

流量控制

当Receiver开始接收数据时,会通过supervisor.pushSingle()方法将接收的数据存入currentBuffer等待BlockGenerator定时将数据取走,包装成block. 在将数据存放入currentBuffer之时,要获取许可(令牌)。如果获取到许可就可以将数据存入buffer, 否则将被阻塞,进而阻塞Receiver从数据源拉取数据。

ReceiverRateController来不断的计算RDD的处理速度和RDD的生成速度
这里的核心就是它,是自动完成的其令牌投放采用令牌桶机制进行, 原理如下图所示:

令牌桶机制

大小固定的令牌桶可自行以恒定的速率源源不断地产生令牌。如果令牌不被消耗,或者被消耗的速度小于产生的速度,令牌就会不断地增多,直到把桶填满。后面再产生的令牌就会从桶中溢出。最后桶中可以保存的最大令牌数永远不会超过桶的大小。当进行某操作时需要令牌时会从令牌桶中取出相应的令牌数,如果获取到则继续操作,否则阻塞。用完之后不用放回。

Spark的maven依赖

    <properties><spark.version>2.2.0</spark.version><scala.version>2.11</scala.version><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.apache.spark</groupId><artifactId>spark-core_${scala.version}</artifactId><version>${spark.version}</version></dependency><dependency><groupId>org.apache.spark</groupId><artifactId>spark-sql_${scala.version}</artifactId><version>${spark.version}</version></dependency><dependency><groupId>org.apache.spark</groupId><artifactId>spark-streaming_${scala.version}</artifactId><version>${spark.version}</version></dependency><dependency><groupId>org.apache.spark</groupId><artifactId>spark-yarn_${scala.version}</artifactId><version>${spark.version}</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.16</version></dependency></dependencies>

Spark Streaming与Storm对比



对于Storm来说:

  1. 建议在那种需要纯实时,不能忍受1秒以上延迟的场景下使用,比如实时金融系统,要求纯实时进行金融交易和分析
  2. 此外,如果对于实时计算的功能中,要求可靠的事务机制和可靠性机制,即数据的处理完全精准,一条也不能多,一条也不能少,也可以考虑使用Storm
  3. 如果还需要针对高峰低峰时间段,动态调整实时计算程序的并行度,以最大限度利用集群资源(通常是在小型公司,集群资源紧张的情况),也可以考虑用Storm
  4. 如果一个大数据应用系统,它就是纯粹的实时计算,不需要在中间执行SQL交互式查询、复杂的transformation算子等,那么用Storm是比较好的选择对于

Spark Streaming来说:

  1. 如果对上述适用于Storm的三点,一条都不满足的实时场景,即,不要求纯实时,不要求强大可靠的事务机制,不要求动态调整并行度,那么可以考虑使用SparkStreaming
  2. 考虑使用Spark Streaming最主要的一个因素,应该是针对整个项目进行宏观的考虑,即,如果一个项目除了实时计算之外,还包括了离线批处理、交互式查询等业务功能,而且实时计算中,可能还会牵扯到高延迟批处理、交互式查询等功能,那么就应该首选Spark生态,用Spark Core开发离线批处理,用Spark SQL开发交互式查询,用Spark Streaming开发实时计算,三者可以无缝整合,给系统提供非常高的可扩展性

有收获?希望烙铁们来个三连击,让更多的同学看到这篇文章

1、烙铁们,关注我看完保证有所收获,不信你打我。

2、点个赞呗,可以让更多的人看到这篇文章,后续还会有很哇塞的产出。

本文章仅供学习及个人复习使用,如需转载请标明转载出处,如有错漏欢迎指出
务必注明来源(注明: 来源:csdn , 作者:-马什么梅-)

SparkStreaming的原理介绍相关推荐

  1. HDR sensor 原理介绍

    HDR sensor 原理介绍 一. HDR sensor 原理介绍 什么是sensor的动态范围(dynamic range): sensor的动态范围就是sensor在一幅图像里能够同时体现高光和 ...

  2. java语言的实现机制_JAVA语言之Java NIO的工作机制和实现原理介绍

    本文主要向大家介绍了JAVA语言之Java NIO的工作机制和实现原理介绍,通过具体的内容向大家展示,希望对大家学习JAVA语言有所帮助. 前言 本文只简单介绍NIO的原理实现和基本工作流程 I/O和 ...

  3. 中兴SDH原理介绍及中兴E300网管介绍

    姓名 苟忠兴 培训课程 中兴SDH原理介绍及中兴E300网管介绍 培训心得 1. SDH概念: SDH(Synchronous Digital Hierarchy,同步数字体系)是一种将复接.线路传输 ...

  4. 【机器学习】多项式回归原理介绍

    [机器学习]多项式回归原理介绍 [机器学习]多项式回归python实现 [机器学习]多项式回归sklearn实现 在上一节中我们介绍了线性回归的原理,然后分别用python和sklearn实现了不同变 ...

  5. 计算机原理 英文版,计算机原理介绍英文版.doc

    计算机原理介绍英文版 Importing TrafficOverview This lesson demonstrates the traffic import capabilities of Mod ...

  6. heartbeat原理介绍

    heartbeat原理介绍 HeartBeat运行于备用主机上的Heartbeat可以通过以太网连接检测主服务器的运行状态,一旦其无法检测到主服务器的"心跳"则自动接管主服务器的资 ...

  7. 安检x光机原理计算机实现,安检x光机成像原理介绍

    安检x光机是我们都很熟悉的一种安检设备,但很少有人去了解安检x光机成像原理.本文将为大家介绍安检x光机成像原理. 安检x光机成像原理 安检x光机主要由X光管和X光机电源以及控制电路等组成,而X光管又由 ...

  8. php new对象 调用函数,关于JS中new调用函数的原理介绍

    这篇文章主要介绍了关于JS中new调用函数的原理介绍,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下 JavaScript 中经常使用构造函数创建对象(通过 new 操作符调用一个函数) ...

  9. Springboot中的缓存Cache和CacheManager原理介绍

    一.背景理解 什么是缓存,为什么要用缓存? 程序运行中,在内存保持一定时间不变的数据就是缓存.简单到写一个Map,里面放着一些key,value数据,就已经是个缓存了.所以缓存并不是什么高大上的技术, ...

最新文章

  1. 微博“异地多活”部署经验谈
  2. Java-开源工具类
  3. mybatis+spring报错PropertyAccessException 1
  4. [记录] --- safari浏览器对于yyyy-MM的坑
  5. 80386/386/Intel386 架构/流水线及其优化
  6. 移远EC600S-CN (4) - MQTT接入阿里云
  7. 安装geopandas库
  8. h, w = img.shape什么意思?
  9. 计算机专业综合理论模拟测试卷五,2020银保监会考试题库:计算机类模拟试题练习(五)...
  10. js用post传送数组给php格式转换
  11. 北航计算机学院 高小鹏,毕业季 | 以来自学院的深情祝福,定格属于你的最美青春(二)...
  12. Android开发 调用系统相机相册图片功能,解决小米手机拍照或者图片横竖相反问题,及小米手机相册图片路径问题
  13. XML HttpRequest
  14. 雨林木风 GHOST XP SP3 五一纯净版
  15. linux内核丢弃udp报文,内核udp报文截取、修改和发送
  16. ROWNUM 与 ROW_NUMBER()OVER() 的区别
  17. pytorch基础学习(四) 数据处理(一)
  18. Generative Adversarial Networks简介
  19. java操作Excel,mdb,dbf
  20. Cadence Allegro PCB中如何导出BOM

热门文章

  1. ubuntu qt使用搜狗输入法
  2. 第1章-为什么选择阿里云学生机
  3. 【Python网络蜘蛛 · 3】:post请求、模拟金山翻译(附源代码)
  4. 淘宝移动网络库全解析
  5. MYSQL的一知半解
  6. TP5.1 支付宝app支付 (沙箱本地测试)
  7. 2013年华北五省计算机应用大赛,我校学生在华北五省计算机应用大赛获得佳绩...
  8. 页面还未加载完成显示loading
  9. 大数据 勾勒中国人“的亲情地图”!
  10. 菜学C++ Day57 OJ题目1204 有趣的数字图形I