Spark

作者: 圆企鹅i | 来源:发表于2021-05-24 18:18 被阅读0次

    Spark

    Spark 是一种基于内存的快速、通用、可扩展的大数据分析计算引擎。

    特点

    1. Spark 是一种由 Scala 语言开发的快速、通用、可扩展的大数据分析引擎

    2. Spark Core 中提供了 Spark 最基础与最核心的功能

    3. Spark SQL 是 Spark 用来操作结构化数据的组件。通过 Spark SQL,用户可以使用 SQL 或者 Apache Hive 版本的 SQL 方言(HQL)来查询数据。

    4. Spark Streaming 是 Spark 平台上针对实时数据进行流式计算的组件,提供了丰富的 处理数据流的 API。

    由上面的信息可以获知,Spark 出现的时间相对较晚,并且主要功能主要是用于数据计算, 所以其实 Spark 一直被认为是 Hadoop 框架的升级版。

    组成

    1. Driver 执行main函数(主要流程),辅助计算

      Spark 驱动器节点,用于执行 Spark 任务中的 main 方法,负责实际代码的执行工作。

      Driver 在 Spark 作业执行时主要负责:

      1. 将用户程序转化为作业(job)

      2. 在 Executor 之间调度任务(task)

      3. 跟踪 Executor 的执行情况

      4. 通过 UI 展示查询运行情况

      实际上,我们无法准确地描述 Driver 的定义,因为在整个的编程过程中没有看到任何有关Driver 的字眼。所以简单理解,所谓的 Driver 就是驱使整个应用运行起来的程序,也称之为Driver 类

    2. Executor 负责main函数中的复杂计算

      Spark Executor 是集群中工作节点(Worker)中的一个 JVM 进程,负责在 Spark 作业中运行具体任务(Task),任务彼此之间相互独立。Spark 应用启动时,Executor 节点被同时启动,并且始终伴随着整个 Spark 应用的生命周期而存在。如果有 Executor 节点发生了故障或崩溃,Spark 应用也可以继续执行,会将出错节点上的任务调度到其他 Executor 节点上继续运行。

      Executor 有两个核心功能:

      1. 负责运行组成 Spark 应用的任务,并将结果返回给驱动器进程

      2. 它们通过自身的块管理器(Block Manager)为用户程序中要求缓存的 RDD 提供内存式存储。RDD 是直接缓存在 Executor 进程内的,因此任务可以在运行时充分利用缓存数据加速运算。

    3. Master & Worker(独立部署脱离Yarn)

      Spark 集群的独立部署环境中,不需要依赖其他的资源调度框架,自身就实现了资源调度的功能,所以环境中还有其他两个核心组件:Master 和 Worker,这里的 Master 是一个进程,主要负责资源的调度和分配,并进行集群的监控等职责,类似于 Yarn 环境中的 RM, 而Worker 呢,也是进程,一个 Worker 运行在集群中的一台服务器上,由 Master 分配资源对数据进行并行的处理和计算,类似于 Yarn 环境中 NM。

    4. Application Master(独立部署脱离Yarn)

      Hadoop 用户向 YARN 集群提交应用程序时,提交程序中应该包含 Application Master,用于向资源调度器申请执行任务的资源容器 Container,运行用户自己的程序任务 job,监控整个任务的执行,跟踪整个任务的状态,处理任务失败等异常情况。说的简单点就是,Resource Manager(资源)和 Driver(计算)之间的解耦合靠的就是Application Master。

    image

    Spark core

    Spark Core 中提供了 Spark 最基础与最核心的功能,Spark 其他的功能如:Spark SQL, Spark Streaming,GraphX, MLlib 都是在 Spark Core 的基础上进行扩展的

    三大数据结构

    Spark 计算框架为了能够进行高并发和高吞吐的数据处理,封装了三大数据结构,用于 处理不同的应用场景。三大数据结构分别是:

    RDD

    RDD(Resilient Distributed Dataset) : 弹性分布式数据集

    Spark 中最基本的数据处理模型。代码中是一个抽象类,它代表一个弹性的、不可变、可分区、里面的元素可并行计算的集合。

    计算模式类似于stream流/IO流,多个map,flat map,只是提供逻辑,知道collect才正式开始执行(看似循环很多次,实际循环一次)

    不同的是,stream流在一台机上,RDD会分散到多台机去处理

    image

    注意:RDD只是数据计算逻辑

    1. 弹性 存储的弹性:内存与磁盘的自动切换; 容错的弹性:数据丢失可以自动恢复; 计算的弹性:计算出错重试机制; 分片的弹性:可根据需要重新分片。

    2. 分布式:数据存储在大数据集群不同节点上

    3. 数据集:RDD 封装了计算逻辑,并不保存数据

    4. 数据抽象:RDD 是一个抽象类,需要子类具体实现

    5. 不可变:RDD 封装了计算逻辑,是不可以改变的,想要改变,只能产生新的 RDD,在新的 RDD 里面封装计算逻辑

    6. 可分区、并行计算

    代码说明

    /**
     *
     * Internally, each RDD is characterized by five main properties:
     *
     *  - A list of partitions //多分区 多台机分布式并行执行计算
     *  - A function for computing each split //每个分区的计算函数(计算函数相同)
     *  - A list of dependencies on other RDDs //RDD之间的依赖关系,上一个RDD的结果成为这一次的入参
     *  - Optionally, a Partitioner for key-value RDDs (e.g. to say that the RDD is hash-partitioned) //自定义分区器
     *  - Optionally, a list of preferred locations to compute each split on (e.g. block locations for
     *    an HDFS file)//首选位置
     *
     * All of the scheduling and execution in Spark is done based on these methods
     */
    abstract class RDD[T: ClassTag]( @transient private var _sc: SparkContext,@transient private var deps: Seq[Dependency[_]]) extends Serializable with Logging {}
    
    1. 分区列表
      /**
       * Implemented by subclasses to return the set of partitions in this RDD. This method will only
       * be called once, so it is safe to implement a time-consuming computation in it.
       *
       * The partitions in this array must satisfy the following property:
       *   `rdd.partitions.zipWithIndex.forall { case (partition, index) => partition.index == index }`
       *
       * ##### Driver在切分任务的时候 会生成多个小队列 ,每个队列的任务发往不同的机器的Executor
       * ##### 也支持根据partion对任务做部分调整 exp:mapPartitionsWithIndex
       */
      protected def getPartitions: Array[Partition]
    
    1. 分区计算函数
      /**
       * :: DeveloperApi ::
       * Implemented by subclasses to compute a given partition.
       *
       * ##### 每个分区都有自己的计算函数 但如RDD的结构图所示 其实计算函数都是相同的
       */
      @DeveloperApi
      def compute(split: Partition, context: TaskContext): Iterator[T]
    
    1. RDD之间的依赖关系
      /**
       * Implemented by subclasses to return how this RDD depends on parent RDDs. This method will only
       * be called once, so it is safe to implement a time-consuming computation in it.
       *
       * ##### 因为需要接收到的入参由上一个计算的结果决定 所以需要存储RDD之间的依赖关系(类似于java Stream流中的函数入参)
       * ##### 依赖关系也可以是一个依赖多个
       */
      protected def getDependencies: Seq[Dependency[_]] = deps
    
    1. 分区器
      /** 
       *
       * Optionally overridden by subclasses to specify how they are partitioned. 
       *
       * ##### 自定义分区器
       */
      @transient val partitioner: Option[Partitioner] = None
    
    1. 首选位置
      /**
       * Optionally overridden by subclasses to specify placement preferences.
       *
       * ##### 可以根据特殊要求选择计算任务执行的节点 
       * ##### 如:类似于hadoop中,选择MapReduce的计算的节点最好是,计算需要的数据(HDFS在该台机上有副本)和计算任务都在同一个机器上。减少网络IO
       */
      protected def getPreferredLocations(split: Partition): Seq[String] = Nil
    
    累加器

    累加器:分布式共享只写变量

    广播变量

    广播变量:分布式共享只读变量

    Spark Streaming

    Spark Streaming 是 Spark 平台上针对实时数据进行流式计算的组件,提供了丰富的处理 数据流的 API。

    Spark SQL

    Spark SQL 是 Spark 用来操作结构化数据的组件。通过 Spark SQL,用户可以使用 SQL 或者 Apache Hive 版本的 SQL 方言(HQL)来查询数据。

    相关文章

      网友评论

          本文标题:Spark

          本文链接:https://www.haomeiwen.com/subject/tyjojltx.html