Spark Streaming学习(一)流处理框架,Spark运
流处理框架
Spark Streaming和其他流处理框架的对比
-
处理模式: 一种是
原生流处理
(Native)方式,所有输入记录会一条一条地被处理,Storm就是这种模式;另一种是微批处理(Batch)方式,将输入数据以某一时间间隔进行切分,对每个批次的数据进行处理,Spark Streaming就是这种模式 -
消息传输保障: 三种分模式,
At most once
,At least once
,Exactly once
;At most once表示消息最多传输1次,就是0次或者1次,这样数据可能丢失,At least once表示数据至少传输1次,消息可能重复传输但是不会丢失,Strom是这种模式;Exactly once表示只会精确地传输1次,Spark Streaming就是这种模式。 -
性能: 流处理框架的性能评价指标包括
吞吐量(Throughput)
,延迟时间(Latency)
等,Strom原生流处理模式逐条处理延迟低,Spark Streaming微批处理模式延迟较高,在吞吐量方面Spark Streaming优于Strom。
Spark Streaming简介
Spark Streaming是一个高吞吐
,高容错
的实时流
处理系统,可以从Kafka
,Flume
等获取数据,然后利用复杂操作(如map
,reduce
,window
等)进行操作,最终处理后的数据输出到文件系统
,数据库
或者控制台
。
实际上Spark Streaming在接受到实时数据时,会将其按照批数据(Batch)来处理,再对批数据进行处理得到最后的结果数据流。
Spark批数据处理过程.png
Spark Streming将批处理数据抽象为离散数据流(DStream),DStream有两种产生方式,一种是从Kafka,Flume等输入流上直接创建,一种是对其他DStream采用高阶API操作得到(transform),DStream的本质是由RDD数据结构的序列来表示的。
Spark的运行模式
Spark提供了4种模式,分别是本地模式
,Standalone模式
,Spark On Yarn模式
以及Spark On Mesos模式
,本地模式包含单机模式和伪集群模式,用于调试实验,其他三种集群配置。Spark运行的相关概念如下:
-
Driver
: 执行应用程序中创建SparkContext的main函数的进程,在集群的任何节点提交应用程序该节点就是Driver节点。 -
Cluster manager
: 集群管理器,统筹管理集群的各种资源,包括CPU,内存等。根据服务方式进行资源分配。 -
Master节点
:部署Cluster manager的节点 -
Worker
: 集群中任何一个运行应用程序的节点,它接受集群管理器的安排,为应用程序生成Executor,其他桥梁作用。 -
Slave节点
:部署Woker的机器节点,每个Slave节点可以有多个Worker进程。 -
Executor
:表示应用在Worker节点中进行实际计算的继承,进程会切分Task任务,并将结果缓存在节点内存和磁盘上。 -
Task
:配分配到Executor的单位工作内容,是Spark中的最小执行单位,一般有多少个Partition
(将数据划分为多少不同部分进行并行处理)就会有多少个Task,每个Task只会处理单一分支上的数据。 -
Job
:Spark中action操作会生成一个Job,一个Job是一个Spark并行部分任务 -
Stage
:是Job的组成单位,一个Job会分割成多个Stage,通常根据数据是否要重分区
(shuffle)或者任何破坏数据局域性
的事件,Stage之间上下依赖顺序执行,每个Stage是多个Task的集合,同一个Stage下的Task(Partition)可以并行处理。
Spark Streaming UI监控界面
从Spark运行日志中跟踪url地址
日志中的Spark UI地址.png
Spark主界面记录应用详情
应用详情页-Jobs.png
应用详请页-Stages.png
应用详情页-Executors.png
一共三个executors,每个executor4个core,一共12cores
应用详情页-Streaming.png
运行环境.png
包括Java,Scala版本,Spark配置参数,系统配置参数,Jar包明细
RDD编程模型
1.RDD概述
RDD的核心为内存计算
,适合计算机集群
,有容错方式
,RDD的容错是通过记录RDD之间的转换从而刻画集成关系,最终形成一个DAG
有向无环图,这种结构当发生RDD丢失时,能够利用上下文的信息从祖辈RDD中重新计算得到
。
RDD并行计算的核心是分区
,数据在RDD内部被划分为多个子集合,每个子集合是一个分区,每个分区又一个单独的任务Task来运行,分区数越多并行度越高。
2.RDD操作
RDD操作可以分为Transformation
和Action
两种,Transformation不会触发计算,只会建立RDD之间的关系图
map
和mapPartitions
的区别
- map: RDD中每一个元素调用函数,如果函数需要创建额外对象(数据库链接),那么每一个元素都要创建一次这个对象
- mapPartitions: RDD中按照分区调用函数,一个分区执行一次函数,函数接受整个分区的数据,如果需要在操作中创建对象(比如数据库链接对象)可以使用mapPartitions,从而每个分区创建一次
Action操作代表一次计算的结束,不再产生新的RDD,将结果返回到Driver程序,Action才是真正的执行者,Transformation建立计算关系。 -
collect
: 将所有数据集以数组的形式汇总在Driver节点,当数据集很大时会撑爆Driver节点内存,通常先filter一下
3.RDD间的依赖方式
从一个RDD生成新的RDD称为子RDD
,子RDD的向上依赖就是父RDD
,两个RDD之间的依赖关系分为宽依赖
(Shuffle依赖)和窄依赖
。
-
窄依赖
:父RDD和子RDD的分区是一一对应的,父RDD中的分区是不能分割的,只能由子RDD中的一个分区利用 -
宽依赖
: 父RDD中的分区可能被多个子RDD利用,父RDD中的一个分区内的数据会被分割发送给子RDD的所有分区
map之类都是窄依赖,Shuffle之类都是宽依赖,join看情况,可能是窄依赖,可能是宽依赖
RDD持久化
如果对一个RDD进行持久化,那么每个节点的每个Partition都会将计算记过保存在内存中,下次调用的时候无需重新计算。可以使用rdd.persist()
或者rdd.cache()
方法将一个RDD持久化,默认是作为非序列化对象在内存中持久化
(MEMORY_ONLY)。Spark会自动把Shuffle操作的一些中间数据进行持久化,防止Shuffle时一个节点失败导致全局重新计算。
共享变量
广播变量的好处:如果算子函数中,使用到了特别大的数据,那么推荐将该数据进行广播,就不至于将一个大数据拷贝到每一个task
上去,而是给每个节点
拷贝一份,然后节点上的task共享该数据
。这样的话,就可以减少大数据在节点上的内存消耗
,并且可以减少数据到节点的网络传输消耗
。例如把配置文件添加到广播变量:
import java.util.Properties
val prop = new Properties()
val configProperties = ssc.sparkContext.broadcast(prop)
// 使用value获得值
configProperties.value.getProperty("", "")
scala中一切可序列化的对象都是可以广播的,可以利用广播变量将一些经常访问的大变量进行广播。