Spark 简单性能调优

Yarn方面的调优


1.Yarn资源不足引起Spark应用程序失败

原因:yarn 资源队列不足可能会引起Spak应用程序失败

  • 只有一个程序在运行的时候可以选择将Memory和Cores 都调整到最大,这样最大化的使用资源来快速完成程序的计算,同时简化集群的运维和故障的解决。
  • 吐过提交的Spark 应用程序比较耗时,如均超过10min,而其他的Spark程序都在2min之内执行完成,这时候可以把Spark拥有的资源进行分类(耗时任务和快速任务)。此时可以使用两个线程池,每个线程池都有一个线程。

2.Spark on Yarn 下Executor被Kill

现象:出现以下异常信息:

ExecutorLost Failure (Executor 3 exited caused by one of the task)
Reson:Container killed by Yarn for exceeding memory limits 52.6G of 50G physical 
memory used,Consider boosting Spark.Yarn.Executor.memoryOverhead.

调优方案:spark on yarn 模式下Executor经常被杀死可考虑如下解决方式

  • 移除RDD缓存操作
  • 增加该Job的Spark.storage.memoryFraction 系数值
  • 增加该Job的spark.yarn.Executor.memoryoverhead 值

3.Yarn-Cluster模式下JVM出现OOM

有些Spark作业在Yarn-Clinent模式下是可以运行的,但是在Yarn-Cluster模式下面,会报出JVM的PermGen(永久代)内存溢出的情况。

出现上述问题的原因是:Yarn-Clinent模式下,Driver运行在本地机器上面 ,Spark使用JVM的PermGen的配置,但是Yarn-Cluster模式下面Driver运行在集群上面的某个节点上面的JVM并未经过配置,采用的是默认值需要进行如下配置。

优化方案:

  • 在Spark-Submit脚本中设置PermGen
 - -conf Spark.Deriver.extraJavaOptions="-XX:PermiSize=128M -XX:MaxPermSize=256M"
  • 如果使用的是SparkSQL中采用了大量的or语句,也可能会报JVM Stack Overflow,Jvm栈内存溢出,此时可以把复杂的SQL简化为多个简单的SQL进行处理。

合理设置并行度

并行度就是Spark作业中,每个Stage的Task数量,也就代表了Spark作业在各个阶段(Stage)的并行度,并行度过低会导致集群资源的浪费,比如100个Task设置50个Executor,每个Executor 3个core,那么同时可以跑150个Task,现在只有100个Task,会导致一部分的集群资源的浪费。如果并行度过高的话比如现在是100个Task,并行度为50,那么执行完成这次的任务需要轮询两次才能完成,如果并行度为100,那么轮询一次就可以了。

最佳实践:Task数量至少设置成与Spark Application 的总CPU core个数相同(比如150个CPU core 设置150个Task,一起运行,差不多同一时间运行完毕),通常,在集群当中建议为每个CPU 分配2~3个任务。
例如:这里有150个CPU Core,基本要设置的Task数量为300-500

SparkConf = new SparkConf()
conf.set("Spark.default.parallelism","500")

SparkSQL 参数设置

  1. Spark.sql.Shuffle.Partitions=200,并行度的优化,这个要根据自己实际情况来配置调节
  2. Spark.sql.files.maxPartitionBytes=128M,调节每个Partition的大小,默认128M
  3. Spark.sql.files.openCostInBytes=4M,很多小文件浪费Task,合并成一个Task,提高处理性能
  4. Spark.sql.autoBroadcastJoinThreshold=10M,两个表Shuffle,默认是10M
/**
 * SparkSQL 参数调优
 */
  def main(args: Array[String]): Unit = {
    val conf = new SparkConf()
      .setAppName(this.getClass.getSimpleName)
      .setMaster("local")
      .set("Spark.sql.Shuffle.Partitions","4") // 调节并行度
      .set("Spark.sql.file.maxPartitionBytes","256") // 调节每个Partition的大小
      .set("Spark.sql.file.openCostInBytes","4") // 小文件合并
      .set("Spark.sql.autoBroadcastJoinThreshold","100") // Join时候小表的大小
  }
}

你可能感兴趣的:(Spark系列)