Spark on Yarn:性能调优

转载 2015年07月09日 15:52:38

我们团队一直在对Spark在大规模数据挖掘、机器学习上的应用进行实践和探索,本系列文章是我们在使用Spark on Yarn进行分布式开发的总结,有不足的地方,欢迎大家指正和交流,希望更多的人加入我们。

本文主要分享一下我们之前在开发Softmax Regression算法中的一些性能调优的经验(主要是基于0.6.1版本)。

1. 调优经验

应该说,Spark开发中,具体采用什么调优方法去优化性能,需要根据具体算法和实现而定,适合我们这个问题的方法不一定就适合其他问题,但希望我们的经验可以让其他人少踩点坑,更多的调优方法还可以参考官方文档中的  Configuration  和 Tuning  部分。

(1)配置项的使用

熟悉Hadoop开发的同学应该对配置项不陌生。根据不同问题,调整不同的配置项参数,是比较基本的调优方案。配置项可以在脚本文件中添加,也可以在代码中添加。如果是在代码中添加,则需要在 SparkContext 定义 之前 进行配置项的修改,例如:

1
2
System . setProperty ( "spark.akka.frameSize" , "100" )
val sc = new SparkContext ( args ( 0 ) , "SparkSR" )

其中每一个配置项的修改都通过setProerty来实现。下面介绍几个我们用到的比较重要的配置项:

  • spark.akka.frameSize: 控制Spark中通信消息的最大容量 (如 task 的输出结果),默认为10M。当处理大数据时,task 的输出可能会大于这个值,需要根据实际数据设置一个更高的值。如果是这个值不够大而产生的错误,可以从  worker的日志  中进行排查。通常 worker 上的任务失败后,master 的运行日志上出现”Lost TID: “的提示,可通过查看失败的 worker 的日志文件($SPARK_HOME/worker/下面的log文件) 中记录的任务的 Serialized size of result 是否超过10M来确定。
  • spark.storage.memoryFraction: 控制用于 Spark 缓存的 Java 堆空间,默认值是0.67,即 2/3 的 Java 堆空间用于 Spark 的缓存。如果任务的计算过程中需要用到较多的内存,而 RDD 所需内存较少,可以调低这个值,以减少计算过程中因为内存不足而产生的 GC 过程。在调优过程中我们发现,GC 过多是导致任务运行时间较长的一个常见原因。如果你的任务运行较慢,想确定是否是GC太多导致的,可以在 spark-env.sh 中设置 JAVA_OPTS 参数以打印 GC 的相关信息,设置如下: 

    1
    JAVA_OPTS = " -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps"

    这样如果有GC发生,就可以在master和work的日志上看到。
  • spark.default.parallelism: 控制Spark中的分布式shuffle过程默认使用的task数量,默认为8个。如果不做调整,数据量大时,就容易运行时间很长,甚至是出Exception,因为8个task无法handle那么多的数据。 注意这个值也不是说设置得越大越好。
  • spark.local.dir:Spark 运行时的临时目录,例如 map 的输出文件,保存在磁盘的 RDD 等都保存在这里。默认是 /tmp 这个目录,而一开始我们搭建的小集群上 /tmp 这个目录的空间只有2G,大数据量跑起来就出 Exception (”No space left on device”)了。

(2)Broadcast 变量

Spark 所支持的两种共享变量 (shared variables) 的一种,主要用于共享分布式计算过程中各个 task 都会用到的只读变量,broadcast 变量只会在每台计算机器上保存一份,而不会每个task都传递一份,节省空间,效率也高。Spark 的HadoopRDD 的  实现  中,就采用 broadcast 进行 Hadoop JobConf 的传输。 官方文档的说法  是当task的大小大于20k时,就可以考虑用 broadcast 进行优化。

在我们的实现中,权重矩阵是一个 100 * 1000000 的Float矩阵,Spark 默认进行压缩后大约是400M左右,由于梯度计算时每个样本都需要跟整个权重矩阵进行计算,因此权重矩阵的传输我们通过 broadcast 实现。而由于权重矩阵在每次迭代后都会更新,因此在每次迭代后都会重新 broadcast 一次。每次 worker 读取 broadcast 的时间短则几秒,长则二三十秒,相比序列化传参的方式,要快得多。但是这种实现也不完美,因为每次迭代所传输的 broadcast 变量都会保存在 worker 的内存中,直至内存不够用,spark 才会把旧的 broadcast 变量释放掉,不能提前release掉。

(3)accumulator 变量

另外一种 Spark 所支持的共享变量。accumulator 支持在 worker 端进行对其累加操作 +=,但不能读取数据,类似 hadoop 中的counter,但其除了支持 Int 和 Double 类型外,用户还可以自定义类型,只要该类实现相应接口即可。此外,它还支持 type A += type B,即累加结果的类型和累加的值的类型无须一致。

在解决权重更新的问题时,accumulator 是我们尝试过的一种方式,即在 driver 程序中定义一个保存权重矩阵的 accumulator ,然后 worker 计算的梯度直接通过 += 操作,更新该 accumulator 。但尝试没有成功,在不停的 GC 之后,还没到 worker 执行代码的阶段,程序就挂了。

(4)reduce 和 reduceByKey

reduce 是 Action 操作,reduceByKey 是 Transformation 操作。

reduce 是一种聚合操作,可以把各个 task 的结果汇集到 master 节点,执行自定义的 function 操作。reduce的实现做了优化,可以把同一个task内的结果先在本地执行聚合function,再把结果传给master节点执行聚合操作。但由于始终还是要汇总到master节点,且reduce会把接收到的数据保存到内存直到所有task都完成为止,因此当task很多,task的结果数据又比较大时,master容易造成性能瓶颈。

reduceByKey 也是聚合操作,是根据key聚合对应的value。同样的,在每一个mapper把数据发送给reducer前,会在mapper本地先进行merge,类似mapreduce中的combiner。跟reduce不同的是,reduceByKey不是把数据汇集到master节点,是分布式进行的,因此不会存在reduce那样的性能瓶颈。

在我们的softmax regression算法的实现中,需要对worker上计算的梯度进行累加,由于每个 DataPoint 的特征向量是稀疏向量,其计算所得的梯度矩阵也是稀疏的。故我们把稀疏矩阵按照 (列id,列向量) 的形式进行分发,再通过 reduceByKey 对这些 pair 进行聚合累加,得到梯度矩阵。

2. 总结

当面对的数据规模较大时,调优是必经之路,尤其跟Spark打交道的主要是内存。开发过程中,尤其是性能调优时,Spark 的文档可能无法满足需求,特别是出现各种错误时,往往一头雾水,这时最好还是上  google group  上搜索或提问,他们的回复一般还是比较及时的,而且现在用Spark的人相比以前已经多了起来,你踩到的坑估计很多已经早被人踩过了。另外,本文提到的主要是Spark层面上的调优经验,至于机器学习算法的并行设计方面的经验,还请各位高手不吝指点。

该文章转自于http://www.tuicool.com/articles/FFVFnu

Spark On Yarn:提交Spark应用程序到Yarn

转载自:http://lxw1234.com/archives/2015/07/416.htm  关键字:Spark On Yarn、Spark Yarn Cluster、Spark Yarn Cli...
  • hhl2046
  • hhl2046
  • 2016年06月13日 09:44
  • 850

spark on yarn作业运行的jar包缓存优化

这几天一直在追查spark on yarn的作业运行中的jar包分发,以及执行后的jar包删除的问题。从一开始的毫无头绪,到后来逐渐清晰,到后来通过hadoop的两个很简单的参数配置解决了问题。不得不...

Spark on Yarn:性能调优

1. 调优经验 应该说,Spark开发中,具体采用什么调优方法去优化性能,需要根据具体算法和实现而定,适合我们这个问题的方法不一定就适合其他问题,但希望我们的经验可以让其他人少踩点坑,更多的...

第1章 对运行在YARN上的Spark进行性能调优

第1章  对运行在YARN上的Spark进行性能调优1.1      运行环境Jar包管理及数据本地性原理调优实践1.1.1运行环境Jar包管理及和数据本地性原理在YARN上运行Spark需要在Spa...

Spark2.1.1<性能调优Spark运行时jar从yarn端访问>

1.为什么要让运行时Jar可以从yarn端访问spark2以后,原有lib目录下的大JAR包被分散成多个小JAR包,原来的spark-assembly-*.jar已经不存在每一次我们运行的时候,如果没...
  • Gpwner
  • Gpwner
  • 2017年06月19日 10:55
  • 704

spark性能调优

  • 2017年11月16日 15:42
  • 2.71MB
  • 下载

Spark-on-YARN-A-Deep-Dive-Sandy-Ryza

  • 2015年09月22日 16:40
  • 5.42MB
  • 下载

Spark Streaming:性能调优

Spark Streaming:性能调优

Spark性能优化:资源调优篇

在开发完Spark作业之后,就该为作业配置合适的资源了。Spark的资源参数,基本都可以在spark-submit命令中作为参数设置。很多Spark初学者,通常不知道该设置哪些必要的参数,以及如何设置...

spark性能优化:数据倾斜调优

调优概述 有的时候,我们可能会遇到大数据计算中一个最棘手的问题——数据倾斜,此时Spark作业的性能会比期望差很多。数据倾斜调优,就是使用各种技术方案解决不同类型的数据倾斜问题,以保证Spark...
  • chenjoe
  • chenjoe
  • 2017年06月26日 05:40
  • 105
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Spark on Yarn:性能调优
举报原因:
原因补充:

(最多只允许输入30个字)