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

94 阅读4分钟

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

Lect05. Spark 原理与实践

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

1.1 大数据处理技术栈

数据
计算算子代价
计算执行计划代价
执行计划枚举

1.2 常见大数据处理链路

1.3 开源大数据处理引擎

批式计算:hadoop Map Reduce、hive、Spark

流式计算

OLAP

1.4 什么是Spark?

Apache Spark™ is a multi-language engine for executing data engineering, data science, and machinelearning on single-node machines or clusters.

生态&特点:

支持多语言

  • SparkCore:Spark的核心组件,任务调度、内存管理、错误恢复、与存储系统交互等模块。
  • SparkSQL:操控结构化数据(查询hive、hBase),可查询丰富的数据源
  • Spark Structured Streaming
  • MLlib:机器学习库

1.5 特点:

  • 多语言支持:

    • SQL
    • Java/Scala
    • R
    • Python
  • 丰富的数据源:

    • 内置DataSource
    • 自定义DataSource
  • 丰富的API/算子

    • SparkCore--->RDD
    • SparkSQL--->DataFrame

1.6 Spark运行架构&部署方式

标准master-slave架构

  • Cluster Manager:监控Worker Node,负责资源管理和调度,支持多种模式

  • Worker Node:从节点(Node Manager)启动Executor,Task

    • Executor:实际执行任务
    • Task:实时将状态返回给Driver
  • Driver Program:App manager,一个Java进程。将用户程序划分为不同的Stage,每一个Stage会有一组完全相同的Task

    • 创建一个SparkContext:控制应用生命周期,连接到Cluster Manager

部署方式

  • Spark Local Mode
  • Spark Standalone Mode
  • On YARN / K8S

02. SparkCore原理解析

2.1 SparkCore

2.2 什么是RDD

容错、并行处理的数据集,Spark中最基本的数据处理单元

特点:

  • 并行
  • 计算函数
  • 依赖
  • 分区
  • 优先列表
  • 内存中 缓存数据集

2.2.1 如何创建RDD

  • 内置RDD
  • 自定义RDD

2.2.2 RDD算子

两类RDD算子:

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

2.2.3 RDD依赖

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

  • 窄依赖:父RDD的每个partition至多对应一个子RDD分区

    • NarrowDependency
    • OneToOneDependency
    • RangeDependency
    • PruneDependency
  • 宽依赖(会产生Shuffle):父RDD的每个partition都可能对应多个子RDD分区

    • ShuffleDependency

检查点checkpoint

2.5 Shuffle

2.5.1 SortShuffleManager

每个MapTask生成一个Shuffle数据data文件和一个Index文件

2.5.2 External Shuffle Service

Shuffle write的文件被NodeManager中的Shuffle Service托管,供后续ReduceTask进行Shuffle Fetcb,如果Executor空闲,DRA可以进行回收

03. SparkSQL原理解析

3.1 Catalyst优化器

最主要部分:Optimize

  • RBO

    • RuleExecutor

    • Batch执行策略:

      • Once:只执行一次
      • FixedPoint:重复执行,直到plan不再改变,或者执行达到固定次数(默认100次)
    • 谓词下推

  • CBO

    • Filter Join

    • 正确的join类型

      • Broadcast Hash Join,BHJ
      • Shuffle Hash Join,SHJ
      • Sort Merge Join,SMJ
    • 改变join顺序

3.2 Adaptive Query Execution(AQE),自适应查询

  • Partition合并 (Coalescing Shuffle Partitions)

  • 动态切换join策略(Switching Join Strategies)

    • Catalyst Optimizer优化阶段,算子的statistics估算不准确,生成的执行计划并不是最优
    • AQE运行过程中动态获取准确Join的leftChild/rightChild的实际大小,将SMJ转换为BHJ
  • 优化数据倾斜Join(Optimizing Skew Joins)

    • AQE根据MapStatus信息自动检测是否有倾斜,将大的partition拆分成多个Task进行Join

3.5 Codegen - Expression

表达式:将表达式中的大量虚函数调用压平到一个函数内部,类似手写代码

简单拼成java代码

3.5 Codegen - WholeStageCodegen

算子:火山模型

算子之间大量的虚函数调用,开销大

——将同一个Stage中的多个算子压平到一个函数内部进行执行

04. 业界挑战与实践

4.1 Shuffle稳定性问题

在大规模作业下,开源ExternalShuffleService(ESS)的实现机制容易带来大量随机读导致的磁盘IOPS瓶颈、 Fetch 请求积压等问题,进而导致运算过程中经常会出现 Stage重算甚至作业失败,继而引起资源使用的恶性循环,严重影响SLA。

4.2 SQL执行性能问题

问题:压榨CPU资源

  • CPU流水线/分支预测乱序执行/SIMD/CPU缓存友好l ...
  • Vectorized /Codegen ?
  • C++ / Java ?

4.3 参数推荐/作业推荐

  • Spark参数很多,资源类/Shuffle/Join/Aggl . ..调参难度大
  • 参数不合理的作业,对资源利用率/Shuffle稳定性/性能有非常大影响
  • 同时,线上作业失败/运行慢,用户排查难度大

解决方法:自动参数推荐/作业诊断