一分钟了解spark的调优 (3)

Spark 中 GC 调优的目的是确保只有长寿命的 RDD 存储在 Old 版本中,并且 Young 版本的大小足够存储短命期的对象。这将有助于避免使用完整的 GC 来收集任务执行期间创建的临时对象。可能有用的一些步骤是:

通过收集 GC 统计信息来检查垃圾收集是否太多。如果在任务完成之前多次调用完整的 GC ,这意味着没有足够的可用于执行任务的内存。

如果太小的集合太多,而不是很多主要的 GC ,为 Eden 分配更多的内存将会有所帮助。您可以将 Eden 的大小设置为对每个任务需要多少内存的估计。如果确定 Eden 的大小 E ,那么您可以使用该选项设置年轻一代的大小 -Xmn=4/3*E 。(按比例增加4/3是考虑幸存者地区使用的空间。)

在打印的 GC 统计信息中,如果 OldGen 接近于满,则通过降低减少用于缓存的内存量 spark.memory.fraction; 缓存较少的对象比减慢任务执行更好。或者,考虑减少年轻一代的大小。这意味着 -Xmn 如果您将其设置为如上所述降低。如果没有,请尝试更改 JVM NewRatio 参数的值。许多 JVM 默认为2,这意味着 Old 版本占据堆栈的2/3。它应该足够大,使得该分数超过 spark.memory.fraction。

尝试使用 G1GC 垃圾回收器 -XX:+UseG1GC。在垃圾收集是瓶颈的一些情况下,它可以提高性能. 请注意,对于大型 excutor 的堆大小,通过设置 -XX:G1HeapRegionSize 参数来增加 G1 区域的大小 是非常重要的

例如,如果您的任务是从 HDFS 读取数据,则可以使用从 HDFS 读取的数据块的大小来估计任务使用的内存量。请注意,解压缩块的大小通常是块大小的2或3倍。所以如果我们希望有3或4个任务的工作空间,而 HDFS 块的大小是128MB,我们可以估计 Eden 的大小4*3*128MB。

监控垃圾收集的频率和时间如何随着新设置的变化而变化。

我们的经验表明, GC 调整的效果取决于您的应用程序和可用的内存量。有更多的优化选项 在线描述,但在较高的水平,管理完整的 GC 如何经常发生可以减少开销帮助。

可以通过spark.executor.extraJavaOptions在作业的配置中设置来指定执行器的 GC 调整标志。

集群不会被充分利用,除非您将每个操作的并行级别设置得足够高。自动星火设置的 “地图” 任务的数量根据其大小对每个文件运行(尽管你可以通过可选的参数来控制它 SparkContext.textFile ,等等),以及用于分布式”减少”操作,如: groupByKey 和 reduceByKey ,它采用了最大父 RDD 的分区数。您可以将并行级别作为第二个参数传递(请参阅  文档),或者将 config 属性设置 spark.default.parallelism 为更改默认值。一般来说,我们建议您的群集中每个 CPU 内核有2-3个任务。

有时,您将得到一个 OutOfMemoryError ,因为您的 RDD 不适合内存,而是因为您的其中一个任务的工作集(如其中一个 reduce 任务groupByKey)太大。 Spark 的 shuffle 操作(sortByKey, groupByKey, reduceByKey, join,等)建立每个任务中的哈希表来进行分组,而这往往是很大的。这里最简单的解决方案是增加并行级别,以便每个任务的输入集都更小。 Spark 可以有效地支持短达200 ms 的任务,因为它可以将多个任务中的一个执行者JVM重用,并且任务启动成本低,因此您可以将并行级别安全地提高到集群中的核心数量。

使用 可用的 SparkContext 可以大大减少每个序列化任务的大小,以及在群集上启动作业的成本。如果您的任务使用其中的驱动程序中的任何大对象(例如:静态查找表),请考虑将其变为广播变量。 Spark 打印主机上每个任务的序列化大小,因此您可以查看该任务以决定您的任务是否过大; 一般任务大于20 KB大概值得优化。

数据本地化可能会对 Spark job 的性能产生重大影响。如果数据和在其上操作的代码在一起,则计算往往是快速的。但如果代码和数据分开,则必须移动到另一个。通常,代码大小远小于数据,因此将数据代码从一个地方寄送到另一个地方比一大块数据更快。 Spark 围绕数据局部性的一般原则构建其调度。

数据本地化是指数据和代码处理有多近。根据数据的当前位置有几个地方级别。从最近到最远的顺序:

PROCESS_LOCAL 数据与运行代码在同一个 JVM 中。这是可能的最好的地方

NODE_LOCAL 数据在同一个节点上。示例可能在同一节点上的 HDFS 或同一节点上的另一个执行程序中。这比 PROCESS_LOCAL 因为数据必须在进程之间移动慢一些

NO_PREF 数据从任何地方同样快速访问,并且没有本地偏好

RACK_LOCAL 数据位于同一机架上的服务器上。数据位于同一机架上的不同服务器上,因此需要通过网络发送,通常通过单个交换机发送

ANY 数据在网络上的其他地方,而不在同一个机架中

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpxydd.html