0%

spark on yarn遇到的问题

本文主要包括:

  • 以yarn-client方式提交spark任务,任务一直卡在ACCEPTED状态
  • spark on yarn任务提交缓慢解决

以yarn-client方式提交spark任务,任务一直卡在ACCEPTED状态

问题背景

spark是以客户端的方式安装的,并没有启动spark的mesos集群,这时候的spark就相当与hive客户端。
以local模型和yarn-cluster方式提交任务,都能正确额执行,但是一yarn-client方式就卡在ACCEPTED

问题原因

在网上查了资料,都说是资源不够用,需要调整yarn.scheduler.capacity.maximum-am-resource-percent从0.1改成0.5,
但是我测试数据才几k,集群内存128G,所以我直接排除了这个原因。后来想到,只有yarn-client方式失败,那问题应该出来driver端。
就查看了一下服务器的/etc/hosts,发现diver上有集群其他节点的IP等信息,但是其他节点没有driver配置信息,导致driver能访问到集群,
但是集群其他节点访问不了driver,所以local模式可以执行
yarn-cluster上可以执行,是因为客户端只要把任务提交到yarn上,客户端就没有用了。
但是yarn-client方式,客户端是充当了driverdriver需要一直和集群有通信,所以接收不到resouceManager的反馈。任务就一直卡住了

解决办法:

有两个方法:
1、在命令后面加上一个–conf spark.driver.host=$your_ip_address,后面直接填客户端机器的IP地址就行

spark-submit \ 
        --master yarn \
        --deploy-mode client \
        --num-executors 2 \
        --executor-memory 1G \
        --executor-cores 1 \
        --conf spark.driver.host=192.168.72.129\
         dmp_broadcast_data_day.py
 ```   
   2、在集群其他节点上都把driver服务器的IP加上去。

# spark on yarn任务提交缓慢解决
## 问题背景
   在使用pyspark提交任务导yarn上的时候,每次提交任务,都要等待好长时间,但是在之前公司中,提交任务导yarn上很快的,所以就调查了一下
   在提交任务的时候,有一个WARN的日志:
```shell
    WARN yarn.Client: Neither spark.yarn.jars nor spark.yarn.archive is set, falling back to uploading libraries under SPARK_HOME.

在网上查了一下,每一次我们运行的时候,如果没有指定 spark.yarn.archive or spark.yarn.jars,Spark将在安装路径下的Jar目录,将其所有的Jar包打包然后将其上传到分布式缓存
官网的原话:

To make Spark runtime jars accessible from YARN side, you can specify spark.yarn.archive or spark.yarn.jars. For details please refer to Spark Properties. If neither spark.yarn.archive nor spark.yarn.jars is specified, Spark will create a zip file with all jars under $SPARK_HOME/jars and upload it to the distributed cache.

调优方法

  • 首先将Spark安装路径下的所有jar包上传到HDFS上
  • 在spark的conf目录下的spark-defaults.conf添加
    spark.yarn.archive               hdfs://ycluster-3/data/hadoop/spark-jars/*jar

    有个bug

    我记得我当时按照这个步骤修改完,提交任务导yarn上之后,会报以下错误
    ERROR SparkContext: Error initializing SparkContext.
    org.apache.spark.SparkException: Yarn application has already ended! It might have been killed or unable to launch application master.
        at org.apache.spark.scheduler.cluster.YarnClientSchedulerBackend.waitForApplication(YarnClientSchedulerBackend.scala:85)
        at org.apache.spark.scheduler.cluster.YarnClientSchedulerBackend.start(YarnClientSchedulerBackend.scala:62)
        at org.apache.spark.scheduler.TaskSchedulerImpl.start(TaskSchedulerImpl.scala:156)
        at org.apache.spark.SparkContext.<init>(SparkContext.scala:509)
        at org.apache.spark.SparkContext$.getOrCreate(SparkContext.scala:2313)
        at org.apache.spark.sql.SparkSession$Builder$$anonfun$6.apply(SparkSession.scala:868)
        at org.apache.spark.sql.SparkSession$Builder$$anonfun$6.apply(SparkSession.scala:860)
        at scala.Option.getOrElse(Option.scala:121)
        at org.apache.spark.sql.SparkSession$Builder.getOrCreate(SparkSession.scala:860)
        at org.apache.spark.repl.Main$.createSparkSession(Main.scala:95)
    这里以前忘记怎么修复的了,现在果然又遇到了,查了很多资料,总结出两点:
  • spark-env.sh文件中的HADOOP_CONF_DIR配置错误
  • yarn的虚拟内存超限,contrainer被干杀死

这里查了一下,我的是spark-end.sh配置没问题,问题出现在第二点
我的yarn-site.xmlyarn.nodemanager.vmem-pmem-ratio=2.1,虚拟内存最大是2.1,查看yarn上的日志,发现实际内存是2.2,所以,这里把它设置成了3.1

<!--2个配置只用配置一个即可解决问题,当然都配置也没问题-->
<!--虚拟内存设置是否生效,若实际虚拟内存大于设置值 "-->
<property>
    <name>yarn.nodemanager.vmem-check-enabled</name>
    <value>false</value>
    <description>Whether virtual memory limits will be enforced for containers</description>
</property>
<!--配置虚拟内存/物理内存的值,默认为2.1,物理内存默认应该是1g,所以虚拟内存是2.1g-->
<property>
    <name>yarn.nodemanager.vmem-pmem-ratio</name>
    <value>3.1</value>
    <description>Ratio between virtual memory to physical memory when setting memory limits for containers</description>
</property>