【问题标题】:How Spark works internallySpark 内部的工作原理
【发布时间】:2015-08-21 20:54:31
【问题描述】:

我知道 Spark 可以使用 Scala、Python 和 Java 进行操作。此外,RDD 用于存储数据。

但是请解释一下,Spark 的架构是什么以及它在内部是如何工作的。

【问题讨论】:

    标签: apache-spark


    【解决方案1】:

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

    Spark 将 RDD 转换转换为称为 DAG(有向无环图)的东西并开始执行,

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

    • DAG 调度器将算子划分为任务的阶段。一个阶段由基于输入数据分区的任务组成。 DAG 调度程序将操作员流水线化在一起。例如。许多地图操作员可以在一个阶段进行调度。 DAG 调度器的最终结果是一组阶段。

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

    • Worker/Slave 执行任务。

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

    在高层次上,可以对 RDD 应用两种变换,即窄变换和宽变换。宽变换基本上会产生阶段边界。

    窄转换 - 不需要在分区之间打乱数据。例如mapfilter等。

    宽变换 - 需要对数据进行shuffle,例如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 对象(RDD 沿袭)的 DAG,稍后将在调用操作时使用该 DAG。每个 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 图的更多图解视图。

    构建 DAG 后,Spark 调度程序会创建一个物理执行计划。如上所述,DAG 调度程序将图拆分为多个阶段,这些阶段是基于转换创建的。狭窄的转换将被组合在一起(流水线)成一个阶段。因此对于我们的示例,Spark 将创建一个两阶段执行,如下所示:

    然后,DAG 调度程序将阶段提交到任务调度程序。提交的任务数量取决于textFile 中存在的分区数量。 Fox 示例假设我们在此示例中有 4 个分区,那么如果有足够的 slaves/cores,将有 4 组任务并行创建和提交。下图更详细地说明了这一点:

    有关更多详细信息,我建议您观看以下 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

    【讨论】:

    • 嗨,Santish,我有一个简短的问题。您说 reduceByKey 是一个广泛的转换,因为它“需要对数据进行洗牌”。你能详细说明一下你所说的洗牌是什么意思吗?这是否意味着您只是在添加来自不同元组的值,以便“打乱”数据?
    • 这应该给出一个非常详细的图形描述什么是洗牌 - databricks.gitbooks.io/databricks-spark-knowledge-base/content/…
    • @Sathish 很好的解释
    • 解释得很好,但如果你想深入了解它在物理层面的工作原理,请参考此链接jaceklaskowski.gitbooks.io/mastering-apache-spark/…
    【解决方案2】:

    下图显示了 Apache Spark 内部的工作原理:

    【讨论】:

      【解决方案3】:

      以下是我将使用的 Apache Spark 的一些行话。

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

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

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

      DAG:- DAG 代表有向无环图,在当前上下文中,它是运算符的 DAG。

      执行者:-负责执行任务的进程。

      驱动程序:-负责在 Spark 引擎上运行作业的程序/进程

      Master:-驱动程序运行的机器

      Slave:-Executor程序运行的机器

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

      Spark 的代码库很小,系统分为不同的层。每一层都有一些职责。这些层是相互独立的。

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

      Spark 缓存要处理的数据,这让我比 hadoop 快 100 倍。 Spark 是高度可配置的,并且能够利用 Hadoop 生态系统中已经存在的现有组件。这使得 spark 呈指数级增长,并且在短时间内,许多组织已经在生产中使用它。

      【讨论】:

        猜你喜欢
        • 2011-08-29
        • 2014-01-22
        • 1970-01-01
        • 2017-07-06
        • 2018-07-28
        • 2019-06-29
        • 2022-05-21
        • 2019-12-28
        • 1970-01-01
        相关资源
        最近更新 更多