热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

SparkRDD宽窄依赖及Stage划分

1.术语解释:Master(Standalone):资源管理的主节点(进程)ClusterManager:在集群上获取资源的外部服务(例如standalone,Mesos,Yarn

1.术语解释:

Master(Standalone):资源管理的主节点(进程)

Cluster Manager:在集群上获取资源的外部服务(例如standalone,Mesos,Yarn)

Worker Node(standalone):资源管理的从节点(进程)或者说管理本机资源的进程

Application:基于Spark的用户程序,包含了Driver程序和运行在集群上的executor程序

Driver Program:用来连接工作进程(Worker)的程序

Executor:是在一个Worker进程所管理的节点上为某一个Application启动的一个进程,该进程负责运行任务,并且负责将数据存在内存或者磁盘上,每个应用各自独立的executors

Task:被送到某个executor上的工作单元

Job:包含很多任务(Task)的并行计算,可以看做和action对应

Stage:一个Job会被拆分成很多组任务,每组任务被称为Stage

按照资源层面划分:Master ->Worker->Executor->ThreadPool

按照任务层面划分:Application->job->stage->tasks

2.宽窄依赖:

RDD之间有一系列的依赖关系,依赖关系又分为窄依赖和宽依赖。

Spark中的Stage其实是一组并行的任务,任务是一个个的Task

窄依赖:

父RDD和子RDDpartition之间的关系是一对一的,或者父RDD一个partition只对应一个子RDD的partition情况下的父RDD和子RDD partition关系是多对一的,不会有shuffle产生。父RDD的一个分区去到了子RDD的一个分区

《Spark----RDD宽窄依赖及Stage划分》
《Spark----RDD宽窄依赖及Stage划分》

宽依赖:

父RDD与子RDD partition之间的关系是一对多,会有shuffle的产生。父RDD的一个分区的数据去到了子RDD的不同分区里面。

《Spark----RDD宽窄依赖及Stage划分》
《Spark----RDD宽窄依赖及Stage划分》

区分宽窄依赖主要就是看父RDD的一个partition的流向,要是流向一个的话就是窄依赖,流向多个的话就是宽依赖。相比于宽依赖,窄依赖对优化很有利,主要基于一下两点:

1.宽依赖往往对应着shuffle操作,需要在运行过程中将同一个父RDD的分区传入到不同的子RDD分区中,中间可能涉及多个节点间的数据传输,而窄依赖的每个父RDD分区只会传入到一个子RDD分区中,通常可以在一个节点内完成转换。

2.当RDD分区丢失时(某个节点故障),spark会对数据进行重算

1).对于窄依赖,由于父RDD的一个分区只对应一个子RDD分区,这样只需要重算和子RDD分区对应的父RDD分区即可,所以这个重算对数据的利用率是100%的。

2).对于宽依赖,重算的父RDD分区对应多个字RDD分区,这样实际上父RDD中只有一部分的数据是被用于恢复这个丢失的子RDD分区的,另一部分对应子RDD的其他未丢失分区,这就造成了多余的计算,宽依赖中子RDD分区通常来自于多个父RDD分区,极端情况下,所有的父RDD分区都要重新计算

3).如下图所示,b1分区丢失,则需要重新计算a1,a2和a3,这样就产生了冗余计算(a1,a2,a3中对应着b2的数据)

《Spark----RDD宽窄依赖及Stage划分》

区分这两种依赖很有用,首先,窄依赖允许在一个集群节点上以流水线的方式(pipeline)计算所有父分区。例如,逐个元素地执行map,然后filter操作;而宽依赖则需要首先计算好所有父分区数据,然后在节点间进行shuffle,这和MapReduce类似。第二,窄依赖能够更有效地进行失效节点的恢复,即只需要重新计算丢失RDD分区的父分区,而且不同节点间可以并行计算;而对于一个宽依赖关系的Lineage图,单个节点失效可能导致这个RDD的所有祖先丢失部分分区,因而需要整体重新计算。

在深入分区级别来看待这个问题,重算的效用并不在于算了多少,而是在于有多少是冗余的计算。窄依赖中需要重算的都是必须的,所以重算并不会产生冗余计算。

3.Stage划分:

Spark任务会根据RDD之间的依赖关系,形成一个DAG有向无环图,DAG会提交给DAGScheduler,DAGScheduler会把DAG划分成互相依赖的多个stage,划分stage的依据就是RDD之间的宽窄依赖。遇到宽依赖就划分stage,每个stage包含一个或多个task任务,然后将这些task以taskSet的形式提交给TaskScheduler运行。

stage是由一组并行的task组成。

stage切割规则:从后往前,遇到宽依赖就切割stage

《Spark----RDD宽窄依赖及Stage划分》
《Spark----RDD宽窄依赖及Stage划分》

stage计算模式:pipeline管道计算模式,pipeline只是一种计算思想,模式

《Spark----RDD宽窄依赖及Stage划分》
《Spark----RDD宽窄依赖及Stage划分》

备注:

1.Spark的pipeline的计算模式

相当于执行了一个高阶函数f4(f3(f2(f1(“…..))))。也就是来一条数据然后计算一条数据,把所有的逻辑走完,然后落地。准确的说,是一个task处理一串分区的数据。整个计算逻辑全部走完。而MapReduce是1+1=2,2+1=3的模式,也就是计算完落地,然后拉取,再执行计算,然后再落地到磁盘或者内存,最后数据是落在计算节点上,按reduce的hash分区落地。所以这也是Saprk比MapReduce快的原因,是完全基于内存计算的。

2.管道中的数据何时落地:

shuffle write的时候

对RDD进行持久化的时候

3.Stage的task并行度是由stage的最后一个RDD的分区数来决定的

一般来说,一个partition对应一个task,但最后reduce的时候,可以手动改变reduce的个数来提高并行度,也就是分区数。例如reduceByKey(xxx,3),GroupByKey(4),union的分区数,是由前面的相加

测试验证pipeline计算模式(迭代器模式):

import org.apache.spark.rdd.RDD import org.apache.spark.{SparkConf, SparkContext} object pipeLineTest { def main(args: Array[String]): Unit = { val cOnf= new SparkConf().setMaster(“local”).setAppName(“pipelineTest”) val sc = new SparkContext(conf) sc.setLogLevel(“Error”) val rdd1 = sc.parallelize(Array(1,2,3,4)) val rdd2: RDD[Int] = rdd1.map { x => { println(“map———” + x) x } } val rdd3: RDD[Int] = rdd2.filter(x => { println(“filter***********” + x) true }) rdd3.collect() sc.stop() } }

运行结果如下所示:

《Spark----RDD宽窄依赖及Stage划分》
《Spark----RDD宽窄依赖及Stage划分》


推荐阅读
  • 本文探讨了Hive中内部表和外部表的区别及其在HDFS上的路径映射,详细解释了两者的创建、加载及删除操作,并提供了查看表详细信息的方法。通过对比这两种表类型,帮助读者理解如何更好地管理和保护数据。 ... [详细]
  • 本文详细介绍了Akka中的BackoffSupervisor机制,探讨其在处理持久化失败和Actor重启时的应用。通过具体示例,展示了如何配置和使用BackoffSupervisor以实现更细粒度的异常处理。 ... [详细]
  • 深入解析Android自定义View面试题
    本文探讨了Android Launcher开发中自定义View的重要性,并通过一道经典的面试题,帮助开发者更好地理解自定义View的实现细节。文章不仅涵盖了基础知识,还提供了实际操作建议。 ... [详细]
  • 本文详细介绍了Java中org.neo4j.helpers.collection.Iterators.single()方法的功能、使用场景及代码示例,帮助开发者更好地理解和应用该方法。 ... [详细]
  • Windows服务与数据库交互问题解析
    本文探讨了在Windows 10(64位)环境下开发的Windows服务,旨在定期向本地MS SQL Server (v.11)插入记录。尽管服务已成功安装并运行,但记录并未正确插入。我们将详细分析可能的原因及解决方案。 ... [详细]
  • 本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ... [详细]
  • 本文介绍如何使用Objective-C结合dispatch库进行并发编程,以提高素数计数任务的效率。通过对比纯C代码与引入并发机制后的代码,展示dispatch库的强大功能。 ... [详细]
  • 技术分享:从动态网站提取站点密钥的解决方案
    本文探讨了如何从动态网站中提取站点密钥,特别是针对验证码(reCAPTCHA)的处理方法。通过结合Selenium和requests库,提供了详细的代码示例和优化建议。 ... [详细]
  • Java 中的 BigDecimal pow()方法,示例 ... [详细]
  • 本文介绍了Java并发库中的阻塞队列(BlockingQueue)及其典型应用场景。通过具体实例,展示了如何利用LinkedBlockingQueue实现线程间高效、安全的数据传递,并结合线程池和原子类优化性能。 ... [详细]
  • 本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ... [详细]
  • 本文探讨了如何在给定整数N的情况下,找到两个不同的整数a和b,使得它们的和最大,并且满足特定的数学条件。 ... [详细]
  • 2023年京东Android面试真题解析与经验分享
    本文由一位拥有6年Android开发经验的工程师撰写,详细解析了京东面试中常见的技术问题。涵盖引用传递、Handler机制、ListView优化、多线程控制及ANR处理等核心知识点。 ... [详细]
  • 本文详细介绍如何使用 Apache Spark 执行基本任务,包括启动 Spark Shell、运行示例程序以及编写简单的 WordCount 程序。同时提供了参数配置的注意事项和优化建议。 ... [详细]
  • 深入解析Hadoop的核心组件与工作原理
    本文详细介绍了Hadoop的三大核心组件:分布式文件系统HDFS、资源管理器YARN和分布式计算框架MapReduce。通过分析这些组件的工作机制,帮助读者更好地理解Hadoop的架构及其在大数据处理中的应用。 ... [详细]
author-avatar
mobiledu2502931077
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有