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

116 阅读6分钟

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

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

Spark简介

Apache Spark是用于大规模数据处理的统一分析引擎。它提供了Java、Scala、Python和R的高级api,以及支持通用执行图的优化引擎。它还支持一系列丰富的高级工具,包括用于SQL和结构化数据处理的Spark SQL,用于pandas工作负载的Spark上的pandas API,用于机器学习的MLlib,用于图形处理的GraphX,以及用于增量计算和流处理的structured Streaming。

Spark原理

  • Spark应用作为独立的进程集合运行在集群上,由主程序(称为驱动程序Driver Program)中的SparkContext对象协调。
  • 在集群上运行时,SparkContext能连接到多个类型的集群管理器(Spark自己的独立集群管理器,Mesos,YARN或者Kubernets),集群管理器在应用程序之间分配资源。一旦连接成功,Spark需要集群节点中的executors进程为应用程序处理计算和存储数据。接下来发送应用程序的代码给executors。最后SparkContext发送tasks给executors来运行。
  • 集群上的任务是由Driver调度的,driver节点应该和worker距离近一些,最好在一个本地局域网中

capture_20220730132841356.bmp

  • 每个应用获得自己的executor进程,并且executor通过多线程运行tasks。利于数据隔离,但也意味着如果不将数据写入外部存储系统,数据就无法在不同的Spark应用程序(SparkContext的实例)之间共享。

CLuster Manager类型

  • Standalone:一个简单的独立部署模式,可以手动启动一个master和workers,或者运行启动脚本。
  • Apache Mesos:通用的集群管理器,可以运行Hadoop MapReduce和服务应用(不推荐)
  • Hadoop YARN:Hadoop 2和3的资源管理器
  • Kubernets:一个用于自动化部署、扩展和管理容器化应用程序的开源系统

SparkCore

capture_20220730140001441.bmp

RDD(Resilient Distributed Dataset):弹性分布式数据集,表示一个不可变的,可以并行操作的分区的元素集合。

特性:

  • Partition:Partitions列表,分区列表。RDD的分区数量可以指定,在集群中创建时根据集群中CPU核数,在HDFS中根据文件的BLOCK数创建。
  • Compute:Spark RDD中都有一个计算函数,以partition为基本单位
  • Dependencies:RDD依赖列表,每个RDD依赖于其他RDD,相互之间有依赖关系,用于数据恢复,减少计算。
  • Partitioner:实现两种分区函数,基于hash和基于范围range,基于key-value的RDD才有partitioner,非Key-Value的RDD partitioner为空。
  • PreferredLocations:每个分区都有优先位置列表

算子: map、filter、count、cache、persist

创建RDD

  • 内置RDD
  • 自定义RDD

RDD 算子

  • Transform算子:生成新的RDD
  • Action算子:触发Job提交

RDD 依赖(这个地方理解不太够)

  • 窄依赖:父RDD的每个Partition至多对应一个子RDD分区
    • NarrowDependency(找父RDD操作,三种类型如下)
      • OneToOneDependency:一对一的获取父RDD。
      • RangeDependency:inStart(父RDD起始位置), outStart(子RDD起始位置),Length(Range长度)。获取父RDD的partition的规则:子RDD的partition index在父RDD的range内,返回父RDD。
      • PruneDependency:对父RDD的partition做Filter操作。
  • 宽依赖:父RDD的每个partition都可能对应多个子RDD分区。
    • ShuffleDependency

RDD执行流程(还是有问题)

划分Stage,stage是啥?

capture_20220730143645647.bmp

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


作者:青训营官方账号
链接:juejin.cn/post/712390… 来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

调度器

RDD.action->runJob()生成DAG(有向无环图),将DAG提交给DAGScheduler,根据ShuffleDependency切分Stage,并按照依赖顺序调度Stage,为每个Stage生成并提交TaskSet到TaskScheduler,根据调度算法进行调度到executors中进行运行。

内存管理

capture_20220730144243621.bmp

Executor堆内内存内存主要有两类:Storage、Execution 两种内存空间可以动态调整,相互借用。 Executor堆外内存管理相对堆内比较简单。

Shuffle 数据传输

SparkSQL

capture_20220730145551408.bmp

Catalyst优化器

过程:解析逻辑计划 -> 分析逻辑计划 -> 优化逻辑计划 -> 生成物理计划 第二阶段到第三阶段

  • RBO:基于规则的优化,根据规则对节点进行转换 capture_20220730150521951.bmp

    • RuleExecutor:每个Batch代表一个规则,Batch可以执行一次或者进行多次迭代。
    • once:只执行一次
    • FixedPoint:重复执行,直到Plan不再改变,或者执行到达固定次数(默认100次)
    • RBO常用规则:常量累加、谓词下推、列裁剪、动态过滤裁剪、简化条件
    • TransformDown:先序遍历树进行规则匹配
    • TransformUP:后序遍历树进行规则匹配
    • 对于join的优化不能满足
  • CBO:基于代价的优化,根据代价路径不同来选择最优方案。

    • 采集表的statistics:ANALYZE TABLE ... COMPUTE STATISTICS ... FOR CLOLUMNS c1,c2
    • TableStat(原始表) --(FilterEstimation)--> FilterStat --(JoinEstimation)--> JoinStat。TableStat从ANALYZE TABLE获取后续算子的Stat,通过对应的Estimation进行估算算子代价。
    • JoinReorder:重新排列join的循序
    • JoinSelection(Join查询算法):
      • Broadcast Hash Join(BHJ):大表和小表的Join
      • Shuffle Hash Join(SHJ):小表超过10M
      • Sort Merge Join(SMJ):大表之间

Adaptive Query Execution(AQE):自适应查询

capture_20220730152924031.bmp

优化场景:

  • Coalescing Shuffle Partitions(合并Shuffle分区):partition合并

capture_20220730153530684.bmp

  • Switching Join Strategies(转换join策略):例如优化阶段,算子statistics估算不准确,生成计划不是最优,AQE运行过程中动态获取准确的Join的LeftChild/RightChild的实际大小,SML转换为BHL。

  • Optimizing Skew Joins(优化倾斜join):优化数据倾斜,AQE根据MapStauts信息自动检测是否有倾斜,将达额partiton拆分为多个Task进行Join。

capture_20220730154257908.bmp

Runtime Filter

对Join算法的优化,用filter算子进行优化,将filter置于靠近数据源的一端,减少参与数据的量。

Bloom Runtime Filter(3.3版本)

Codegen

从runtime局部优化,提高CPU利用率的优化

  • Experssion capture_20220730155638924.bmp
  • WholeStageCodegen:

capture_20220730160130415.bmp

挑战与实践

Shuffle稳定性解决方案

capture_20220730160908331.bmp

SQL执行性能问题

压榨CPU资源 CPU流水线/分支预测/乱序执行/SIMD/CPU缓存友好 向量化/Codegen

SQL执行性能业界引擎实践

capture_20220730161822416.bmp

SQL执行性能解决方向

capture_20220730161927281.bmp

参数推荐/作业诊断

capture_20220730162047115.bmp