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
    Spark原理为什么要将Job切割成Stage?
    Stage与Stage之间是宽依赖没有shuffle
    Stage内部是窄依赖没有shuffle

    Spark原理task0:这条红线所贯穿的所有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

未完待续…

相关文章:

  • 2021-11-02
  • 2021-11-30
  • 2021-11-18
  • 2021-11-30
  • 2021-11-30
  • 2021-11-18
  • 2021-11-30
  • 2021-11-18
猜你喜欢
  • 2022-01-08
  • 2021-11-24
  • 2021-05-29
  • 2021-08-09
  • 2021-09-15
  • 2021-10-06
  • 2021-11-30
相关资源
相似解决方案