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

49 阅读4分钟

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

课程目录:

1. 大数据处理引擎Spark介绍

2. SparkCore原理解析

3. SparkSQL原理解析

4. 业界挑战与实践

1. 大数据处理引擎Spark介绍

1.1 大数据处理技术栈

image.png

1.2 常见大数据处理链路

image.png

1.3 spark生态 & 特点

  • 统一引擎,支持多种分布式场景
  • 多语言支持
  • 可读写丰富数据源
  • 丰富灵魂的API/算子
  • 支持K8S/yarn/Mesos资源调度

1.4 Spark生态组件:

  • 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)上运行。

2. SparkCore原理解析

  • RDD: 弹性分布式数据集,是一个容错的、并行的数据结构

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

  • Transform(转换)算子: 根据已有RDD创建新的RDD

  • Action(动作)算子: 将在数据集上运行计算后的数值返回到驱动程序,从而触发真正的计算

  • DAG: 有向无环图,Spark中的RDD通过一系列的转换算子操作和行动算子操作形成了一个DAG

  • RDD依赖: 描述父子RDD之类的血缘关系,包括宽依赖和窄依赖。

    • 宽依赖: 父RDD可以对应多个子RDD,有shuffle
    • 窄依赖: 父与子RDD为一一对应的关系

有Shuffle的是宽依赖。 窄依赖1对1。宽依赖:新的RDD的一个分区的数据依赖于旧的RDD多个分区的数据(因此会shuffle)

  • DAGScheduler: 将作业的DAG划分成不同的Stage,每个Stage都是TaskSet任务集合,并以TaskSet为单位提交给TaskScheduler。
  • TaskScheduler: 通过TaskSetManager管理Task,并通过集群中的资源管理器(Standalone模式下是Master,Yarn模式下是ResourceManager)把Task发给集群中Worker的Executor
  • Shuffle: Spark中数据重分发的一种机制。

3. SparkSQL原理解析

Catalyst优化器: SparkSQL核心模块,主要是对执行过程中的执行计划进行处理和优化。

  • CBO:基于代价优化
  • RBO:基于规则优化

SparkSql执行过程:

  • Unresolved Logical Plan: 未解析的逻辑计划,仅仅是数据结构,不包含任何数据信息。

  • Logical Plan: 解析后的逻辑计划,节点中绑定了各种优化信息。

  • Optimized Logical Plan: 优化后的逻辑计划

  • Physical Plans: 物理计划列表

  • Selected Physical Plan: 从列表中按照一定的策略选取最优的物理计划

AQE: AQE对于整体的Spark SQL的执行过程做了相应的调整和优化,它最大的亮点是可以根据已经完成的计划结点真实且精确的执行统计结果来不停的反馈并重新优化剩下的执行计划。

AQE框架三种优化场景:

  • 动态合并shuffle分区(Dynamically coalescing shuffle partitions)

  • 动态调整Join策略(Dynamically switching join strategies)

  • 动态优化数据倾斜Join(Dynamically optimizing skew joins)

RuntimeFilter: 实现在Catalyst中动态获取Filter内容做相关优化,当我们将一张大表和一张小表等值连接时,我们可以从小表侧收集一些统计信息,并在执行join前将其用于大表的扫描,进行分区修剪或数据过滤。可以大大提高性能

Runtime优化分两类:

  • 全局优化:从提升全局资源利用率、消除数据倾斜、降低IO等角度做优化。包括AQE。

  • 局部优化:提高某个task的执行效率,主要从提高CPU与内存利用率的角度进行优化。依赖Codegen技术。

4.业界挑战与实践

4.1 Shuffle稳定问题

image.png

4.2 SQL执行性能问题

  • 向量化(vectorization): 将循环转换为向量操作的编译器优化

  • 代码生成(Codegen:Code generation): 生成程序代码的技术或系统,可以在运行时环境中独立于生成器系统使用

4.3 参数推荐/作业诊断: Spark参数很多,参数不合理的作业,对资源利用率/Shuffle稳定性/性能有非常大影响。 自动化参数推荐/作业诊断——自动化