『DT_Spark』Spark定制班第1课:通过案例对Spark Streaming透彻理解三板斧之一:解密Spark Streaming另类实验及Spark Streaming本质解析

Spark定制班第1课:通过案例对Spark Streaming透彻理解三板斧之一:解密Spark Streaming另类实验及Spark Streaming本质解析 - andyshar的博客 - 博客频道 - CSDN.NET
http://blog.csdn.net/andyshar/article/details/51295030

从今天起,我们踏上了新的Spark学习旅途。我们的目标是要像Spark官方机构那样有能力去定制Spark。
我们最开始将从Spark Streaming入手。
为何从Spark Streaming切入Spark定制?Spark的子框架已有若干,为何选择Spark Streaming?让我们细细道来。
Spark最开始只有Spark Core,没有目前的这些子框架。这些子框架是构建于Spark Core之上的。没有哪个子框架能摆脱Spark Core。我们通过对一个框架的彻底研究,肯定可以领会Spark力量的源泉,并精通所有问题的解决之道。
我们再看看目前的这些子框架。Spark SQL有太多语法,研究这些会太浪费精力。SparkR还没完善。Spark GraphX已无太多可改进之处,图计算相关的数学知识也不是目前重点。Spark MLlib中的机器学习也有太多算法是与数学相关,也不是做改进的好的选择 。所以我们选择了Spark Streaming。
2015年是流式处理的一年。大家考虑用Spark,主要也是因为Spark Streaming。这是一个流处理的时代,一切数据如果与流式处理不相关的话,都是无效的数据。Spark之所以强悍的一个重要原因在于,它的流式处理可以在线使用图计算、机器学习或者SparkR的成果,这得益于Spark一体化、多元化的基础架构设计。也就是在Spark Streaming中可以调用其它子框架,无需任何设置。这是Spark的无可匹敌之处,也是Spark Streaming必将一统天下的根源。但Spark的应用中,Spark Streaming也是最容易出问题的。
Spark Streaming与其它子框架不同之处在于,它更像是Spark Core之上的一个应用程序。所以如果要做Spark的定制开发,Spark Streaming则提供了最好的参考。你想掌握Spark Streaming,但你不去精通Spark Core的话,那是不可能的。所以我们选择Spark Streaming来提升自己,是找到了关键点。如果对照风水学的说法,我们已经幸运地找到了龙脉。如果要寻龙点穴,那么Spark Streaming就是龙穴之所在。找到了穴位,我们就能一日千里。

本期内容
1 Spark Streaming另类在线实验
2 瞬间理解Spark Streaming本质

1 Spark Streaming另类在线实验
我们在研究Spark Streaming的过程中,会有困惑的事情:如何清晰的看到数据的流入、被处理的过程?
使用一个小技巧,通过调节放大Batch Interval的方式,来降低批处理次数,以方便看清楚各个环节。
我们从已写过的广告点击的在线黑名单过滤的Spark Streaming应用程序入手。
[plain] view plain copy 在CODE上查看代码片派生到我的代码片
package com.dt.spark.streaming

import org.apache.spark.SparkConf
import org.apache.spark.streaming.StreamingContext
import org.apache.spark.streaming.Seconds

object OnlineBlackListFilter {
def main(args: Array[String]){
/**
* 第1步:创建Spark的配置对象SparkConf,设置Spark程序的运行时的配置信息,
* 例如说通过setMaster来设置程序要链接的Spark集群的Master的URL,如果设置
* 为local,则代表Spark程序在本地运行,特别适合于机器配置条件非常差(例如
* 只有1G的内存)的初学者。
*/
// 创建SparkConf对象
val conf = new SparkConf()
// 设置应用程序的名称,在程序运行的监控界面可以看到名称
conf.setAppName("OnlineBlackListFilter")
// 此时,程序在Spark集群
conf.setMaster("spark://Master:7077")

  val ssc = new StreamingContext(conf, Seconds(30))  

  /**  
   * 黑名单数据准备,实际上黑名单一般都是动态的,例如在Redis或者数据库中,  
   * 黑名单的生成往往有复杂的业务逻辑,具体情况算法不同,  
   * 但是在Spark Streaming进行处理的时候每次都能够访问完整的信息。  
   */  
  val blackList = Array(("Spy", true),("Cheater", true))  
  val blackListRDD = ssc.sparkContext.parallelize(blackList, 8)  

  val adsClickStream = ssc.socketTextStream("Master", 9999)  

  /**  
   * 此处模拟的广告点击的每条数据的格式为:time、name  
   * 此处map操作的结果是name、(time,name)的格式  
   */  
  val adsClickStreamFormatted = adsClickStream.map { ads => (ads.split(" ")(1), ads) }  
  adsClickStreamFormatted.transform(userClickRDD => {  
    // 通过leftOuterJoin操作既保留了左侧用户广告点击内容的RDD的所有内容,  
    // 又获得了相应点击内容是否在黑名单中  
    val joinedBlackListRDD = userClickRDD.leftOuterJoin(blackListRDD)  

    /**  
     * 进行filter过滤的时候,其输入元素是一个Tuple:(name,((time,name), boolean))  
     * 其中第一个元素是黑名单的名称,第二元素的第二个元素是进行leftOuterJoin的时候是否存在的值。  
     * 如果存在的话,表明当前广告点击是黑名单,需要过滤掉,否则的话是有效点击内容;  
     */  
    val validClicked = joinedBlackListRDD.filter(joinedItem => {  
      if(joinedItem._2._2.getOrElse(false))  
      {  
        false  
      } else {  
        true  
      }  

    })  

    validClicked.map(validClick => {validClick._2._1})  
  }).print  

  /**  
   * 计算后的有效数据一般都会写入Kafka中,下游的计费系统会从kafka中pull到有效数据进行计费  
   */  
  ssc.start()  
  ssc.awaitTermination()  

}  

}
把程序的Batch Interval设置从30秒改成300秒:
val ssc = new StreamingContext(conf, Seconds(300))
重新生成一下jar包 。

   Spark集群有5台机器:Master、Worker1、Worker2、Worker3、Worker4。
   启动Spark的History Server。
   打开数据发送的端口:
   nc -lk 9999
   用spark-submit运行前面生成的jar包。

   在数据发送端口输入若干数据,比如:
   1375864674543 Tom
   1375864674553 Spy
   1375864674571 Andy
   1375864688436 Cheater
   1375864784240 Kelvin
   1375864853892 Steven
   1375864979347 John

   打开浏览器,看History Server的日志信息:


   点击最新的应用,看我们目前运行的应用程序中有些什么Job:

    总共竟然有5个Job。这完全不是我们此前做Spark SQL之类的应用程序时看到的样子。
   我们接下来看一看这些Job的内容,主要揭示一些现象,不会做完全深入的剖析,只是为了先让大家进行一些思考。

   Job 0:此Job不体现我们的业务逻辑代码。这个Job是出于对后面计算的负载均衡的考虑。

   Job 0包含有Stage 0、Stage 1。随便看一个Stage,比如Stage 1。看看其中的Aggregated Metrics by Executor部分:

   发现此Stage在所有Executor上都存在。

   Job 1:运行时间比较长,耗时1.5分钟。

   点击Stage 2的链接,进去看看Aggregated Metrics By Executor部分:

   可以知道,Stage 2只在Worker4上的一个Executor执行,而且执行了1.5分钟。
   是否会觉得奇怪:从业务处理的角度看,我们发送的那么一点数据,没有必要去启动一个运行1.5分钟的任务吧。那这个任务是做什么呢?
   从DAG Visualization部分,就知道此Job实际就是启动了一个接收数据的Receiver:

   原来Receiver是通过一个Job来启动的。那肯定有一个Action来触发它。
   看看Tasks部分:

   只有一个Worker运行此Job。是用于接收数据。
   Locality Level是PROCESS_LOCAL,原来是内存节点。所以,默认情况下,数据接收不会使用磁盘,而是直接使用内存中的数据。
   看来,Spark Streaming应用程序启动后,自己会启动一些Job。默认启动了一个Job来接收数据,为后续处理做准备。

   重要启示:一个Spark应用程序中可以启动很多Job,而这些不同的Job之间可以相互配合。这一认识为我们写复杂Spark程序奠定了良好的基础。

   Job 2:看Details可以发现有我们程序的主要业务逻辑,体现在Stage 3、Stage 4、Stage 5中。

   我们看Stage 3、Stage 4的详情,可以知道这2个Stage都是用4个Executor执行的。所有数据处理是在4台机器上进行的。

   Stage 5只在Worker4上。这是因为这个Stage有Shuffle操作。


    Job3:有Stage 6、Stage 7、Stage 8。其中Stage 6、Stage 7被跳过。

   看看Stage 8的Aggregated Metrics by Executor部分。可以看到,数据处理是在4台机器上进行的:


   Job4:也体现了我们应用程序中的业务逻辑 。有Stage 9、Stage 10、Stage 11。其中Stage 9、Stage 10被跳过。

   看看Stage 11的详情。可以看到,数据处理是在Worker2之外的其它3台机器上进行的:


   综合以上的现象可以知道,Spark Streaming的一个应用中,运行了这么多Job,远不是我们从网络博客或者书籍上看的那么简单。
   我们有必要通过这些现象,反过来回溯去寻根问源。不过这次暂不做深入分析。
   我们的神奇之旅才刚刚开始。

2 瞬间理解Spark Streaming本质

   以上的连续4个图,分别对应以下4个段落的描述:
   Spark Streaming接收Kafka、Flume、HDFS和Kinesis等各种来源的实时输入数据,进行处理后,处理结果保存在HDFS、Databases等各种地方。
   Spark Streaming接收这些实时输入数据流,会将它们按批次划分,然后交给Spark引擎处理,生成按照批次划分的结果流。
   Spark Streaming提供了表示连续数据流的、高度抽象的被称为离散流的DStream。DStream本质上表示RDD的序列。DStream中的每个RDD都包含来自一个时间间隔的数据。
   Spark Streaming除了使用数据源产生的数据流创建DStream,也可以在已有的DStream上使用一些操作来创建新的DStream。任何对DStream的操作都会转变为对底层RDD的操作。本图例子是对lines Dstream做了flatMap操作,生成words Dstream。

   在我们前面的实验中,每300秒会接收一批数据,基于这批数据会生成RDD,进而触发Job,执行处理。

   DStream是一个没有边界的集合,没有大小的限制。
   DStream代表了时空的概念。随着时间的推移,里面不断产生RDD。
   锁定到时间片后,就是空间的操作,也就是对本时间片的对应批次的数据的处理。

   下面用实例来讲解数据处理过程。
   从Spark Streaming程序转换为Spark执行的作业的过程中,使用了DStreamGraph。
   Spark Streaming程序中一般会有若干个对DStream的操作。DStreamGraph就是由这些操作的依赖关系构成。
   从程序到DStreamGraph的转换,如以下图例所示:

   本例中,从每个foreach开始,都会进行回溯。从后往前回溯这些操作之间的依赖关系,也就形成了DStreamGraph。
   执行从DStream到RDD的转换,也就形成了RDD Graph,如下图所示:


   空间维度确定之后,随着时间不断推进,会不断实例化RDD Graph,然后触发Job去执行处理。
   现在再去读官方的Spark Streaming的文档,就好理解多了。



   看来我们的学习,将从Spark Streaming的现象开始,深入到Spark Core和Spark Streaming的本质。
   正巧还在着手编写Spark Streaming源码剖析的书。有王家林这样的老师指引方向,这本书可以写得相当有料。

http://blog.csdn.net/sinat_25306771/article/details/51404910

主要内容:

  1.  Spark Streaming 另类在线实验
    
  2.  理解Spark Streaming本质
    

写在前面的话:
为什么我们要以SparkStreaming为切入点进行Spark的源码定制呢?
原因如下:
1从研究目的来看
在Spark创立之初,并没有现在我们常用的这些子框架,如Spark Streaming、Spark SQL、Spark R等内容,仅有原始的Spark core;而这些子框架是在Spark不断发展中加入到Spark大家庭的。我们采用的是与Spark core联系最紧密的Spark Streaming作为切入点,可以透过一个子框架的彻底研究,从而了解Spark的核心问题与解决办法

2各个框架的对比来说
现阶段,我们运行最多的是Sparkcore 以及其他的一些常用子框架。一下我们做了一些纵向对比。

框架

特点

备注

Spark SQL

基于Spark的快速的查询引擎

由于太多的SQL语句解析,会对我们研究的核心问题Spark运行到来不必要的干扰,不作为研究对象

Spark GraphX

基于Spark高效的图和图并行计算

近几个版本更新较少,难以体现最新的Spark发张方向,故不作为研究对象

Spark MLlib

封装了Vector与Matrix基础上结合RDD构建的机器学习库

由于其中涉及了许多算法,并不是我们研究Spark的重点,所以我们不研究这个框架。

Spark Streaming

面向流式处理的Spark子框架,与Spark core联系最紧密,最想Spark core上的一个应用程序

符合我们通过子框架达到透视Spark的要求。因此选择这个子框架作为我们研究的对象。

Spark Streaming是一个流式处理技术,而当前对于数据处理的要求基本上都要,数据都是流式数据且是实时在线处理的。而从我对大数据的初步印象来讲,也是关注与流式的数据即将大量数据流入到机器/处理器,并能立刻产生反馈的结果。此外Spark Streaming还可以利用Spark在图计算和机器学习以及Spark SQL、Spark R上获得成果,来进行实时在线数据处理。这要得益于在Spark技术堆栈中一体化结构的优势。这一优势带来的直接结果就是Spark Streaming在调用其他Spark 技术时,无需进行设置,直接调用。我们可以预想在未来Spark各个子框架协作,必将对业界产生巨大影响。从而Spark Streaming会成为未来的企业统一选择的技术。
3.从Spark Streaming与其他框架联系来看
在SparkStreaming的背后会与Spark其他子框架,有很大的关联性,我们在Spark Streaming中可以使用其他子框架,并进行整合,从而可以从中展现其他子框架的风貌,进而展现这个大数据技术的缩影。
4.Spark调试来看
在基于Spark框架的代码中,基于Spark Streaming的程序是最容易出现问题的,其根本原因在于数据是流动的,因此框架需要控制数据的流入、作业的划分、数据处理;考虑的方面多,相应的问题也变多,但是也最能体现编程者的能力,最吸引人。
5.从Spark Streaming的运行来说
它更像是在Sparkcore之上的一个应用程序,需考虑程序输入的数据是变化的和数据怎么处理两方面。
6.Spark Streaming的地位
可以说SparkStreaming是Spark框架中的一个关键点,要想成为高手,Spark Streaming是最能修炼Spark 内功的地方,也是提升我们的最佳的试炼场。
所以,我们以Spark Streaming作为切入点,来进行源码定制。
首先,我们进行一个实验:
这里我们有一个来自DT大数据梦工厂IMF课程的案例------在线过滤黑名单
源代码如下:

package com.dt.spark.Streamingimport org.apache.spark.streaming.{Seconds, StreamingContext}import org.apache.spark.{SparkContext, SparkConf}/** * 使用Scala开发集群运行的Spark 在线黑名单过滤程序 * @author DT大数据梦工厂 * 新浪微博:http://weibo.com/ilovepains/ * Created by pc-Hipparic on 2016/5/9. * * 背景描述:在广告点击计费系统中,我们在线过滤掉黑名单的点击, * 进而保护广告商的利益,只进行有效的广告点击计费; * 或者在防刷评分(或者流量)系统。(可以通过ip查看刷频分或流量的ip)过滤掉 * 无效的投票或者频分或者流量; * 黑名单: * 实现技术:利用黑名单库(这里只是利用集合来模拟),通过对每个batch中的RDD进行操作, * 这是就要利用transform Api直接基于RDD编程,进行join操作(若要考虑性能则需考虑广播) /object onlineBlackListFilter { def main(args: Array[String]) { /* * 第一步:创建Spark的配置对象SparkConf,设置Spark程序的运行时的配置信息, * 例如说通过setMaster来设置程序要连接的Spark集群的Master和URL,如果设置为 * local,则代表Spark程序在本地运行,特别适合机器配置条件差的情况。 / val conf = new SparkConf() //创建SparkConf对象 conf.setAppName("OnlineBlackListFilter") //设置应用程序名称 conf.setMaster("Spark://Master:7077") //设置集群运行下的Master /* * 第二步:创建SparkStreaming上下文 / val ssc = new StreamingContext(conf,Seconds(300)) //我们将Batch interval由原来的30s放大到300s /* * 第三步:创建黑名单 * 黑名单数据准备,实际上黑名单一般都是动态生成的,例如在Redis或者其他DB中, * 黑名单的生成往往有复杂的业务逻辑,视具体情况而言有不同的算法。 * 在Spark Streaming进行处理时每次都能够访问完整的信息。 / val blackList = Array(("hadoop",true),("mahout",true)) val blackListRDD = ssc.sparkContext.parallelize(blackList,8) //考虑如何利用kafka方式? val adsClickStream = ssc.socketTextStream("Master",9999) /* * 备注:此处模拟的广告点击的每条数据的格式为:time、name * 此处map操作的结果是name、(time、name)的格式 / val adsClickStreamFormatted = adsClickStream.map(ads => (ads.split(" ")(1),ads)) adsClickStreamFormatted.transform(userClickRDD => { //通过leftOuterJoin操作既保留了左侧用户广告点击内容的RDD的所有内容,又获得了相应 //点击内容是否在黑名单中。 val joinedBlackListRDD = userClickRDD.leftOuterJoin(blackListRDD) /* * 第四步:进行过滤 * 进行filter过滤的时候,其输入元素是一个Tuple:(name,((time,name),boolean)) * 其中第一个元素是黑名单的名称,第二个元素的第二个元素是进行leftOuterJoin的时候是否 * 存在该值,如果存在的话,说明当前广告点击是黑名单,需要过滤掉,否则的话是优先点击内容。 / val validClicked = joinedBlackListRDD.filter(joinedItem => { if(joinedItem._2._2.getOrElse(false)){ false }else{ true } }) validClicked.map(validClick => { validClick._2._1 }) }).print /* * 第五步:数据输出 * 计算后的数据一般都会写入kafka中,下游的计费系统会从kafka中pull到 * 有效数据进行计费 */ ssc.start() ssc.awaitTermination() }}

执行结果:


这里我们将Spark Streaming的Batch interval放大,主要是想通过Batch interval放大后更好的观察Spark Streaming的运行流程。此时由于我们将Batch interval放大很大,可以在Spark Streaming运行玩一次Batch后停掉它,来观察一次Batch,Spark Streaming是怎么运行的。
首先,我们来看看WebUI


     可以发现,虽然只有一个Batch进行了处理但是却产生了5个Job。为什么?

为了解决这个问题,我们来看看每个Job的内部吧,对于Job 0:


它的DAG与我们在Spark Streaming的业务逻辑类即onlineBlackListFilter中的逻辑是不同的,我们没有写reduceByKey函数。所以,我们可以得到一个解释就是这是Spark Streaming框架帮我们启动的Job,同时也说明Spark Streaming在启动时会启动一些Job来实现一些流式处理所需的功能。(类似我们启动word时,它需要启动一些Job来实现监控,显示,临时文件保存等一些功能,不单单是仅仅启动我们写文档这个作业。)
对于Job 1:

它只有一个Stage,里面包含了对一个对RDD的操作。其实这个Job是负责启动SparkStreaming中的Receive的。可以这样理解:有一个独立的Stage产生了一个Job,通过这个 Job来启动我们的Receive进行数据的接收。从RDD角度来看,这个Job是由action触发的。

有具体运行来看,它是由一个Task完成的,也就是数据的接收是由一个Executor中的一个Task来负责的,其实这个过程与其他Job运行时相似的,只不过是这个Job不单单仅有一个Stage,而且Stage内部也仅有一个Task,但处理逻辑与其他Job是相似的。从这一点我们可以看出,一个Application中可以启动多个Job,并且可以让这些Job相互配合来完成一个业务或者程序,这一点可以用来编写复杂的程序。

而且此处是PROCESS_LOCAL,内存本地性,这说明了Spark默认情况时MEMORY_AND_DISK_ONLY的,由于我们发送的信息比较小,可以在内存中存下,所以就使用了内存本地性了。
对于Job 2:

这个DAG图与我们在onlineBlackListFilter类代码中的业务逻辑是一致的,但是我们写的是以DStream为基础的,这里的DAG中显示的却是以RDD为基础的,这一点疑问先留下,后面我们会进一步讲解。
我们对这个Job里面的一个Stage观察下,可以发现:

Task是运行在两个节点上的(这里集群有两个worker)。这说明,即使Spark Streaming只有一个executor(worker)负责接收数据,但是处理数据的确实我们集群中所有的worker中的Executor,这就最大化的利用了集群的资源。其实,这里数据是由副本的,所以自动就分布在了两台机器上,如果集群的节点数大于2的话,会通过网络来进行数据的分布,这点后面我们会讲到。在该Stage结束时,会有shuffle write的过程,将数据写到相当于Spark core中Driver 里的MapOutputTracker里,供下一个Stage读取。
对于Stage4,我们可以看见它与Stage2类似,也是在我们集群中所有机器上来运行的,也会有shuffle write的过程。


而在stage5,我们发现此时他又由一个Stage中的一个Task来执行了。但是会有shuffle过程,可以看见在AggregatedMetrics by Executor栏目中的Shuffle Read size/records处观察展示的shuffle信息。


可以发现该Stage是在 00:45:00产生的transform(transform@00:45:00)

在这个Stgae会经过shuffleRead 读取数据并在Worker2上的一个Executor中,由一个Task进行leftOuterJoin、filter、map操作,产生最后我们结果。
而Job 3和Job 4 与Job 2基本上是类似的。
Job 3:

Job 4:

我们发现Job 3和Job 4强前两个Stageskip掉了,是因为此时经过第一个Job产生的数据已在内存中,而Job 3 和 Job 4可以复用这些结果,所以Job 3 与Job 4直接跳过了。但是这里有一个奇怪的地方,为什么Job 3与Job 4的最后一个Stage与前面的Job 3逻辑是相同的,但是却要重新进行计算呢?打开Job 3的最后一个Stage,我们发现,他并不是由一个Worker节点的Executor中的一个Task来运行的,而是分散在集群中运行的,所以不能也Skip掉了。

对于Job 4也有类似的现象,

就从我们业务逻辑来讲,实质上只有一个Batch的数据进行了一次计算,而SparkStreaming为什么会为我们产生这么多的Job呢?对于Spark Streaming来说肯定不是无关紧要的。它们到底在Spark Streaming运行时起着什么样的角色?先买个关子,以后我们会一一详细讲解。
通过Spark Streaming运行的现象,我们发现SparkStreaming中有太多的我们不知道的东西了,并不像官网上所讲的那么简单,这正是值得我们深入研究其奥妙的价值所在。
最后,我们大体上讲下SparkStreaming的原理。

Spark Streaming本身是根据从不同的输入源(例如Kafka、Flume、HDFS等)流入的数据,按照时间为单位(一个Batch interval)将数据划分为一个集合,产生一个Job,然后触发这个Job在集群中运行,来对数据集合进行处理的流式数据处理的引擎。
从根本上讲,它是加上了时间维度的批处理,例如例子中的300s是一个Batch interval,所以每个300s,它就会产生一个RDD,进而基于这个RDD就会触发Job,而RDD的生成与Job的生成、处理都是由SparkStreaming框架管理的。
在Spark Streaming中有一个至关重要的概念-----DStream,因为每个一段时间都会产生RDD,以及这些RDD的依赖,会触发Job、然后会具体执行Job。由于时间是持续不断的,而RDD又是基于时间,每个固定的间隔产生的,为了更好的处理和管理这些RDD,引入了DStream,可以简单理解DStream就是一个无边际、无限大的集合,每个一定的时间间隔会往这个集合中加入新的RDD。可以认为DStream是一个时间+空间的观念,在时间维度上,每隔一定时间产生新的RDD加入DStream,在空间上我们对新加入的RDD(或整个DStream里的RDD集合)进行的处理。所以,从这一点来看,Spark Streaming会给研究者带来无限的乐趣。


在空间上,对DStream的一系列操作(及我们编程时所写的业务逻辑代码)会产生DStream Graph,如下图


其中T1、T2分别代表两个不同的数据来源,对于不同的数据来源的数据我们会进行join操作,产生Join DStream,然后进行map操作产生Mapped DStream,最后我们进行了3个foreach操作,每个foreach都会产生Job。在进行第一个foreach之前,进行了map操作;第二个直接进行foreach操作;第三个则先进行了reduce操作,最终多产生了Foreach DStream。这样就每个foreach DStream都产生了一个DAG的依赖。
这个DStreamGraph相当于一个模板,每隔一个时间间隔(Batch interval)就会产生RDD,而这些RDD的依赖关系就来自于这个模板,或者说RDD 的DAG Graph就是将我们这个模板(DStream Graph)实例化后的结果。如下图



从另一个角度来讲每当到达一个Batch interval时,在这个节点上,时间定格下来,确定时间后就产生了模板的实例,即空间上RDD的处理逻辑产生的RDD Graph。然后触发具体的Job来进行Job执行。
说了这么多,我们来看看官网上的介绍吧:
从官网上来看,SparkStreaming是在Spark core基础上的一个延伸的处理在线数据流的Spark API框架,这个框架是可扩展、高吞吐高容错的。(可扩展和高容错都是由Spark继承的,而由于Spark Streaming每个worker节点都可以做为Receive来接收数据,可想而知它的吞吐量必然会相当大,同时Spark的处理数据能力也说明了其吞吐能力)数据可以有多种来源,也可以同时接收多种数据来源的数据,例如Kafka、Flume、TCP Socket等。对于数据的处理可以利用Spark高阶函数例如map、reduce、join和window函数,处理后的数据可以放到本地文件系统、数据库和dashboards中。并且在处理数据时,我们可以利用在data streams上实时利用机器学习和图计算的算法。
在内部,Spark Streaming利用其receive接收实时的输入数据,并按照时间间隔Batch interval将数据划分成不同的批次。进而交给Spark引擎在该批次中产生final Stream进而产生final RDD,有action触发Job,运行Job获得结果。
DStream其实就是一个离散流的概念,代表了一个连续系统中的数据。它可以由Kafka、flume、TCP Socket接收的输入流数据创建,也可以由高阶函数(map、reduce等)作用于其他DStream来创建。在内部,DStream就是一系列RDD的序列(由Batch interval确定的)。
至此,我们对SparkStreaming有了一定的理解,也存在一些问题,日后我们会一一解决的。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,378评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,356评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,702评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,259评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,263评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,036评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,349评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,979评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,469评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,938评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,059评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,703评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,257评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,262评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,485评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,501评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,792评论 2 345

推荐阅读更多精彩内容