Day1111

Spark任务调度
Spark几个重要组件
Spark Core
RDD的概念和特性
生成RDD的两种类型
RDD算子的两种类型
算子练习
分区
RDD的依赖关系
DAG:有向无环图
任务提交
缓存
checkPoint
自定义排序
自定义分区器
自定义累加器
广播变量
Spark Shuffle过程
Spark优化过程
SparkSQL
集成Hive

一.Spark Core

1 Spark任务调度:

    |->:standalone
|->:local
|->:Yarn
|->:Mesos

2 Spark几个重要的组件

		|->:Master:管理Worker,负责接收Driver发送的注册信息(任务信息)
|->:Worker:负责本节点资源和任务的管理,启动Exector进程
|->:Exector:负责计算任务
|->:Driver:用来提交任务(SparkSubmit进程)

3 Spark Core: RDD的概念和特性

		数据的描述
1):一组分片(Partition),即数据集的基本组成单位。对于RDD来说,每个分片都会被一个计算任务处理,并决定并行计算的粒度。用户可以在创建RDD时指定RDD的分片个数,如果没有指定,那么就会采用默认值。默认值就是程序所分配到的CPU Core的数目。
2):一个计算每个分区的函数。Spark中RDD的计算是以分片为单位的,每个RDD都会实现compute函数以达到这个目的。compute函数会对迭代器进行复合,不需要保存每次计算的结果。
3):RDD之间的依赖关系。RDD的每次转换都会生成一个新的RDD,所以RDD之间就会形成类似于流水线一样的前后依赖关系。在部分分区数据丢失时,Spark可以通过这个依赖关系重新计算丢失的分区数据,而不是对RDD的所有分区进行重新计算。
4):一个Partitioner,即RDD的分片函数。当前Spark中实现了两种类型的分片函数,一个是基于哈希的HashPartitioner,另外一个是基于范围的RangePartitioner。只有对于key-value的RDD,才会有Partitioner,非key-value的RDD的Parititioner的值是None。Partitioner函数不但决定了RDD本身的分片数量,也决定了parent RDD Shuffle输出时的分片数量。
5):一个列表,存储存取每个Partition的优先位置(preferred location)。对于一个HDFS文件来说,这个列表保存的就是每个Partition所在的块的位置。按照“移动数据不如移动计算”的理念,Spark在进行任务调度的时候,会尽可能地将计算任务分配到其所要处理数据块的存储位置。 基本特性:可分区,函数,依赖,分区器,就近原则
RDD的弹性
1): 自动进行内存和磁盘数据存储的切换
Spark优先把数据放到内存中,如果内存放不下,就会放到磁盘里面,程序进行自动的存储切换
2): 基于血统的高效容错机制
在RDD进行转换和动作的时候,会形成RDD的Lineage依赖链,当某一个RDD失效的时候,可以通过重新计算上游的RDD来重新生成丢失的RDD数据。
3): Task如果失败会自动进行特定次数的重试
RDD的计算任务如果运行失败,会自动进行任务的重新计算,默认次数是4次。
4): Stage如果失败会自动进行特定次数的重试
如果Job的某个Stage阶段计算失败,框架也会自动进行任务的重新计算,默认次数也是4次。
5): Checkpoint和Persist可主动或被动触发
RDD可以通过Persist持久化将RDD缓存到内存或者磁盘,当再次用到该RDD时直接读取就行。也可以将RDD进行检查点,检查点会将数据存储在HDFS中,该RDD的所有父RDD依赖都会被移除。
6): 数据调度弹性
Spark把这个JOB执行模型抽象为通用的有向无环图DAG,可以将多Stage的任务串联或并行执行,调度引擎自动处理Stage的失败以及Task的失败。
7): 数据分片的高度弹性
可以根据业务的特征,动态调整数据分片的个数,提升整体的应用执行效率。
RDD全称叫做弹性分布式数据集(Resilient Distributed Datasets):它是一种分布式的内存抽象,表示一个只读的记录分区的集合,它只能通过其他RDD转换而创建,为此,RDD支持丰富的转换操作(如map, join, filter, groupBy等),通过这种转换操作,新的RDD则包含了如何从其他RDDs衍生所必需的信息,所以说RDDs之间是有依赖关系的。基于RDDs之间的依赖,RDDs会形成一个有向无环图DAG,该DAG描述了整个流式计算的流程,实际执行的时候,RDD是通过血缘关系(Lineage)一气呵成的,即使出现数据分区丢失,也可以通过血缘关系重建分区,总结起来,基于RDD的流式计算任务可描述为:从稳定的物理存储(如分布式文件系统)中加载记录,记录被传入由一组确定性操作构成的DAG,然后写回稳定存储。另外RDD还可以将数据集缓存到内存中,使得在多个操作之间可以重用数据集,基于这个特点可以很方便地构建迭代型应用(图计算、机器学习等)或者交互式数据分析应用。可以说Spark最初也就是实现RDD的一个分布式系统,后面通过不断发展壮大成为现在较为完善的大数据生态系统,简单来讲,Spark-RDD的关系类似于Hadoop-MapReduce关系。

4 生成RDD的两种类型

	1:从集合中创建RDD
val conf = new SparkConf().setAppName("Test").setMaster("local")
val sc = new SparkContext(conf)
//这两个方法都有第二参数是一个默认值2 分片数量(partition的数量)
//scala集合通过makeRDD创建RDD,底层实现也是parallelize
val rdd1 = sc.makeRDD(Array(1,2,3,4,5,6))
//scala集合通过parallelize创建RDD
val rdd2 = sc.parallelize(Array(1,2,3,4,5,6))
2:从外部存储创建RDD
al rdd3 = sc.textFile("hdfs://hadoop01:8020/word.txt")

5 RDD算子的两种类型

    |->:transformation算子:转化成新RDD
|->:Action算子:转化成非RDD

6 算子练习

		|->迭代类型算子:map,flatMap,mapPartitions,foreach,foreachPartition...
|->shuffle类算子:
|->byKey:groupBy,reduceByKey(不一定),groupByKey,sortBy,SortByKey...
|->重分区算子:repartition(必然发生shuffle),colaesce(不一定,多分区变少分区不需要发生shuffle),partitionBy(发生shuffle),repartitionAndSortWithinPartitions
|->join类算子:join(不一定),fullOuterJoi,leftOuterJoin,rightOuterJoin
|->去重类算子:distinct,countApproxDistinct(返回去重的个数)
|->聚合类算子:reduce,reduceByKey,aggregate,aggregateByKey,fold,foldByKey,combineByKey,combineByKey,countByKey,countByValue
|->排序类算子:sortBy,sortByKey
优化:
1.map,mapPartition优化:一定要分数据量和对应的物力资源来确定到底使用哪个算子
数据量 | map | mapPartition
| 每个元素 | 每个分区
--------------------------------------
比较大 | | 优先选择
海量数据 | 优先选择 | 可能发生OOM 2.foreach,foreachPartition优化:需要考虑到持久化时能够承受的连接数
场景 | foreach | foreachPartition
| 每个元素 | 每个分区
---------------------------------------------------------
连接数据库 | 每个元素对应一个连接 | 优先选择(一个分区对应一个连接)
海量数据 | 优先选择 | 可能发生OOM 3.groupByKey,reduceByKey:如果能用reduceByKey解决的需求就用reduceByKey
场景 | groupByKey | reduceByKey(局部聚合)
---------------------------------------------------------
| | 优先选择
4.join+filter(过滤):为了避免join过程产生很大的数据集的情况,可以先filter再join
filter:过滤后再计算可能发生严重的数据倾斜,可以在过滤后先调整
5.序列化调优:
:RDD在计算过程中,调用的算子和传入算子的函数都是在Executor端执行,除此之外都是在Driver端执行的
class SearchFunction(val query: String) extends Serializable {
//第一个方法是判断输入的字符串是否存在query 存在返回true,不存在返回false
def isMatch(s: String): Boolean = {
s.contains(query)
}
// 问题:"isMatch"表示"this.isMatch",因此我们要传递整个"this"
def getMatchFunctionReference(rdd: RDD[String]): RDD[String] = rdd.filter(x => this.isMatch(x))// 等价于:rdd.filter(isMatch)
// 问题:"query"表示"this.query",因此我们要传递整个"this"
def getMatchesFieldReference(rdd: RDD[String]): RDD[String] = rdd.filter(x => x.contains(this.query))
// 安全:只把我们需要的字段拿出来放入局部变量中
def getMatchesNoReference(rdd: RDD[String]): RDD[String] = {
val _query = this.query
rdd.filter(x => x.contains(_query))
}
}
object SearchFunctions {
def main(args: Array[String]): Unit = {
val conf = new SparkConf().setAppName(SearchFunctions.getClass.getName).setMaster("local[2]")
val sc = new SparkContext(conf)
val rdd = sc.parallelize(List("hello java", "hello scala hello", "hello hello"))
val sf = new SearchFunction("hello")
sf.getMatchFunctionReference(rdd).foreach(println)
sf.getMatchesFieldReference(rdd).foreach(println)
sf.getMatchesNoReference(rdd).foreach(println)
sc.stop()
}
}
class Rules extends Serializable {
val rulesMap = Map("xiaoli" -> 23, "xiaoming" -> 26)
}
object ObjectRules extends Serializable {
val rulesMap = Map("jack" -> 27, "lucy" -> 22)
}
object SerializeTest_1 {
def main(args: Array[String]): Unit = {
val conf = SparkUtil.getSparkConf
val sc = new SparkContext(conf)
val lines = sc.parallelize(Array("xiaolv", "xiaohong", "xiaoming"))
//map方法中的函数是在Executor的某个Task中执行的
val res = lines.map(x => {
val rules = new Rules
val hostname = InetAddress.getLocalHost.getHostName
val threadName = Thread.currentThread().getName
(hostname, threadName, rules.rulesMap.getOrElse(x, 0), rules.toString)
})
println(res.collect.toBuffer)
/*
ArrayBuffer(
(localhost,Executor task launch worker for task 0,0,cn.qf.streaming.day01.test.Rules@5c3d762c),
(localhost,Executor task launch worker for task 1,0,cn.qf.streaming.day01.test.Rules@736d5f3b),
(localhost,Executor task launch worker for task 1,26,cn.qf.streaming.day01.test.Rules@374cd5ba))
*/
sc.stop()
}
}
object SerializeTest_2 {
def main(args: Array[String]): Unit = {
val conf = SparkUtil.getSparkConf
val sc = new SparkContext(conf)
val lines = sc.parallelize(Array("xiaolv", "xiaohong", "xiaoming"))
//该对象在Driver中创建
val rules = new Rules
//map方法中的函数是在Executor的某个Task中执行的
val res = lines.map(x => {
val hostname = InetAddress.getLocalHost.getHostName
val threadName = Thread.currentThread().getName
(hostname, threadName, rules.rulesMap.getOrElse(x, 0), rules.toString)
})
println(res.collect.toBuffer)
/*
ArrayBuffer(
(localhost,Executor task launch worker for task 0,0,cn.qf.streaming.day01.test.Rules@48158406),
(localhost,Executor task launch worker for task 1,0,cn.qf.streaming.day01.test.Rules@a287af2),
(localhost,Executor task launch worker for task 1,26,cn.qf.streaming.day01.test.Rules@a287af2))
*/
sc.stop()
}
}
object SerializeTest_3 {
def main(args: Array[String]): Unit = {
val conf = SparkUtil.getSparkConf
val sc = new SparkContext(conf)
val lines = sc.parallelize(Array("xiaolv", "xiaohong", "xiaoming"))
//该对象在Driver中创建单例对象
val rules = ObjectRules
//map方法中的函数是在Executor的某个Task中执行的
val res = lines.map(x => {
val hostname = InetAddress.getLocalHost.getHostName
val threadName = Thread.currentThread().getName
(hostname, threadName, rules.rulesMap.getOrElse(x, 0), rules.toString)
})
println(res.collect.toBuffer)
/*
ArrayBuffer(
(localhost,Executor task launch worker for task 0,0,cn.qf.streaming.day01.test.ObjectRules$@543e593),
(localhost,Executor task launch worker for task 1,0,cn.qf.streaming.day01.test.ObjectRules$@543e593),
(localhost,Executor task launch worker for task 1,0,cn.qf.streaming.day01.test.ObjectRules$@543e593))
*/
sc.stop()
}
}
object SerializeTest_4 {
def main(args: Array[String]): Unit = {
val conf = SparkUtil.getSparkConf
val sc = new SparkContext(conf)
val lines = sc.parallelize(Array("xiaolv", "xiaohong", "xiaoming"))
//该对象在Driver中创建单例对象
//map方法中的函数是在Executor的某个Task中执行的
val res = lines.map(x => {
val hostname = InetAddress.getLocalHost.getHostName
val threadName = Thread.currentThread().getName
/*
不用在Driver端去创建对象,Rules不用实现序列化
*/
(hostname, threadName, ObjectRules.rulesMap.getOrElse(x, 0), ObjectRules.toString)
})
println(res.collect.toBuffer)
/*
ArrayBuffer(
(localhost,Executor task launch worker for task 0,0,cn.qf.streaming.day01.test.ObjectRules$@2539fca6),
(localhost,Executor task launch worker for task 1,0,cn.qf.streaming.day01.test.ObjectRules$@2539fca6),
(localhost,Executor task launch worker for task 1,0,cn.qf.streaming.day01.test.ObjectRules$@2539fca6))
*/
sc.stop()
}
}

7 分区

		textFile分片过程:由指定的cpu核数+指定的分区数+block块的大小+文件的个数,经过分片算法得到最终的分区数

8 RDD的依赖关系

		|->宽依赖:一对多  一个父RDD分区会被多个子RDD使用
|->窄依赖:一对一,多对一
|->为什么区分宽窄依赖:
|->1:有宽窄依赖就可以进行相应的容错
|->2:宽依赖决定了stage的划分的依据

9 DAG

		为什么划分stage:主要是为了生成task,stage划分过程实际上就将rdd的依赖按照shuffle来分为一个到多个的范围,task执行过程根本不会跨stage
task数量 = stage数量 * 分区数(注:前提是没有手动更改分区数)
如果手动更改分区数,该stage的task数据由最后的分区数决定的

Spark Core知识点复习-1的更多相关文章

  1. Spark Core知识点复习-2

    day1112 1.spark core复习 任务提交 缓存 checkPoint 自定义排序 自定义分区器 自定义累加器 广播变量 Spark Shuffle过程 SparkSQL 一. Spark ...

  2. Spring知识点复习

    Spring知识点复习 一.专业术语 侵入式设计 引入框架,对现有的类的结构有影响,即需要实现或继承某些特定类.如:Struts框架 非侵入式设计 引入框架,对现有的类结构没有影响.如:Hiberna ...

  3. 大数据笔记(二十七)——Spark Core简介及安装配置

    1.Spark Core: 类似MapReduce 核心:RDD 2.Spark SQL: 类似Hive,支持SQL 3.Spark Streaming:类似Storm =============== ...

  4. Spark Streaming揭秘 Day35 Spark core思考

    Spark Streaming揭秘 Day35 Spark core思考 Spark上的子框架,都是后来加上去的.都是在Spark core上完成的,所有框架一切的实现最终还是由Spark core来 ...

  5. 【Spark Core】任务运行机制和Task源代码浅析1

    引言 上一小节<TaskScheduler源代码与任务提交原理浅析2>介绍了Driver側将Stage进行划分.依据Executor闲置情况分发任务,终于通过DriverActor向exe ...

  6. TypeError: Error #1034: 强制转换类型失败:无法将 mx.controls::DataGrid@9a7c0a1 转换为 spark.core.IViewport。

    1.错误描述 TypeError: Error #1034: 强制转换类型失败:无法将 mx.controls::DataGrid@9aa90a1 转换为 spark.core.IViewport. ...

  7. Spark Core

    Spark Core    DAG概念        有向无环图        Spark会根据用户提交的计算逻辑中的RDD的转换(变换方法)和动作(action方法)来生成RDD之间的依赖关系,同时 ...

  8. spark core (二)

    一.Spark-Shell交互式工具 1.Spark-Shell交互式工具 Spark-Shell提供了一种学习API的简单方式, 以及一个能够交互式分析数据的强大工具. 在Scala语言环境下或Py ...

  9. Spark Core 资源调度与任务调度(standalone client 流程描述)

    Spark Core 资源调度与任务调度(standalone client 流程描述) Spark集群启动:      集群启动后,Worker会向Master汇报资源情况(实际上将Worker的资 ...

随机推荐

  1. 进程调度算法spf,fpf,时间片轮转算法实现

    调度的基本概念:从就绪队列中按照一定的算法选择一个进程并将处理机分配给它运行,以实现进程并发地执行. 进程信息 struct node { string name;//进程名称 int id;//进程 ...

  2. 小鸟初学Shell编程(九)环境变量变量配置文件

    介绍 在上一篇使用完了环境变量,并且知道PATH环境变量概念,那么我们对命令的执行就有了一定深入的理解.那么PATH环境变量或其他环境变量是保存在哪呢?那么这篇文章主要介绍环境变量配置文件. 配置文件 ...

  3. 如何在Ubuntu编译ice

    摘要:所有操作都在root用户下执行 第一步:下载ice最新版本,以3.7版本为例 第二步:安装ICE依赖包里面的三方库 #apt-get install libmcpp-dev;apt-get in ...

  4. 面向对象程序设计(java)

    201871010136-赵艳强<面向对象程序设计(java)>第二周学习总   第一部分:理论知识学习部分 一.简单的Java程序应运程序 1.标识符0标识符由字母.下划线.美元符号和数 ...

  5. python27期day15:自定义模块、模块导入、模块的路径、模块的查找顺序、time、datetime、random、os、sys、作业题

    1.模块的介绍: py文件就是一个模块 2.模块的分类:内置模块:python标准库 200 第三方模块 自定义模块 3.为什么学习模块? 开发效率高,内置函数和模块 减少重复代码,分文件管理,有助于 ...

  6. 安装_升级Eclipse插件

    在线安装_升级Eclipse插件可以保证插件的完整性,并可自由选择最新版本.1.单击Eclipse的Help菜单,选择"Install New Software"菜单项2.单击&q ...

  7. 原生js-input框全选

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. Spring 中的异常处理

    工作中遇到这样的同事,问他活干完吗,他说开发好了,结果测试时发现各种异常情况未处理,联调测试时各种未知错误,最后联调完成比他预期的两倍工作量还多.这样的开发如果是新人还可以原谅,如果有工作经验且出现多 ...

  9. docker的一些常用操作

    镜像:一个打包好的应用,还有应用运行的系统.资源.配置等容器:镜像的实例,一个镜像可以有一个或多个实例(容器)对docker容器的变更时写到容器的文件系统的,而不是写到docker镜像中的,可以用一个 ...

  10. [LeetCode] 4. Median of Two Sorted Arrays 两个有序数组的中位数

    There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the two ...