spark知识总结

spark前置知识总结:

1.spark专业术语:

关于任务

application:
用户写的应用程序(由两部分组成: Driver program + Execuotr program)

Job:
一个action类算子触发执行的操作,有多少个action类算子就有多少个job

stage:
一组任务, map task 一组任务(task) 就是一个stage

task:
(thread) 在集群运行时最小的执行单元

关于资源集群:

Master:
资源管理的主节点
Worker:
资源管理的从节点
Excutor:
执行任务的进程
ThreadPool:
线程池,存在于Executor进程中


2.RDD的依赖关系: 窄依赖+宽依赖

1.窄依赖:

父RDD与子RDD,patition之间的关系为一对一,那么父子RDD的依赖关系为窄依赖,无shuffle操作

(shuffle: 数据的规整,根据所使用的方法进行规整
partition:一份待处理的原始数据会被按照相应的逻辑(例如jdbc和hdfs的split逻辑)切分成n份,每份数据对应到RDD中的一个Partition,Partition的数量决定了task的数量,影响着程序的并行度)

在这里插入图片描述

2.宽依赖:

在这里插入图片描述
关系:
一个application 有多个job组成,job的个数跟action类算子个数相关, 一个job由多个stage组成,具体个数由RDD宽窄依赖决定,一个stage由一组task组成

3.宽窄依赖的作用:为了将一个个的job切成一个个的stage
在这里插入图片描述同一个stage中,均为窄依赖,不同stage之间均未宽依赖

问题:
为什么要将job切割成stage?

stage与stage之间是宽依赖,有shuffle
stage内部是窄依赖,无shuffle

分为stage可以划分task,实现管道计算

RDD实际上存储的是计算逻辑,不是真实的数据

task封装的是它所贯穿的所有的partition的逻辑,并且他以递归函数展开式的形式进行存储的

在这里插入图片描述
根据代码画有向无环图:
在这里插入图片描述task0:
这条线所贯穿的所有partion中的计算逻辑,并且以递归函数展开式的形式整合在一起 fun2(fun1(textFile(b1))) task0最好发送到b1以及他的副本所在的位置(计算找数据)

task1:
fun2(fun1(textFile(b2))) task1最好发送到b2以及他副本所有的位置

task计算模式是pipeline的计算模式, 管道模式(每经过一个RDD就进行处理。 数据不落地,减少磁盘IO,并行计算)

kv格式RDD:如果一个RDD的返回值类型为KV格式,则称这个RDD为KV格式RDD

问题:
stage中每一个task(管道计算模式)在什么时候落地磁盘呢?
1.如果stage后面是action类算子。
collect:将每一个管道的计算结果手机到Driver端的内存中
saveAndTextFile:将每一个管道的计算结果写到指定目录
count:将管道的计算结果统计记录数,返回给Driver
在这里插入图片描述2.如果stage后面是stage
在shuffle write节点会写磁盘
为什么write阶段必须写磁盘:为了防止在reducetask在拉取数据时失败

spark在计算过程中,是不是非常消耗内存?
不是!

因为管道中装载不了太多的数据

什么样的场景最耗内存?
管道多了,并行度非常高(消耗大,不是最耗)
控制类算子 特别是cache()

解释 :如果管道中有cache逻辑,它是如何缓存数据的?
在这里插入图片描述
RDD弹性分布式数据集,为什么不存储数据,还叫数据集?
因为RDD具有处理数据的能力,生成新的数据

M任务调度:

在创建SparkContext对象的时候,一个核心的是模块就是调度器(Scheduler),在spark中Scheduler有两种:

TaskScheduler(是低级的调度器接口)。TaskScheduler负责实际每个具体Task的物理调度。
DagScheduler(是高级的调度)。DAGScheduler负责将Task拆分成不同Stage的具有依赖关系(包含RDD的依赖关系)的多批任务,然后提交给TaskScheduler进行具体处理。DAG全称 Directed Acyclic Graph,有向无环图。简单的来说,就是一个由顶点和有方向性的边构成的图,从任意一个顶点出发,没有任何一条路径会将其带回到出发的顶点。

在这里插入图片描述
问题:什么是(掉队)挣扎的任务?
例子:比如有1000task,已经有999个task执行完毕,只有一个task正在执行,则称这个task是挣扎的任务

当TS遇到挣扎的任务的时候,他会重试。此时TS会重新提交一个和掉队的task一模一样的task到集群中运行,注意:此时挣扎的task不会被kill掉,而是两个task一起比赛执行, 谁先执行完,以谁的结果为准(重新提交的task是放在与第一个task不用的节点上,而是放在其他副本上)
以上过程为 推测执行机制

推测执行的三个指标:100ms 1.5 75%(这些指标是可以调整的)

标准:TS每隔100ms会计算一下,看看集群中是否有挣扎的task
例如:有100task,已经有76个task执行完毕,24个task未执行完毕。则TS会取这些task执行时间的中位数*1.5作为一个时间标准,如果有task超过这个时间标准,则认定为是一个挣扎的task。(已经执行的task超过75%时,执行这套标准)

问题:
1.如果1T数据,单机运行需要30分钟,但是spark运行需要两个小时,为什么?

原因:
1.数据发生了数据倾斜(大部分的数据给了少量的task,少量的数据)
2.开启了推测执行机制(默认是关闭状态)
例如:有100G的数据,100个task。 1个task计算99G数据,99个task计算1G的数据,此时99的task执行的快,而且推测执行机制开启了。就会认为那1个task是挣扎的,就会再重启一个,此时运行的还是慢,还是会被认为是一个挣扎的task,就会再重启,循环 …
解决方案: 数据调优,或者关闭推测执行

2.对于ETL业务,开启了推测执行、重试机制,对于最终的结果是否有影响?

ETL:数据清洗流程 抽取数据进行清洗再放回(在进行数据清洗的时候,是从一个脏数据表中得到数据,存放到一个新表里面)
有影响:最终数据库中会有重复的数据。

例如:当一个task执行到90%的时候,被认为是挣扎的task或fail。此时重启一个task,这个task从0开始,但是数据库中已经有了90的数据,这样就会造成数据的重复

解决方案:
1.关闭推测重试机制,不大可行,因为太容易失败
2.设置事务表:在入库之前,先查询事务表,数据是否插入,如果重复不在插入
在spark中无法使用mysql中的事务(事务是分批处理。spark是分条处理)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值