这是我参与「第五届青训营 」伴学笔记创作活动的第 21 天
这里是Spark相关内容的介绍。Spark 在大数据处理领域在业界已经成为一个事实标准,同时字节内部离线大数据处理场景都是使用Spark,有丰富的实践经验。本节课首先介绍了 Spark 的定义、版本演进、运行框架以及部署方式,通过提交一个 Spark 任务帮助大家了解使用 Spark 的整体流程。
大数据处理引擎Spark介绍
技术栈
-
应用:BI报表/实时大盘/广告/推荐/...
-
计算:
- Spark/Flink/Presto/Impala/ClickHouse/...
- YARN/K8S
-
存储:
- MetaStore
- Parquet/ORC/DeltaL ake/Hudi/lceberg/...
- HDFS/Kafka/HBase/Kudu/TOS/S3/...
-
数据:
- Volume/Variety/Velocity
- On-Premise/On-Cloud,平台/管理/安全/...
链路
开源大数据处理引擎
什么是Spark
官网: spark.apache.org/ github: github.com/apache/spar…
Unified engine for large -scale data analytics
Apache SparkTM is a multi-language engine for executing data engineering, data science, and machine learning on single-node machines or clusters.
Key features
-
Batch/streaming data:
Unify the processing of your data in batches and real-time streaming, using your preferred language: Python, SQL, Scala, Java or R.
-
SQL analytics:
Execute fast, distributed ANSI SQL queries for dashboarding and ad-hoc reporting.Runs faster than most data warehouses.
-
Data science at scale:
Perform Exploratory Data Analysis (EDA) on petabyte-scale data without having to resort to downsampling
-
Machine learning
Train machine learning algorithms on a laptop and use the same code to scale to fault- tolerant clusters of thousands of machines.
Spark版本演进
Spark生态&特点
- 统一引擎,支持多种分布式场景
- 多语言支持
- 可读写丰富数据源
- 丰富灵活的API/算子
- 支持K8S/YARN/Mesos资源调度
Spark特点
多语言支持
- SQL
- Java
- Scala
- R
- Python
- ...
丰富数据源
-
内置DataSource
- Text
- Parquet/ORC
- JSON/CSV
- JDBS
-
自定义DataSource
- 实现 DataSourceV1N2 API
- HBase/Mongo/ElasticSearch/...
- A community index of third- party packages for Apache Spark. spark-packages.org
丰富的API/算子
-
SparkCore-> RDD
- map/filter/flatMap/mapPartitions
- repartition/groupBy/reduceBy/join/aggregate
- foreach/foreachPartition
- count/max/min
......
-
SparkSQL -> DataFrame
- select/filter/groupBy/agg/join/union/orderBy/...
- Hive UDF/EEXUDF
Spark运行架构&部署方式
标准的主从模式
-
Spark Local Mode
- 本地测试/单进程多线程模式
- spark- sql --master local[*]...
-
Spark Standalone Mode
- 自己启动Master/Slave,不依赖外部的昂,本地自己拉起一个集群模式昂!!!
- 需要启动SparkStandalone集群的Master/Worker
- spark-sql --master spark://{port}
-
On YARNK8S
- 依赖外部资源调度器(YARN/K8S)
- spark-sql --master yarn
- spark-sql --master k8s://https://:
Spark 性能benchmark
TPC-DS/TPC-H benchmark github.com/databricks/…
SparkCore原理解析
RDD
RDD是什么?Represents an immutable, partitioned collection of elements that can be operated on in parallel.
如何创建RDD
RDD的算子
RDD的依赖关系
RDD依赖:描述父子RDD之间的依赖关系(lineage)
-
窄依赖: 父RDD的每个partition至多对应一个子RDD分区 。
- NarrowDependency def getParents(partitionld: Int): Seq[Int]
- OneToOneDependency override def getParents(partitionld: Int): List[Int] = List(partitionld)
- RangeDependency override def getParents(partitionld: Int): List[Int] = if (partitionld >= outStart && partitionld < outStart + length) List(partitionld - outStart + inStart)
- PruneDependency
-
宽依赖(会产生Shuffle): 父RDD的每个partition都可能对应多个子RDD分区。
- ShuffleDependency
RDD执行流程
- Job: RDD action算子触发
- Stage:依据宽依赖划分
- Task: Stage内执行单个partition 任务
调度器
内存管理
- Executor内存主要有两类: Storage、 Execution
- UnifiedMemoryManager统一管 理Storage/Execution内存
- Storage和Execution内存使用是动态调整,可以相互借用
- 当Storage空闲,Execution 可以借用Storage的内存使用,
- 可以减少spill 等操作,Execution 使用的内存不能被Storage驱逐
- 当Execution空闲,Storage 可以借用Execution的内存使用,
- 当Execution需要内存时,可以驱逐被Storage借用的内存,直到
- spark.memory.storageFraction边界
多任务间内存分配
- UnifiedMemoryManager统一管理多 个并发Task的内存分配
- 每个Task获取的内存区间为1/(2*N)~ 1/N,
- N为当前Executor中正在并发运行的task数量
Shuffle
Spark的shuffle是在初始化env的时候,创建ShuffleManager,去对于Shuffle 进行处理
SortShuffleManager
这个就是上面的Shuffle的一个实现方式昂!!!
每个MapTask生成一个Shuffle数据文件和一个index文件
External Shuffle Service
shuffle write的文件被NodeManager中的Shuffle Service托管, 供后续的ReduceTask进行shuffle fetch,如果Executor空闲,则DRA可以进行回收
SparkSQL原理解析
执行流程
Catalyse优化器
解析逻辑计划,优化逻辑计划,生成物理优化
RBO
Rule Based Optimizer
CBO
Cost Based Optimizer
Adaptive Query Execution(AQE)
Coalescing Shuffle Paritions
作业运行过程中,根据前面运行完的Stage的MapStatus中实际的partiton大小信息,可以将多个相邻的较小的partiton进行动态合并,由一个Task读取进行处理
parition动态合并
Switching Join Strategies
问题:Catalyst Optimizer优化阶段,算子的statistics估算不准确,生成的执行计划并不是最优 -> AQE运行过程中动态获取准确Join的leftChild/rightChild的实际大小,将SMJ转换为BHJ
Optimizing Skew Joins
解决数据倾斜问题
AQE根据MapStatus信息自动检测是否有倾斜 -> 将大的partition拆分成多个Task进行Join
spark.sql.adaptive.skewJoin.enabled spark.sql.adaptive.skewJoin.skewedPartitionFactor spark.sql.adaptive.skewJoin.skewedPartitionThresholdInBytes
- Pictures From Databricks Blog: databricks.com/blog/2020/0…
Runtime Filter
Bloom Runtime Filter
tpcds/q16.sql: AND cS1 CS_ call center sk Cc call center sk
Codegen
Expression
WholeStageCodegen
业界挑战与实践
Shuffle稳定性问题
在大规模作业下,开源ExternalShuffleService(ESS)的实现机制容易带来大量随机读导致的磁盘IOPS瓶颈、Fetch 请求积压等问题,进而导致运算过程中经常会出现Stage重算甚至作业失败,继而引起资源使用的恶性循环,严重 影响SLA.
SQL执行性能问题
-
压榨CPU资源
- CPU流水线/分支预测/乱序执行 /SIMD/CPU缓存友好/...
- Vectorized / Codegen ?
- C++ / Java
-
解决方向:
Photon: C++实现的向量化执行引擎
Intel: OAP/gazelle_ plugin github.com/oap-project…
参数推荐/作业诊断
- Spark参数很多,资源类/Shuffle/Join/Agg... 调参难度大
- 参数不合理的作业,对资源利用率/Shuffle稳定性/性能有非常大影响
- 同时,线上作业失败/运行慢,用户排查难度大
解决方案:自动参数推荐/作业诊断
课程总结
- 大数据处理常见链路,Spark特点。
- SparkCore中核心概念RDD,调度机制,内存管理机制,shuffle 机制。
- SQL在Spark引擎中执行的详细流程及优化方案。
- 了解目前业界遇到的挑战,解决方案。
References
- 课程PPT: bytedance.feishu.cn/file/boxcns…
- Pictures From Databricks Blog: databricks.com/blog/2020/0…