分配资源
分配资源优化Spark作业
分配更多的资源才是性能调优的王道。 在写完一个spark作业后,要进行性能调优的时候,第一件事就是调配更多的资源;如果已经分配到你能力范围内的资源顶端后,公司无法再给你更多资源了;再考虑其他性能优化的点。(笔者后面会写到更多的性能优化的点)
问题来了?
1.分配哪些资源?
2.给哪里分配这些资源?
3.资源分配到多大,算是最大了呢?
1.分配executor、 给每个executor分配cpu、给每个executor分配memory内存、driver memory
2.在生产环境中,提交spark作业时,spark-submit shell脚本里面调整相应的参数
Spark standalone模式,你就应该根据集群中,大概有多少个G的内存,多少CPU core。然后根据实际情况,调节每一个spark作业的资源分配。比如,集群10台机器,每台机器4G内存,4个CPU core。假设设置有40个executor,那么平均每个executor 2G内存,2个CPU core。
3.一个原则:你能使用的资源有多大,就尽量分配到最大(executor数量,几十到上百不等; executor分配到的内存;每个executor分配到的cpu )
怎么分配资源? 哪些资源会提高哪块性能?
1.增加executor:
如果executor的数量少,那么,能够并行执行的task就少,也就是说,application的并行执行能力很弱。
例子:比如有5个executor,每个executor分配了2个cpu core。那么能够同时计算的task就是10个。10个task执行完成后,再换下一批10个task。
增加executor数量后,增加到10个executor,那么能够同时计算的task就是20个。
2.增加每个executor的cpu core:
一样的,增加每个executor的cpu core,也是增加并行能力。
3.增大每个executor的memory内存:
给每个executor加大其内存,也会提升性能。三点:
-
RDD运算过程中,可能会对RDD作cache缓存。此时,如果内存够的话,就可以缓存数据到内存,只让少量的缓存到磁盘,甚至不缓存到磁盘。减少磁盘IO,提高运算性能。
-
task执行过程中,会创建很多对象。如果内存很小,可能导致JVM频繁GC,速度会很慢。内存加大后,GC减少,性能提高。
task是怎么生成的呢?
粗粒度的说,SparkContext, DAGScheduler, TaskScheduler 会将spark作业里的所有算子,切割成许多task,提交到application的executor去执行。 -
数据处理过程中,shuffle操作时,在reduce(聚合数据)端,也需要内存存放拉取到的数据,并进行聚合。如果内存不够,那数据也会写入磁盘。反之,如果给executor分配更多内存,那就只有少量数据写入磁盘,甚至不需要写入磁盘。减少磁盘IO,提高运算性能。
结论
我们在通过分配资源提高spark作业性能时,要清楚地知道调整哪些资源会对应提升哪块性能。这样有针对性调整资源,提高spark作业性能。