Spark 性能优化:资源分配

性能调优的王道是分配更多的资源,当目前资源够用的情况下,分配的资源越充分,在性能和速度上的提升越明显。当资源无法分配更多时候才会去考虑后续的一些调优手段。

一,分配的资源有哪些?

1,分配的 executor 数量;

2,每个 executor 需要的 core 数量;

3,每个 executor 需要的内存大小;

4,driver 的内存大小 (这个影响不大) ;

二,在哪里去配置这些资源?

提交 spark 作业时,用的 spark-submit 的 shell 脚本,里面有对应的参数:

—num-executors 3 \ 配置的 executor 数量

—driver-memory 100m \配置的 driver 内存

— executor-memory 100m \配置每个 executor 的内存大小

— executor-cores 3 \配置的每个 executor 的核心数量

三,调节到什么程度最好呢?

第一种,Spark Standalone 模式。公司搭建的 Spark 集群上,有多少台机器,每台机器有多少的内存,每台机器的 cpu 是几核的,这些参数要有数,然后根据这些参数去分配 Spark 作业的资源分配。

比如说,集群上有 20 台机器,每台有 4g 内存,每台的 cpu 有两个核心。那么可以这么分配资源:20 个 executor,每个 executor 分配 4g 的内存和 2 个 core。

第二种,使用 Yarn 作为资源调度的集群。这种集群,需要去查看你的 Spark 作业提交到的资源队列大概有多少资源,然后分配。

比如说,该资源队列有 500g 的内存,100 个 cpu 核心。那么可以分配 50 个 executor,每个 executor 分配 10g 的内存和 2 个 core。

四,提升性能的原因

1,Spark 应用启动在 Driver 进程中,所以 Driver 内存的分配大一些可以适当提升 Driver 进程的执行速度;

2,Spark 应用会被拆分成多个 job,每个 job 又会被划分成多个 stage,每个 stage 会被分配多个 task 去执行。这些 task 最后都会被分配到 worker 上的 executor 进程中执行,每个 task 在 executor 进程中是一个线程在执行。

这样就可以看出,如果集群资源充分的话,executor的数量越多,执行速度就越快。

当 executor 所在进程的 JVM 分配的核心越多(要配合该 worker 节点的 cpu 核心数量来定),越有助于提升执行效率,因为 executor 内部执行任务的 task 线程是并发执行的,在 worker 节点的 cpu 核心数量越多的情况下,并行度就越高。

另外,由于 Spark 应用有时会需要对 RDD 进行 cache 操作,shuffle 操作的 map 端和 reduce 端需要存放数据,在 task 执行的时候也会创建出很多的对象,这三个因素都需要内存,所以内存大也会提升 Spark 的性能。