在实际的基于Spark平台的大数据分析项目中,为提高程序的运行效率,对程序进行优化是必不可少的,本文基于个人在大数据项目中使用Spark进行编程实现的实践经历,针对Spark程序优化问题进行总结,具体内容如下所述。

1. 代码层优化

(1)避免创建多个相同的RDD对象
(2)DAG划分的多个stage中存在相同的RDD对象,则需要将该RDD对象进行缓存,避免重复计算。
(3)代码中存在大小表关联逻辑时,建议使用广播变量(Broadcast)解决。
(4)涉及广播变量的map过程,强烈建议使用mapPartitions函数替代map函数,否则在大规模数据场景下,容易导致集群节点内存溢出甚至节点宕掉。
(5)涉及聚合操作时,合理选择groupByKey()和reduceByKey()、combineBykey()函数,三者的具体差异及使用详见文档(链接:http://blog.csdn.net/zylove2010/article/details/78577333
(6)使用repartition()函数合理调整RDD的分区数,特别是在涉及shuffle操作时,需根据shuffle过程中map和reduce阶段的计算复杂度,增大或减少RDD的分区数,以提高程序的运行效率。总体原则是:合理调整RDD的分区值,充分利用集群分配的计算资源。

2. 任务的资源设置优化

(1)合理设置任务运行时集群分配的资源
一般情况下,集群的计算资源有限,且集群资源是多个任务共享的资源池,为避免集群资源浪费,在向集群申请资源时需综合考虑集群可用资源和预估任务需要的资源。集群资源主要考虑CPU核数和内存大小。
(2)合理设置任务运行时的各种参数
任务提交时,可通过spark-submit指令动态设置相关参数,比如设置JVM的垃圾回收机制、executor心跳连接超时时长等。spark-submit指令的具体使用详见文档(链接:http://blog.csdn.net/zylove2010/article/details/78405295

3. 数据倾斜问题专题优化

数据倾斜问题是指在spark任务的运行过程中,某个shuffle阶段的大量数据被分配给某个或某几个executor进行处理,导致这几个executor的运行时长远远超过其他executor。
由于spark中shuffle阶段之间是串行操作,只有当前阶段的所有任务计算完成后才能进入下一个shuffle阶段,因此当前阶段的运行时长由耗时最长的executor决定,数据倾斜会使得整个Spark任务的耗时过长,甚至有内存溢出的风险导致任务报错。数据倾斜问题对整个程序的性能影响非常大,因此都会将其作为一个spark优化专题进行讲解,详细的优化文章网上有很多,在这里仅抛砖引玉。
(1)数据倾斜问题的原因核查
如何发现spark任务存在数据倾斜问题?常见的方法是通过观察spark任务的运行日志记录进行核查。比如通过spark自带的web UI工具查看正在运行的spark程序的详细状态,若某个stage阶段中有一个executor运行时长远远大于其他executor,则该stage存在数据倾斜问题,可定位到该stage对应的程序代码处进行详细核查。
(2)利用数据预处理方法彻底解决数据倾斜问题
数据倾斜问题的主要原因是数据的分布不均衡导致,常见的解决方法是针对数据的分布不均衡进行预处理操作使其变得均衡。

4. 熟练使用web UI核查spark程序的运行状态

web UI的默认地址为:http://master:8080,在浏览器输入该网址即可,其中master为集群主节点的IP。界面如下图所示:
Spark程序优化及常见报错问题分析

5. 程序运行时出现的各种问题汇总

(1)executor-memory设置偏小(图片截取executor所在节点的资源占用情况)
Spark程序优化及常见报错问题分析
在yarn模式下,executor会直接被kill掉,导致任务运行失败。
解决办法:在提交任务时将executor-memory参数的值调大一些即可解决。

(2)任务的并发度设置太高
Spark程序优化及常见报错问题分析
图中cpu资源占用过高,导致任务堵塞。主要原因是分配的cpu核数有限,但任务的并发度很高,使得cpu处理不过来,出现任务堵塞,最终导致任务失败。
解决办法:定位发生该问题的代码段,通过repartition()方式调低RDD的分区值或者在任务提交时申请更多的cpu核数。

(3)executor假死问题
Spark程序优化及常见报错问题分析
图中出现executor心跳连接超时,导致任务运行失败。主要原因是设置的executor-memory过大或者是partition设置大太小,导致executor端的JVM全局回收时长过长,导致其耗时超过executor的心跳时长,使得master误认为executor端出现异常而将executor 正运行的任务kill掉。
解决办法:定位发生该问题的代码段,合理调整executor-memory和RDD的partition值。

相关文章:

  • 2021-08-16
  • 2021-10-31
  • 2021-11-17
  • 2021-09-05
  • 2021-06-29
  • 2021-03-31
  • 2021-05-04
猜你喜欢
  • 2022-12-23
  • 2021-12-26
  • 2022-01-20
  • 2022-12-23
  • 2021-06-19
相关资源
相似解决方案