如何理解spark调优中的高层通用调优,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。
一,并行度
集群不会被充分利用,除非您将每个操作的并行级别设置得足够高。Spark自动会根据文件的大小,是否可分割等因素来设置map的数目(后面会详细讲解输入格式,同时详细讲解各种输入的map数的决定)。对于分布式reduce操作,例如groupbykey和reducebykey,默认它使用的是分区数最大的父RDD的分区数决定reduce的数目。你也可以通过设置spark.default.parallelism来改变默认值,建议值是每个CPU执行2-3个tasks。
二,Reduce任务的内存使用
有时候内存溢出并不是由于你的RDD不适合放在内存里面,而是由于你的某个task的工作集太大了,比如使用groupbykey的时候reduce任务数据集太大了。Spark的shuffle操作(sortByKey, groupByKey, reduceByKey, join, etc)会构建一个hash表,每个task执行一个分组的数据,单个往往会很大。最简单的改善方法是增加并行度,让每个task的输入变得更小。Spark可以高效的支持短达200ms的任务,因为复用了Executor的JVM,这可以降低启动成本,所以你可以很安全的增加并行度,使其超过你的集群core数目。
三,广播变量
使用spark的广播功能可以大幅度减少每个序列化后的task的大小,也可以减少在集群中执行一个job的代价。如果你的任务中使用了大的对象,比如静态表,可以考虑将它声明成广播变量。在driver节点,spark会打印出每个task序列化后的大小,所以你可以通过查看task的大小判断你的task是否过大,通常task的大小超过20KB就值得调优了。
四,数据本地性
数据的本地性可能会对Spark jobs产生重大影响。如果数据和在其上操作的代码在一起,则计算往往是快速的。但如果代码和数据分开,则必须要有一方进行移动。典型的情况是将序列化后的代码移动到数据所在的地方,因为数据往往比代码大很多。Spark构建调度计划的原则就是数据本地性。
数据本地性就是数据离处理他的代码有多远。根据数据和代码当前的位置,数据本地性等级。从最近到最远的顺序列出如下:
1,PROCESS_LOCAL
数据和代码在同一个JVM中,这是最佳的数据本地性。
2,NODE_LOCAL
数据和代码在相同的节点。比如数据在同一节点的HDFS上,或者在统一节点的Executor上。由于数据要在多个进程间移动,所以比PROCESS_LOCAL稍慢。
3,NO_PREF
数据可以从任何地方快速访问,没有数据本地性。
4,RACK_LOCAL
数据和代码在相同的机架。数据位于同一机架上的不同服务器上,因此需要通过网络发送,通常通过单个交换机发送
5,ANY
数据在网络上的其他地方,而不在同一个机架中。
Spark倾向于调度任务依据最高的数据本地性,但这往往是不可能的。在任何空闲的Executor上没有未处理数据的情况下,Spark会切换到较低的数据本地性。这种情况下会有两个选择:
1),等待CPU空闲,然后在相同的server上启动task。
2),立即在一个需要迁移数据的较远位置启动一个新的task。
Spark的典型处理策略是等待繁忙CPU释放,时间很短。一旦超时,将移动数据到空闲CPU的地方执行任务。每个级别之间的回退等待超时可以在一个参数中单独配置或全部配置。如果任务较长,且数据本地性较差,可以适当调整Spark.locatity超时时间相关的配置。具体配置如下:
属性 |
默认值 |
含义 |
spark.locality.wait |
3s |
超时时间,放弃等待在较低数据本地性新启任务。 |
spark.locality.wait.node |
spark.locality.wait |
NODE_LOCAL等待超时时间 |
spark.locality.wait.process |
spark.locality.wait |
PROCESS_LOCAL等待超时时间 |
spark.locality.wait.rack |
spark.locality.wait |
RACK_LOCAL等待超时时间 |
主要调优就是序列化和内存调优。
看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注亿速云行业资讯频道,感谢您对亿速云的支持。
原创文章,作者:3628473679,如若转载,请注明出处:https://blog.ytso.com/223274.html