Spark原理

Spark原理

  • Spark专业术语
    -任务:
    Application:用户写的应用程序(Driver Program+Executor Program)
    Job:一个action类算子触发执行的操作
    Stage:一组任务
    task:(thread)在集群运行时最小的执行单元

    -资源,集群:
    Master:资源管理的主节点
    Worker:资源管理的从节点
    Executor:执行任务的进程
    ThreadPool:线程池,存在于Executor进程中
  • RDD(Resilient Distributed Dataset)弹性分布式数据集
    1.RDD是由一系列的partition组成的
    2.RDD提供的每一个函数实际上是作用在每一个partition上的
    3.RDD是由一系列的依赖关系的,依赖于其他的RDD
    4.可选项 分区器是作用于KV格式的RDD上的
    5.可选项 RDD会提供一系列的最佳计算位置(RDD提供了一个接口方法,直接调用这个方法接口,就能拿到这个RDD的所有的Partition位置)
    在Spark中没有读文件的方法,依赖的是MR读文件的方法,MR在读文件之前会将文件划分成一个个split,split size = block size,block num ≈ split num,split num等于第一个RDD的分区数。(特殊情况除外)
    RDD依赖关系的作用:计算的容错性。如果在计算过程中出现数据丢失问题,RDD会从其父RDD重新计算过来。
    RDD不存数据,它只是一个逻辑上的概念,partition也不存数据,它们有处理数据的能力。RDD中实际存储的是计算逻辑。
  • RDD的依赖关系
    -窄依赖:
    父RDD不知道其有多少子RDD,但是子RDD一定知道其父RDD,父RDD与子RDD,Partition之间的关系是一对一,那么父子RDD的依赖关系就称之为窄依赖,这种依赖不会有shuffle。
    -宽依赖:
    父RDD与子RDD,Partition之间的关系是一对多,那么父子RDD的依赖关系就称之为宽依赖,这种依赖会有shuffle。
    -宽依赖的作用:
    为了将一个个Job切割成一个个Stage
    DAG有向无环图为什么要将Job切割成Stage?
    Stage与Stage之间是宽依赖没有shuffle
    Stage内部是窄依赖没有shuffle
    为了形成pipeline管道并行计算

    tasktask0:这条红线所贯穿的所有partition中的计算逻辑,并且以递归函数展开式的形式整合在一起(例:fun2(fun1(textFile(bl))))计算时最好发送到b1或b1副本所在的节点
    task1:(例:fun2(fun1(textFile(b2))))计算时最好发送到b2或b2副本所在的节点
    -task的计算模式是pipeline的计算模式,管道计算。
    1.Stage中的每个task(管道计算模式)在什么时候会落地磁盘呢?
    ①.如果Stage后面是action类算子
    collect:将每一个管道的计算结果收集到Driver端的内存中
    saveAsTextFile:将每一个管道的计算结果写到指定目录
    count:将管道的计算结果统计记录数,返回给Driver
    ②.如果Stage后面是Stage
    在shuffle write阶段会写磁盘
    shuffle write阶段写磁盘是为了防止reduce task拉取数据失败
    2.Spark在计算过程中并不是非常耗内存,,有控制类算子时最耗内存(例:cache())
    3.RDD有创造数据的能力所以叫数据集
  • 任务调度
    1.根据RDD的宽窄依赖关系,将DAG有向无环图切割成一个个的Stage,将切割出来的Stage封装到另外一个对象TaskSet,然后将一个个TaskSet给TaskScheduler。
    2.TaskSchedule拿到TaskSet后,会遍历这个集合,拿到每一个task,然后去调用HDFS上某一个方法,然后获取数据的位置,依据数据的位置来分发task到Worker节点的Executor进程中的线程池中执行
    3.TaskSchedule会实时跟踪每一个task的执行情况,若执行失败或者遇到挣扎(掉队)的任务,TaskSchedule会重试提交task,默认重复3次,如果重试3次依然失败,那么这个task所在的Stage就失败了,此时它会向DriverSchedule汇报
    4.此时DriverSchedule会重试提交Stage,注意:每一次重试提交的Stage,已经成功执行的不会再次分发到Executor进程执行,只是重试失败的,如果DriverSchedule重试了4次依然失败,那么这个Stage所在的Job就失败了,Job失败是不会进行重试的。
    -挣扎(掉队)的任务:
    默认情况,在任务的75% 执行完毕后,TaskSchedule会每100ms计算一下,统计还未完成的任务已执行的时间取出中位数,然后将这个中位数*1.5,拿到这个最终计算出来的时间去看哪一些task超时,这些task就是挣扎(掉队)的task。当遇到挣扎(掉队)的任务,TaskSchedule会进行重试,此时TaskSchedule会提交一个和挣扎的task同样的task到集群中运行,挣扎的task并不会被kill掉,而是会比赛执行,谁先执行完毕就取谁的结果。
    -配置信息的使用:
    1.在代码中设置SparkConf
    2.在提交Application时通过 --conf来设置,例:spark-submit --master --conf k=v 如果要修改多个配置信息的值,那么需要加一个 --conf(常用)
    3.在spark的配置文件中配置,spark-default.conf
  • 资源调度
    资源调度

-资源调度详细过程:

1.客户端提交命令,在客户端启动一个sparksubmit进程
2.sparksubmit进程为Driver向Master申请资源,此时Master中将申请信息加入waitingDrivers集合,当waitingDrivers集合中元素不为空时,说明有客户向master为Driver申请资源,此时应当查看当前集群的资源情况,找到符合需求的节点,启动Driver,当Driver启动成功时,这个资源的申请信息会从waitingDrivers中删除
3.Driver启动成功后会向Master为当前的Application申请资源,在Master中将申请信息加入waitingApps,当waitingApps集合不为空时,说明有Driver向Master为Application申请资源,Master会查看集群的资源情况找到合适的Worker节点,启动executor进程,默认每一个Worker为当前Application只启动一个executor,这个executor会使用1G内存和这个Worker的所管理的所有core
-资源调度总结:
1.默认情况下,每一个节点为当前的Application只会启动一个executor,这个executor默认使用1G内存和当前Worker所能管理的所有的core
2.如果要想在一个Worker上启动多个executor,在提交Application时要指定executor使用的核心数提交时加上--executor-cores
3.默认情况下,executor的启动是轮训方式来启动的,轮训一定程度有利于数据本地化

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值