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

117 阅读5分钟

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

这是我参与「第四届青训营 」笔记创作活动的的第5天,本篇笔记主要是关于第五次大数据课程《Spark 原理与实践》的课堂笔记


Spark介绍

 基于内存进行计算,在map Reduce基础上进行优化而来的批式计算引擎

Spark生态组件

image.png

  • Spark Core:Spark核心组件,它实现了Spark的基本功能,包含任务调度、内存管理、错误恢复、与存储系统交互等模块。
  • Spark SQL:用来操作结构化数据的核心组件,通过Spark SQL可以直接查询Hive、HBase等多种外部数据源中的数据。
  • Spark Structured Streaming:Spark提供的流式计算框架,支持高吞吐量、可容错处理的实时流式数据处理。
  • MLlib:Spark提供的关于机器学习功能的算法程序库,包括分类、回归、聚类、协同过滤算法等,还提供了模型评估、数据导入等额外的功能。
  • GraphX:Spark提供的分布式图处理框架,拥有对图计算和图挖掘算法的API接口以及丰富的功能和运算符。
  • 独立调度器、Yarn、Mesos、Kubernetes:Spark框架可以高效地在一个到数千个节点之间伸缩计算,集群管理器则主要负责各个节点的资源管理工作,为了实现这样的要求,同时获得最大灵活性,Spark支持在各种集群管理器(Cluster Manager)上运行。

特点:

  1. 多语言支持

SQL、Java/Scala、R、Python

  1. 丰富数据源

内置DataSource、自定义DataSource

  1. 丰富的API/算子

RDD、DataFrame

Spark运行架构

image.png

  • 具体过程: 用户创建一个SparkContext,SparkContext连接到Cluster Manager,Cluster Manager根据用户提交时设置的参数,为本次提交分配一定的资源,启动Executor。Driver会将用户程序划分为不同的spage,每个spage会有完全相同的Task,这些Task会分别作用于待处理的数据,之后Driver会向Executor发送Task,配置每个Task的执行环境,开始执行Task,知道所有Task都执行正确或超过执行次数限制。

Spark部署方式

  • Spark Local Mode:本地测试/单进程多线程模式
  • Spark Standalone Mode:需要启动Spark的Standalone集群的Master/Worker
  • On YARN/K8S:依赖外部资源调度器(YARN/K8S)

SparkCore

RDD:容错的,可以并行执行的弹性分布式数据集

RDD算子:对任何函数进行某一项操作都可以认为是一个算子,RDD算子是RDD的成员函数

  1. Transform算子:生成一个新的RDD
  2. Action算子:触发Job 提交

RDD依赖:描述父子RDD之间的依赖关系。

  1. 窄依赖:父RDD的每个partition至多对应一个子RDD分区。
  2. 宽依赖:父RDD的每个partition都可能对应多个子RDD分区。会产生shuffle(数据之间的重分发机制) RDD执行过程:

image.png 划分Stage的整体思路:从后往前推,遇到宽依赖就断开,划分为一个Stage。遇到窄依赖,就将这个RDD加入该Stage中,DAG最后一个阶段会为每个结果的Partition生成一个ResultTask。每个Stage里面的Task数量由最后一个RDD的Partition数量决定,其余的阶段会生成ShuffleMapTask。

内存管理

image.png

Spark 作为一个基于内存的分布式计算引擎,Spark采用统一内存管理机制。重点在于动态占用机制。

  • 设定基本的存储内存(Storage)和执行内存(Execution)区域,该设定确定了双方各自拥有的空间的范围,UnifiedMemoryManager统一管理Storage/Execution内存
  • 双方的空间都不足时,则存储到硬盘;若己方空间不足而对方空余时,可借用对方的空间
  • 当Storage空闲,Execution可以借用Storage的内存使用,可以减少spill等操作, Execution内存不能被Storage驱逐。Execution内存的空间被Storage内存占用后,可让对方将占用的部分转存到硬盘,然后"归还"借用的空间
  • 当Execution空闲,Storage可以借用Execution内存使用,当Execution需要内存时,可以驱逐被Storage借用的内存,可让对方将占用的部分转存到硬盘,然后"归还"借用的空间

SparkSQL

  • 执行过程 image.png 影响SparkSQL性能两大技术:
  1. Optimizer:执行计划的优化,目标是找出最优的执行计划
  1. Runtime:运行时优化,目标是在既定的执行计划下尽可能快的执行完毕。
  • 优化策略
    • Catalyst优化
      1. Rule Based Optimizer(RBO)
      2. Cost Based Optimizer(CBO)
    • AQE
      1. 动态合并shuffle分区(Dynamically coalescing shuffle partitions): 作业运行过程中,根据前面运行完的Stage的MapStatus中实际的partiton大小信息,可以将多个相邻的较小的partiton进行动态合并,由一个Task读取进行处理
      2. 动态调整Join策略(Dynamically switching join strategies)
      3. 动态优化数据倾斜Join(Dynamically optimizing skew joins): AQE根据MapStatus信息自动检测是否有倾斜将大的partition拆分成多个Task进行Join
    • RuntimeFilter 实现在Catalyst中。动态获取Filter内容做相关优化,当我们将一张大表和一张小表等值连接时,我们可以从小表侧收集一些统计信息,并在执行join前将其用于大表的扫描,进行分区修剪或数据过滤。可以大大提高性能
    • Codegen
    1. Expression级别 表达式常规递归求值语法树。需要做很多类型匹配、虚函数调用、对象创建等额外逻辑,这些overhead远超对表达式求值本身,为了消除这些overhead,Spark Codegen直接拼成求值表达式的java代码并进行即时编译

    2. WholeStage级别