Spark的内部工作

时间:2015-06-07 08:08:12

标签: apache-spark

现在Spark正在进行中。 Spark使用scala语言来加载和执行程序以及python和java。 RDD用于存储数据。但是,我无法理解Spark的架构,它是如何在内部运行的。

请告诉我Spark Architecture以及它如何在内部工作?

3 个答案:

答案 0 :(得分:86)

即使我一直在网上了解Spark的内部,下面是我可以学习和想到的分享,

Spark围绕弹性分布式数据集(RDD)的概念展开,RDD是一个可以并行操作的容错的容错集合。 RDD支持两种类型的操作:转换(从现有数据集创建新数据集)和操作(在数据集上运行计算后将值返回到驱动程序)。

Spark将RDD转换转换为DAG(Directed Acyclic Graph)并开始执行,

在高级别,当在RDD上调用任何操作时,Spark会创建DAG并提交给DAG调度程序。

  • DAG调度程序将运算符划分为任务阶段。阶段由基于输入数据的分区的任务组成。 DAG调度程序将运营商连接在一起。对于例如许多地图运营商可以在一个阶段进行安排。 DAG调度程序的最终结果是一组阶段。

  • 将阶段传递给任务计划程序。任务计划程序通过集群管理器启动任务。(Spark Standalone / Yarn / Mesos)。任务调度程序不知道阶段的依赖关系。

  • Worker在Slave上执行任务。

让我们来看看Spark如何构建DAG。

在高级别,有两种转换可以应用于RDD,即窄转换和广泛转换。宽变换基本上导致阶段边界。

缩小转换 - 不需要跨分区对数据进行混洗。例如,地图,过滤器等。

广泛转型 - 要求对数据进行洗牌,例如reduceByKey等。

我们举一个例子来计算每个严重级别出现的日志消息数量,

以下是以严重性级别

开头的日志文件
INFO I'm Info message
WARN I'm a Warn message
INFO I'm another Info message

并创建以下scala代码以提取相同的

val input = sc.textFile("log.txt")
val splitedLines = input.map(line => line.split(" "))
                        .map(words => (words(0), 1))
                        .reduceByKey{(a,b) => a + b}

此命令序列隐式定义RDD对象的DAG(RDD沿袭),稍后将在调用操作时使用。每个RDD都维护一个指向一个或多个父节点的指针以及有关它与父节点的关系类型的元数据。例如,当我们在RDD上调用val b = a.map()时,RDD b保持对其父a的引用,这是一个沿袭。

为了显示RDD的谱系,Spark提供了一个调试方法 toDebugString()方法。例如,在 splitedLines RDD上执行toDebugString(),将输出以下内容,

(2) ShuffledRDD[6] at reduceByKey at <console>:25 []
    +-(2) MapPartitionsRDD[5] at map at <console>:24 []
    |  MapPartitionsRDD[4] at map at <console>:23 []
    |  log.txt MapPartitionsRDD[1] at textFile at <console>:21 []
    |  log.txt HadoopRDD[0] at textFile at <console>:21 []

第一行(从下面)显示输入RDD。我们通过调用sc.textFile()创建了这个RDD。请参阅下面更多从给定RDD创建的DAG图的示意图。

RDD DAG graph

构建DAG后,Spark调度程序会创建物理执行计划。如上所述,DAG调度程序将图分割为多个阶段,基于变换创建阶段。狭窄的变换将被分组(管道排列)在一起成为一个阶段。因此,对于我们的示例,Spark将创建两个阶段执行,如下所示,

Stages

然后,DAG调度程序将阶段提交到任务调度程序。提交的任务数取决于textFile中存在的分区数。 Fox示例考虑我们在此示例中有4个分区,如果有足够的从属/核心,则会创建并提交4组任务。下图更详细地说明了这一点,

Task execustion

有关更多详细信息,我建议您浏览以下YouTube视频,其中Spark创建者会详细介绍DAG和执行计划以及生命周期。

  1. Advanced Apache Spark- Sameer Farooqui (Databricks)
  2. A Deeper Understanding of Spark Internals - Aaron Davidson (Databricks)
  3. Introduction to AmpLab Spark Internals

答案 1 :(得分:0)

下图显示了Apache Spark的内部工作方式:

enter image description here

答案 2 :(得分:0)

以下是我将使用的来自Apache Spark的一些JARGONS。

工作:-一段代码从HDFS或本地读取一些输入,对数据进行一些计算并写入一些输出数据。

阶段:-工作分为多个阶段。阶段分为Map阶段或reduce阶段(如果您在Hadoop上工作并且想要关联,则更容易理解)。根据计算边界划分各个阶段,不能在单个阶段中更新所有计算(运算符)。它发生在很多阶段。

任务:-每个阶段都有一些任务,每个分区一个任务。在一个执行程序(机器)上的一个数据分区上执行一项任务。

DAG:- DAG代表有向无环图,在当前情况下为DAG运算符。

执行器:-负责执行任务的过程。

驱动程序:-负责通过Spark Engine运行作业的程序/进程

主设备:-运行驱动程序的计算机

从设备:-运行Executor程序的计算机

spark中的所有作业都包含一系列运算符,并在一组数据上运行。作业中的所有运算符都用于构造DAG(有向无环图)。通过尽可能地重新排列和组合运算符来优化DAG。例如,假设您必须提交一个Spark作业,其中包含一个map操作和一个filter操作。 Spark DAG优化器会重新排列这些运算符的顺序,因为过滤会减少要执行映射操作的记录数。

Spark的代码库很小,并且系统分为多个层。每层都有一些责任。各层彼此独立。

enter image description here

  1. 第一层是解释器,Spark使用Scala解释器,并进行了一些修改。
  2. 在Spark控制台中输入代码(创建RDD并应用运算符)时,Spark会创建一个运算符图。
  3. 当用户运行一个动作(如collect)时,该图将提交给DAG Scheduler。 DAG调度程序将运算符图分为(映射和归约)阶段。
  4. 一个阶段由基于输入数据分区的任务组成。 DAG调度程序将运算符流水线在一起以优化图形。例如可以在一个阶段中调度许多地图运算符。此优化是Sparks性能的关键。 DAG调度程序的最终结果是一组阶段。
  5. 这些阶段将传递到任务计划程序。任务计划程序通过集群管理器(Spark Standalone / Yarn / Mesos)启动任务。任务计划程序不了解阶段之间的依赖性。
  6. 工作者在从站上执行任务。每个JOB都会启动一个新的JVM。工人只知道传递给它的代码。

Spark缓存要处理的数据,对我来说,它的速度是hadoop的100倍。 Spark是高度可配置的,并且能够利用Hadoop生态系统中已经存在的现有组件。这使火花呈指数增长,并且不久之后,许多组织已经在生产中使用它。