Spark 原理与实践 | 青训营笔记

106 阅读4分钟

这是我参与「第四届青训营 」笔记创作活动的的第7天

大数据处理链路

下面是大数据处理的主要流程: image.png 我们从数据源获取数据并将其存储到系统,这里常见的分布式存储系统有

  1. Kafka:分布式消息队列系统
  2. HDFS:分布式文件系统
  3. HBase:分布式k-v存储系统
  4. S3/TOS:分布式对象存储
  5. ......

数据要展示到应用层需要经过计算,其中读取数据就可以通过上面的存储系统,也可以是MySQL这些,计算则应用到了计算引擎,其中Spark,Hadoop一般用于批计算;Flink用于流式计算;ClickHouse,presto等则用于OLAP场景,最后将计算完成的数据输出到数据应用,就完成了大数据的处理。

Spark作为批计算的主流,我们今天就来了解一下Spark

Spark

Spark运行架构

image.png Spark是以Master-Slave为基础构建的,其中主要的节点对应的功能如下:

  • Cluster Manager:是master的集群管理器,负责控制整个集群、监控Worker Node、资源的调度和管理,同时支持多种多样的模式。
  • Worker Node:负责控制计算节点,并启动执行器(Executor)和Task任务
  • Driver Program:相当与AppMaster,是应用管理者,负责作业的任务调度,也就是JVM进程,他创建SparkContext来控制上下层。

核心组件SparkCore

用户提交任务后,经过SparkCore的处理流程: image.png 用户提交后,会先生成AppMaster,分配资源并创建Executor执行器,在Yarn模式下也可以相当与Driver,而Driver则进行Task管理和分配。

而这个流程的输入和输出全是基于RDD算子的基础上进行的。

RDD

RDD是一个容错的,可以并发运行的数据集,是Spark中最基本的数据处理模型和单元。 RDD的5大特性:

image.png

  1. A list of partitions,每个RDD都会被分区,这些分区运行站在不同的节点上,而每一个分区可以对应一个Task来处理。
  2. A function for computing each split,每个RDD分区都有对应的计算函数,对具体的partition进行计算。
  3. a list of dependencies on other RDDS,每个RDD会依赖其他RDD,RDD转换后都会生成一个新的RDD
  4. a Partitioner for key- alue RDDS,实现了两种分区函数,只有key-value的RDD才会有分区,其他的则为空。
  5. a list of preferred locations to compute each split on,每个分区都有一个优先位置列表,它会存储每个partition的优先位置。

RDD依赖

RDD依赖有两种,分为窄依赖(Narrow deps)和宽依赖(Wide deps) image.png

  • 窄依赖:父RDD只能对应一个子RDD分区,子RDD可能有多个父RDD分区。
  • 宽依赖:父RDD可以对应多个子RDD分区,对RDD做groupBy或者join都会产生宽依赖。

内存机制

image.png

执行器的内存主要有两类,Storage Memory(存储内存)和Execution Memory(执行内存),它们之间可以动态调整,相互借用。

当存储内存空闲时,执行内存可以借用存储内存来使用,反之,执行内存空闲时,存储内存也可以借用。但当Execution需要内存时,可以驱逐Storage使用的内存,Storage需要将内存里的数据存储到本地硬盘,再将内存归还给Execution,而被Execution借用的内存不能被Storage像上面这样驱逐。

SparkSQL

SparkSQL处理流程: image.png

上面的流程基本都是在Spark中的Catalyst进行的

Catalyst优化器

优化策略:

  • RBO
    • 主要有列裁剪,常量累加,谓词下推,动态过滤裁剪,简化表达式等
  • CBO
    • 计算代价,得出一个最优的结果。

在计算过程中可能会使用到延迟数据产生负面影响,于是在3.0版本引入的自适应查询AQE。

AQE

主要有三个优化场景:

  • 动态合并shuffle分区

image.png 我们会根据前面运行完的Stage获取实际partition的大小,这样我们就可以把相邻的几个较小的partition动态合并,这样就减少了Task的处理。

  • 动态调整状态策略

image.png 右表在执行过程中,我们发现经过Filter过滤原本25MB的数据最后只剩下了8MB,不超过10MB的数据大小可以通过BROADCAST合并,这样我们就及时可以改变原来的合并策略,从SMJ调整到BHJ,带来性能的提升。

  • Skew Join优化

image.png Join的某个任务出现了倾斜的问题,可以看到A0的执行时间明显要大于其他的partition,AQE就可以检测这个倾斜数据,将它拆分成多个较小的数据,这样虽然会增加Task,但在执行时间上来看,无疑是会带来优化的。