Spark on Yarn遇到的几个问题
1 概述
Spark的on Yarn模式。其资源分配是交给Yarn的ResourceManager来进行管理的。可是眼下的Spark版本号,Application日志的查看,仅仅能通过Yarn的yarn logs命令实现。
在部署和执行Spark Application的过程中,假设不注意一些小的细节,或许会导致一些问题的出现。
2 防火墙
部署好Spark的包和配置文件,on yarn的两种模式都无法执行,在NodeManager端的日志都是说Connection Refused,连接不上Driver所在的client节点,可是client的80port能够正常訪问!同一时候,在日志中有类似信息出现:
Initial job has not accepted any resources; check your cluster UI to ensure that workers are registered and have sufficient memory
内存肯定是够的。但就是无法获取资源。检查防火墙,果然client仅仅开启的对80port的訪问,其它都禁止了!
假设你的程序在执行的时候也有类似连接被拒绝的情况。最好也是先检查下防火墙的配置!
3 Spark Driver程序host的指定
部署完Spark后,分别使用yarn-cluster模式和yarn-client模式执行Spark自带的计算pi的演示样例。
Spark的一些配置文件除了一些基本属性外,均未做配置,结果执行的时候两种执行模式出现了不同的状况。
yarn-cluster模式可以正常执行,yarn-client模式总是执行失败。查看ResourceManager、NodeManager端的日志。发现程序总是找不到ApplicationMaster,这就奇怪了!
而且,客户端的Driver程序开启的port。在NodeManager端訪问被拒绝。非Spark的其它MR任务。可以正常执行。
检查client配置文件。发现原来在client的/etc/hosts文件里。client的一个IP相应了多个Host,Driver程序会默认去取最后相应的那个Host,比方是hostB,可是在NodeManager端是配置的其它Host。hostA。所以导致程序无法訪问。为了不影响其它的程序使用client的Host列表,这里在Spark配置文件spark-defaults.conf中使用属性spark.driver.host来指定yarn-client模式执行中和Yarn通信的DriverHost。此时yarn-client模式能够正常执行。
上面配置完了之后,发现yarn-cluster模式又不能执行了!
想想原因,肯定是上面那个配置參数搞的鬼,凝视掉之后,yarn-cluster模式能够继续执行。原因是,yarn-cluster模式下。spark的入口函数是在client执行,可是Driver的其它功能是在ApplicationMaster中执行的。上面的那个配置相当于指定了ApplicationMaster的地址,实际上的ApplicationMaster在yarn-master模式下是由ResourceManager随机指定的。
4 on Yarn日志的查看
測试环境下,通过yarn logs -applicationId xxx能够查看执行结束的Application的日志,可是搞到还有一个环境下发现使用上述命令查看日志时,总是提演示样例如以下信息:
Logs not available at /tmp/nm/remote/logs/hadoop/logs/application_xxx_xxx
Log aggregation has not completed or is not enabled.
去相应的NodeManger文件夹下,确实找不到日志文件。
可是/tmp/nm/remote/logs却是在yarn-site.xml中指定了的文件夹。这个是对的,究竟什么原因呢?难道是Yarn的日志聚集没有起作用?
去NodeManager上查看相应Application的日志:
2014-08-04 09:14:47,513 INFO org.apache.hadoop.yarn.server.nodemanager.containermanager.logaggregation.AppLogAggregatorImpl: Starting aggregate log-file for app application_xxx_xxx at /tmp/nm/remote/logs/spark/logs/application_xxx_xxx/hostB.tmp2014-08-04 09:14:47,525 INFO org.apache.hadoop.yarn.server.nodemanager.containermanager.logaggregation.AppLogAggregatorImpl: Uploading logs for container container_xxx_xxx_01_000007. Current good log dirs are /data/nm/log2014-08-04 09:14:47,526 INFO org.apache.hadoop.yarn.server.nodemanager.containermanager.logaggregation.AppLogAggregatorImpl: Uploading logs for container container_xxx_xxx_000001. Current good log dirs are /data/nm/log2014-08-04 09:14:47,526 INFO org.apache.hadoop.yarn.server.nodemanager.DefaultContainerExecutor: Deleting path : /data/nm/log/application_xxx_xxx2014-08-04 09:14:47,607 INFO org.apache.hadoop.yarn.server.nodemanager.containermanager.logaggregation.AppLogAggregatorImpl: Finished aggregate log-file for app application_xxx_xxx
可见,日志聚集确实起作用了,可是为什么通过命令不能查看!
猛然见看到日志中“/tmp/nm/remote/logs/spark/logs/ application_xxx_xxx/hostB.tmp”。日志的路径有问题,在使用yarn logs命令查看的时候。用的是hadoop用户。实际Spark Application的提交运行用的是spark用户,而yarn logs命令默认去找的是当前用户的路径,这就是查看不到日志的原因。切换到spark用户再查看,日志最终出来了。
5 LZO相关问题
假设在Spark中使用了LZO作为EventLog的的压缩算法等,就得实现安装好LZO这个东东,否则会出现类似于例如以下的异常:
Caused by: java.lang.IllegalArgumentException: Compression codec com.hadoop.compression.lzo.LzoCodec not found.at org.apache.hadoop.io.compress.CompressionCodecFactory.getCodecClasses(CompressionCodecFactory.java:134)at org.apache.hadoop.io.compress.CompressionCodecFactory.<init>(CompressionCodecFactory.java:174)at org.apache.hadoop.mapred.TextInputFormat.configure(TextInputFormat.java:45)... 66 moreCaused by: java.lang.ClassNotFoundException: Class com.hadoop.compression.lzo.LzoCodec not foundat org.apache.hadoop.conf.Configuration.getClassByName(Configuration.java:1680)at org.apache.hadoop.io.compress.CompressionCodecFactory.getCodecClasses(CompressionCodecFactory.java:127)... 68 more
或者
[ERROR] [2014-08-05 10:34:41 933] com.hadoop.compression.lzo.GPLNativeCodeLoader [main] (GPLNativeCodeLoader.java:36) Could not load native gpl libraryjava.lang.UnsatisfiedLinkError: no gplcompression in java.library.path
解决的方法就是得安装好LZO,而且在HDFS、SPARK中配置好相关的包、文件等,详细步骤见:
http://find.searchhub.org/document/a128707a98fe4ec6
https://github.com/twitter/hadoop-lzo/blob/master/README.md
http://hsiamin.com/posts/2014/05/03/enable-lzo-compression-on-hadoop-pig-and-spark/
6 Spark Hive无法訪问Mysql的问题
生产环境下,节点之间肯定是有防火墙限制的。并且Hive的元数据库Mysql,更是对请求的IP和用户等限制的严格,假设在Spark集群中使用yarn-cluster模式进行提交Spark的Application。其执行时Driver是和ApplicationMaster执行在一起。由Yarn的ResourceManager负责分配到集群中的某个NodeManager节点上,假设在Hive-site.xml中仅仅配置了Mysql数据库而没有配置MetaStore的话,或许会遇到连接元数据库失败的问题,此时,就得看下Hive-site.xml的配置,是否Mysql的相关权限配置正确、MetaStore服务能否够正常连接。
7 内存溢出问题
在Spark中使用hql方法运行hive语句时。因为其在查询过程中调用的是Hive的获取元数据信息、SQL解析,而且使用Cglib等进行序列化反序列化。中间可能产生较多的class文件,导致JVM中的持久代使用较多,假设配置不当,可能引起类似于例如以下的OOM问题:
Exception in thread "Thread-2" java.lang.OutOfMemoryError: PermGen space
原因是实际使用时。假设用的是JDK1.6版本号,Server模式的持久代默认大小是64M,Client模式的持久代默认大小是32M,而Driver端进行SQL处理时。其持久代的使用可能会达到90M,导致OOM溢出。任务失败。
解决方法就是在Spark的conf文件夹中的spark-defaults.conf里。添加对Driver的JVM配置。由于Driver才负责SQL的解析和元数据获取。
配置例如以下:
spark.driver.extraJavaOptions -XX:PermSize=128M -XX:MaxPermSize=256M
可是,上述情况是在yarn-cluster模式下出现。yarn-client模式执行时倒是正常的。原来在$SPARK_HOME/bin/spark-class文件里已经设置了持久代大小:
JAVA_OPTS="-XX:MaxPermSize=256m $OUR_JAVA_OPTS"
当以yarn-client模式执行时。driver就执行在客户端的spark-submit进程中。其JVM參数是取的spark-class文件里的设置,所谓未出现持久代溢出现象。
总结一下Spark中各个角色的JVM參数设置:
(1)Driver的JVM參数:
-Xmx。-Xms,假设是yarn-client模式,则默认读取spark-env文件里的SPARK_DRIVER_MEMORY值,-Xmx,-Xms值一样大小;假设是yarn-cluster模式。则读取的是spark-default.conf文件里的spark.driver.extraJavaOptions相应的JVM參数值。
PermSize,假设是yarn-client模式,则是默认读取spark-class文件里的JAVA_OPTS="-XX:MaxPermSize=256m $OUR_JAVA_OPTS"值;假设是yarn-cluster模式。读取的是spark-default.conf文件里的spark.driver.extraJavaOptions相应的JVM參数值。
GC方式,假设是yarn-client模式,默认读取的是spark-class文件里的JAVA_OPTS。假设是yarn-cluster模式,则读取的是spark-default.conf文件里的spark.driver.extraJavaOptions相应的參数值。
以上值最后均可被spark-submit工具中的--driver-java-options參数覆盖。
(2)Executor的JVM參数:
-Xmx,-Xms。假设是yarn-client模式,则默认读取spark-env文件里的SPARK_EXECUTOR_MEMORY值,-Xmx。-Xms值一样大小。假设是yarn-cluster模式,则读取的是spark-default.conf文件里的spark.executor.extraJavaOptions相应的JVM參数值。
PermSize。两种模式都是读取的是spark-default.conf文件里的spark.executor.extraJavaOptions相应的JVM參数值。
GC方式。两种模式都是读取的是spark-default.conf文件里的spark.executor.extraJavaOptions相应的JVM參数值。
(3)Executor数目及所占CPU个数
假设是yarn-client模式。Executor数目由spark-env中的SPARK_EXECUTOR_INSTANCES指定,每一个实例的数目由SPARK_EXECUTOR_CORES指定;假设是yarn-cluster模式。Executor的数目由spark-submit工具的--num-executors參数指定,默认是2个实例,而每一个Executor使用的CPU数目由--executor-cores指定,默觉得1核。
每一个Executor执行时的信息能够通过yarn logs命令查看到,类似于例如以下:
14/08/13 18:12:59 INFO org.apache.spark.Logging$class.logInfo(Logging.scala:58): Setting up executor with commands: List($JAVA_HOME/bin/java, -server, -XX:OnOutOfMemoryError='kill %p', -Xms1024m -Xmx1024m , -XX:PermSize=256M -XX:MaxPermSize=256M -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintHeapAtGC -Xloggc:/tmp/spark_gc.log, -Djava.io.tmpdir=$PWD/tmp, -Dlog4j.configuration=log4j-spark-container.properties, org.apache.spark.executor.CoarseGrainedExecutorBackend, akka.tcp://spark@sparktest1:41606/user/CoarseGrainedScheduler, 1, sparktest2, 3, 1>, <LOG_DIR>/stdout, 2>, <LOG_DIR>/stderr)
当中。akka.tcp://spark@sparktest1:41606/user/CoarseGrainedScheduler表示当前的Executor进程所在节点,后面的1表示Executor编号。sparktest2表示ApplicationMaster的host,接着的3表示当前Executor所占用的CPU数目。
8 序列化异常
在Spark上运行hive语句的时候,出现类似于例如以下的异常:
org.apache.spark.SparkDriverExecutionException: Execution errorat org.apache.spark.scheduler.DAGScheduler.handleTaskCompletion(DAGScheduler.scala:849)at org.apache.spark.scheduler.DAGSchedulerEventProcessActor$$anonfun$receive$2.applyOrElse(DAGScheduler.scala:1231)at akka.actor.ActorCell.receiveMessage(ActorCell.scala:498)at akka.actor.ActorCell.invoke(ActorCell.scala:456)at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:237)at akka.dispatch.Mailbox.run(Mailbox.scala:219)at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(AbstractDispatcher.scala:386)at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107) Caused by: java.lang.ClassCastException: scala.collection.mutable.HashSet cannot be cast to scala.collection.mutable.BitSetat org.apache.spark.sql.execution.BroadcastNestedLoopJoin$$anonfun$7.apply(joins.scala:336)at org.apache.spark.rdd.RDD$$anonfun$19.apply(RDD.scala:813)at org.apache.spark.rdd.RDD$$anonfun$19.apply(RDD.scala:810)at org.apache.spark.scheduler.JobWaiter.taskSucceeded(JobWaiter.scala:56)at org.apache.spark.scheduler.DAGScheduler.handleTaskCompletion(DAGScheduler.scala:845)
排查其前后的日志。发现大都是序列化的东西:
14/08/13 11:10:01 INFO org.apache.spark.Logging$class.logInfo(Logging.scala:58): Serialized task 8.0:3 as 20849 bytes in 0 ms 14/08/13 11:10:01 INFO org.apache.spark.Logging$class.logInfo(Logging.scala:58): Finished TID 813 in 25 ms on sparktest0 (progress: 3/200)
而在spark-default.conf中,事先设置了序列化方式为Kryo:
spark.serializer org.apache.spark.serializer.KryoSerializer
依据异常信息,可见是HashSet转为BitSet类型转换失败。Kryo把松散的HashSet转换为了紧凑的BitSet,把序列化方式凝视掉之后,任务能够正常运行。难道Spark的Kryo序列化做的还不到位?此问题须要进一步跟踪。
9 Executor僵死问题
执行一个Spark任务,发现其执行速度远远慢于执行相同SQL语句的Hive的执行,甚至出现了OOM的错误,最后卡住达几小时!
而且Executor进程在疯狂GC。
截取其一Task的OOM异常信息:
能够看到这是在序列化过程中发生的OOM。
依据节点信息。找到相应的Executor进程,观察其Jstack信息:
Thread 36169: (state = BLOCKED)- java.lang.Long.valueOf(long) @bci=27, line=557 (Compiled frame)- com.esotericsoftware.kryo.serializers.DefaultSerializers$LongSerializer.read(com.esotericsoftware.kryo.Kryo, com.esotericsoftware.kryo.io.Input, java.lang.Class) @bci=5, line=113 (Compiled frame)- com.esotericsoftware.kryo.serializers.DefaultSerializers$LongSerializer.read(com.esotericsoftware.kryo.Kryo, com.esotericsoftware.kryo.io.Input, java.lang.Class) @bci=4, line=103 (Compiled frame)- com.esotericsoftware.kryo.Kryo.readClassAndObject(com.esotericsoftware.kryo.io.Input) @bci=158, line=732 (Compiled frame)- com.esotericsoftware.kryo.serializers.DefaultArraySerializers$ObjectArraySerializer.read(com.esotericsoftware.kryo.Kryo, com.esotericsoftware.kryo.io.Input, java.lang.Class) @bci=158, line=338 (Compiled frame)- com.esotericsoftware.kryo.serializers.DefaultArraySerializers$ObjectArraySerializer.read(com.esotericsoftware.kryo.Kryo, com.esotericsoftware.kryo.io.Input, java.lang.Class) @bci=4, line=293 (Compiled frame)- com.esotericsoftware.kryo.Kryo.readObject(com.esotericsoftware.kryo.io.Input, java.lang.Class, com.esotericsoftware.kryo.Serializer) @bci=136, line=651 (Compiled frame)- com.esotericsoftware.kryo.serializers.FieldSerializer$ObjectField.read(com.esotericsoftware.kryo.io.Input, java.lang.Object) @bci=143, line=605 (Compiled frame)- com.esotericsoftware.kryo.serializers.FieldSerializer.read(com.esotericsoftware.kryo.Kryo, com.esotericsoftware.kryo.io.Input, java.lang.Class) @bci=44, line=221 (Compiled frame)- com.esotericsoftware.kryo.Kryo.readObject(com.esotericsoftware.kryo.io.Input, java.lang.Class, com.esotericsoftware.kryo.Serializer) @bci=136, line=651 (Compiled frame)- com.esotericsoftware.kryo.serializers.FieldSerializer$ObjectField.read(com.esotericsoftware.kryo.io.Input, java.lang.Object) @bci=143, line=605 (Compiled frame)- com.esotericsoftware.kryo.serializers.FieldSerializer.read(com.esotericsoftware.kryo.Kryo, com.esotericsoftware.kryo.io.Input, java.lang.Class) @bci=44, line=221 (Compiled frame)- com.esotericsoftware.kryo.Kryo.readClassAndObject(com.esotericsoftware.kryo.io.Input) @bci=158, line=732 (Compiled frame)- org.apache.spark.serializer.KryoDeserializationStream.readObject(scala.reflect.ClassTag) @bci=8, line=118 (Compiled frame)- org.apache.spark.serializer.DeserializationStream$$anon$1.getNext() @bci=10, line=125 (Compiled frame)- org.apache.spark.util.NextIterator.hasNext() @bci=16, line=71 (Compiled frame)- org.apache.spark.storage.BlockManager$LazyProxyIterator$1.hasNext() @bci=4, line=1031 (Compiled frame)- scala.collection.Iterator$$anon$13.hasNext() @bci=4, line=371 (Compiled frame)- org.apache.spark.util.CompletionIterator.hasNext() @bci=4, line=30 (Compiled frame)- org.apache.spark.InterruptibleIterator.hasNext() @bci=22, line=39 (Compiled frame)- scala.collection.Iterator$$anon$11.hasNext() @bci=4, line=327 (Compiled frame)- org.apache.spark.sql.execution.HashJoin$$anonfun$execute$1.apply(scala.collection.Iterator, scala.collection.Iterator) @bci=14, line=77 (Compiled frame)- org.apache.spark.sql.execution.HashJoin$$anonfun$execute$1.apply(java.lang.Object, java.lang.Object) @bci=9, line=71 (Interpreted frame)- org.apache.spark.rdd.ZippedPartitionsRDD2.compute(org.apache.spark.Partition, org.apache.spark.TaskContext) @bci=48, line=87 (Interpreted frame)- org.apache.spark.rdd.RDD.computeOrReadCheckpoint(org.apache.spark.Partition, org.apache.spark.TaskContext) @bci=26, line=262 (Interpreted frame)
有大量的BLOCKED线程,继续观察GC信息。发现大量的FULL GC。
分析。在插入Hive表的时候,实际上须要写HDFS,在此过程的HashJoin时,伴随着大量的Shuffle写操作。JVM的新生代不断GC,Eden Space写满了就往Survivor Space写,同一时候超过一定大小的数据会直接写到老生代。当新生代写满了之后,也会把老的数据搞到老生代。假设老生代空间不足了。就触发FULL GC,还是空间不够,那就OOM错误了,此时线程被Blocked。导致整个Executor处理数据的进程被卡住。
当处理大数据的时候,假设JVM配置不当就easy引起上述问题。解决办法就是增大Executor的使用内存。合理配置新生代和老生代的大小,能够将老生代的空间适当的调大点。
10 小节
问题是比較严重,Application都直接无法执行了。可是引起问题的解决办法都比較小,归根结底还是部署的时候环境较为复杂,不够细致!再接再砺!
以后遇到相关的问题,会再这里持续更新,方便自己,也方便遇到类似问题的朋友们!
-------------------------------------------------------------------------------
假设您看了本篇博客,认为对您有所收获。请点击下方的 [顶]
假设您想转载本博客。请注明出处
假设您对本文有意见或者建议,欢迎留言
感谢您的阅读。请关注我的兴许博客
转载于:https://www.cnblogs.com/mthoutai/p/6962242.html
Spark on Yarn遇到的几个问题相关推荐
- 2021年大数据Spark(九):Spark On Yarn两种模式总结
目录 Spark On Yarn两种模式 引入 一.当一个MR应用提交运行到Hadoop YARN上时 二.当一个Spark应用提交运行在集群上时 注意 client 模式 cluster 模式 总结 ...
- Apache Spark源码走读之8 -- Spark on Yarn
欢迎转载,转载请注明出处,徽沪一郎. 概要 Hadoop2中的Yarn是一个分布式计算资源的管理平台,由于其有极好的模型抽象,非常有可能成为分布式计算资源管理的事实标准.其主要职责将是分布式计算集群的 ...
- spark on yarn 完全分布式_Spark编程笔记(1)-架构基础与运行原理
引言 根据IBM前首席执行官郭士纳的观点,IT领域每隔十五年就会迎来一 次重大变革 .当前我们正处于第三次信息浪潮(2010年前后),物联网.云计算和大数据技术突飞猛进. 信息爆炸是我们当前所需要解决 ...
- Spark通过YARN提交任务不成功(包含YARN cluster和YARN client)
无论用YARN cluster和YARN client来跑,均会出现如下问题. [spark@master spark-1.6.1-bin-hadoop2.6]$ jps 2049 NameNode ...
- Running Spark on YARN
Running Spark on YARN 对 YARN (Hadoop NextGen) 的支持是从Spark-0.6.0开始的,后续的版本也一直持续在改进. Launching Spark on ...
- spark on yarn :state: ACCEPTED一直 出现
今天运行spark on yarn 一直出现 16/09/20 18:40:41 INFO yarn.Client: Application report for application_147417 ...
- Spark On YARN 集群安装部署
2019独角兽企业重金招聘Python工程师标准>>> 最近毕设需要用到 Spark 集群,所以就记录下了部署的过程.我们知道 Spark 官方提供了三种集群部署方案: Standa ...
- spark on yarn 完全分部署_大数据Spark面试题(一)
1.spark的有几种部署模式,每种模式特点?(☆☆☆☆☆) 1)本地模式 Spark不一定非要跑在hadoop集群,可以在本地,起多个线程的方式来指定.将Spark应用以多线程的方式直接运行在本地, ...
- Spark on Yarn 模式编写workcount实例
Spark on Yarn 模式编写workcount实例 一:上传输入文件到hadoop,本例上传的文件名为spark.txt 二:打包程序,打包名为:Spark-0.0.1-SNAPSHOT.ja ...
- Spark on Yarn集群多Application并行执行
在工作中遇到向Spark集群提交多个任务,并且这些任务是需要同时执行的.但是遇到很多错误,所以把遇到的问题记录下来. 修改hadoop/etc/hadoop/yarn-site.xml文件 需要添加的 ...
最新文章
- 带left join 的sql的执行顺序
- 第三次学JAVA再学不好就吃翔(part26)--static关键字
- EntityFramework实体默认值遇到Oracle自增主键
- 拦截游戏窗口被移动_熊孩子骗家长人脸识别? 腾讯游戏出了个新招
- 为什么t6显示登录不到服务器,t6客户端登录不到服务器
- 数据结构笔记(十三)-- 串的堆分配存储表示
- 类加载常见错误总结,写得非常好!
- DataGridView中如何在textbox列中限制输入。
- Linux 2.4.x 网络协议栈QoS模块(TC)的设计与实现
- mysql 中 where条件的OR 和 and 加括号的说法
- SAAS PASS IASS 理解
- 仿9GAG制作过程(四)
- 三级指标 主成分分析_一文看懂主成分分析(PCA)
- 包含负数的二进制补码的加减运算
- Android 利用重力感应调整手机模式
- Realtek 1296 (RTD1296) OpenWRT Android 双系统全功能开发板
- 哪些是GraphPad Prism 的当前版本?如何更新或升级?
- LeetCode久不久来一题系列之Add Two Numbers
- nodejs addon
- MGC TOKEN—必将超越PlusToken的搬砖套利项目!
热门文章
- 服务器关机显示正在停止服务,云服务器一直停止中
- 【汇编语言】程序格式
- Linux下通过HostName访问主机以及修改HostName方法
- Linux开发sudo apt-cache search检索包
- (三)java版spring cloud+spring boot 社交电子商务平台 - Spring Cloud集成项目简介
- centos下docker无法正常启动检查与解决方法
- javaScript与MVC
- PHP提示Notice: Undefined variable的解决办法
- [转]测试的三重境界
- gcc -nostartfiles; -nodefaultlibs; -nostdlib;-f...