Spark参数调优&&Tricks

spark对内存有一定的要求,内存不够会因为gc而oom。

1、默认情况下,一个worker的内存0.6用于cache,0.4用于task,可以通过设置该值提高每个worker的cache大小。需要注意的是,如果该值太小,则任务执行时所需的空间太小,就会频繁发生GC,这时候应牺牲cache大小,降低该值,从而使task可以获得更多空间执行。降低该值会提高spill频率。

如前面所说spark.executor.memory决定了每个Executor可用内存的大小,而spark.storage.memoryFraction则决定了在这部分内存中有多少可以用于Memory Store管理RDD Cache数据,剩下的内存用来保证任务运行时各种其它内存空间的需要。

spark.executor.memory默认值为0.6,官方文档建议这个比值不要超过JVM Old Gen区域的比值。这也很容易理解,因为RDD Cache数据通常都是长期驻留内存的,理论上也就是说最终会被转移到Old Gen区域(如果该RDD还没有被删除的话),如果这部分数据允许的尺寸太大,势必把Old Gen区域占满,造成频繁的FULL GC。

如何调整这个比值,取决于你的应用对数据的使用模式和数据的规模,粗略的来说,如果频繁发生Full GC,可以考虑降低这个比值,这样RDD Cache可用的内存空间减少(剩下的部分Cache数据就需要通过Disk Store写到磁盘上了),会带来一定的性能损失,但是腾出更多的内存空间用于执行任务,减少Full GC发生的次数,反而可能改善程序运行的整体性能--<a target=_blank href="http://spark-config.readthedocs.org/en/latest/storage.html">http://spark-config.readthedocs.org/en/latest/storage.html</a>

PS.将RDD设置成MEMORY_ONLY_SER而非MEMORY_ONLY,可以减少GC pauses?


2、设置并行task数,提高reducer效率,在出现 java.lang.OutOfMemoryError时候要考虑(由于RDD无法完全放进内存)

spark.default.parallelism     20

这个在1.0.2版本中会出现java.lang.IllegalArgumentException: Can't zip RDDs with unequal numbers of partitions的错误,这在PR1763已经解决

3、spark临时目录
 spark.local.dir        /data/spark/tmp

在1.0上会被SPARK_LOCAL_DIRS (Standalone, Mesos),LOCAL_DIRS (YARN) 环境变量覆盖

4、spark.akka.frameSize

spark.akka.frameSize: 控制Spark中通信消息的最大容量 (如 task 的输出结果),默认为10M。当处理大数据时,task 的输出可能会大于这个值,需要根据实际数据设置一个更高的值。如果是这个值不够大而产生的错误,可以从 worker的日志 中进行排查。通常 worker 上的任务失败后,master 的运行日志上出现”Lost TID: “的提示,可通过查看失败的 worker 的日志文件($SPARK_HOME/worker/下面的log文件) 中记录的任务的 Serialized size of result 是否超过10M来确定。--<a target=_blank href="http://blog.csdn.net/chenxingzhen001/article/details/11835399">http://blog.csdn.net/chenxingzhen001/article/details/11835399</a>


Tricks:

1、在Graphx中cached的图应该尽快释放掉,但不能在其生成的图之前释放掉,否则会出错,坑了好久。

g0.unpersistVertices(blocking=false)
g0.edges.unpersist(blocking=false)

2、在分布式执行时,最好设置numPartitions数,因为分区数对应着,否则默认只有两个任务在执行

Graph.fromEdges(edges,defaultUser,numPartitions)//以下的有待商榷
distinct([numTasks]))
groupByKey([numTasks])
reduceByKey(func, [numTasks])
aggregateByKey(zeroValue)(seqOp, combOp, [numTasks])
sortByKey([ascending], [numTasks])
join(otherDataset, [numTasks])
cogroup(otherDataset, [numTasks])


3、设置RDD的StorgeLevel为StorageLevel.MEMORY_AND_DISK对集群总内存有限的集群来说很有必要。该参数会将因尺寸过大或内存空间不足而不能放到内存中的RDD的分区存到磁盘

val g0:Graph[(Long,Long),Double]=Graph.fromEdges(e,defaultUsers,StorageLevel.MEMORY_AND_DISK,StorageLevel.MEMORY_AND_DISK).cache()


3、在GraphX执行Pregel时,用边属性存不易发生变的值,点属性存放每轮都会变的值。在vpog执行完后会对点属性进行更新(实际是重新生成一个图,因为图跟RDD一样具有不变性)

4、在Pregel中,如果传进来的原图后续没再用,则应该在Pregel中统计初始消息数时释放掉该图,否则一直占有内存(需要对源码进行小改动)。一张图占有很大的内存,如果后面一段时间不需要用到,且再创建的代价不大(可Checkpoint),则最好释放掉。在WebUI中可以结合Storage界面观察当前内存中的RDD。

Pregel.apply(graph: Graph[VD, ED],
   initialMsg: A,
   maxIterations: Int = Int.MaxValue,
   activeDirection: EdgeDirection = EdgeDirection.Either)
  (vprog: (VertexId, VD, A) => VD,
   sendMsg: EdgeTriplet[VD, ED] => Iterator[(VertexId, A)],
   mergeMsg: (A, A) => A)


6、采用jmap查看jvm的内存分配情况

e.g. jmap -histo [CGEB's PID] |less 


------------------------------------------------------------------------


jstack [Executor PID] |less


7、用mapPartitions代替map、filter



---针对Spark 1.1.0

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值