Spark on Yarn ”爬坑“集锦(spark1.2)

一、概述

Ha,已经有两个月没有更新blog了。由于近排公司需要引入Spark相关技术,我也是作为技术攻关人员之一,在这段时间使用Spark遇到了挺多问题,跌的坑也比较多,这篇blog主要总结一下这段时间使用Spark遇到的一些问题。

二、遇到的"坑"和爬坑思路

1、SparkSql on yarn-client模式遇到找不到mysql驱动包问题。

解决方案:这个比较简单直接编辑$SPARK_HOME/conf/spark-env.sh文件,将mysql的驱动jarexport进去,如:

export SPARK_CLASSPATH=$SPARK_CLASSPATH:/home/hadoop/hadoop/spark-1.2.0-bin-hadoop2.4/lib/mysql-connector-java-5.1.7-bin.jar:/home/hadoop/hadoop/hadoop-2.5.0/share/hadoop/common/hadoop-lzo-0.4.20-SNAPSHOT.jar

里边我同时也将lzo的jar包也export进去了,是因为我需要在spark中使用lzo的压缩输入格式,对于这个lzo的jar包需要注意下,这个jar包是需要自己在装好了lzo本地库之后,自己编译出来的。

2、SparkSql on yarn-cluster模式遇到找不到datanucleus相关jar包,具体错误信息看下面:

Caused by: java.lang.RuntimeException: Unable to instantiate org.apache.hadoop.hive.metastore.HiveMetaStoreClient
 at org.apache.hadoop.hive.metastore.MetaStoreUtils.newInstance(MetaStoreUtils.java:1412)
 at org.apache.hadoop.hive.metastore.RetryingMetaStoreClient.<init>(RetryingMetaStoreClient.java:62)
 at org.apache.hadoop.hive.metastore.RetryingMetaStoreClient.getProxy(RetryingMetaStoreClient.java:72)
 at org.apache.hadoop.hive.ql.metadata.Hive.createMetaStoreClient(Hive.java:2453)
 at org.apache.hadoop.hive.ql.metadata.Hive.getMSC(Hive.java:2465)
 at org.apache.hadoop.hive.ql.session.SessionState.start(SessionState.java:340)
 ... 7 more
Caused by: java.lang.reflect.InvocationTargetException
 at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
 at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
 at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
 at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
 at org.apache.hadoop.hive.metastore.MetaStoreUtils.newInstance(MetaStoreUtils.java:1410)
 ... 12 more
Caused by: javax.jdo.JDOFatalUserException: Class org.datanucleus.api.jdo.JDOPersistenceManagerFactory was not found.
NestedThrowables:
java.lang.ClassNotFoundException: org.datanucleus.api.jdo.JDOPersistenceManagerFactory
 at javax.jdo.JDOHelper.invokeGetPersistenceManagerFactoryOnImplementation(JDOHelper.java:1175)
 at javax.jdo.JDOHelper.getPersistenceManagerFactory(JDOHelper.java:808)
 at javax.jdo.JDOHelper.getPersistenceManagerFactory(JDOHelper.java:701)
 at org.apache.hadoop.hive.metastore.ObjectStore.getPMF(ObjectStore.java:310)
 at org.apache.hadoop.hive.metastore.ObjectStore.getPersistenceManager(ObjectStore.java:339)
 at org.apache.hadoop.hive.metastore.ObjectStore.initialize(ObjectStore.java:248)
 at org.apache.hadoop.hive.metastore.ObjectStore.setConf(ObjectStore.java:223)
 at org.apache.hadoop.util.ReflectionUtils.setConf(ReflectionUtils.java:73)
 at org.apache.hadoop.util.ReflectionUtils.newInstance(ReflectionUtils.java:133)
 at org.apache.hadoop.hive.metastore.RawStoreProxy.<init>(RawStoreProxy.java:58)
 at org.apache.hadoop.hive.metastore.RawStoreProxy.getProxy(RawStoreProxy.java:67)
 at org.apache.hadoop.hive.metastore.HiveMetaStore$HMSHandler.newRawStore(HiveMetaStore.java:497)
 at org.apache.hadoop.hive.metastore.HiveMetaStore$HMSHandler.getMS(HiveMetaStore.java:475)
 at org.apache.hadoop.hive.metastore.HiveMetaStore$HMSHandler.createDefaultDB(HiveMetaStore.java:523)
 at org.apache.hadoop.hive.metastore.HiveMetaStore$HMSHandler.init(HiveMetaStore.java:397)
 at org.apache.hadoop.hive.metastore.HiveMetaStore$HMSHandler.<init>(HiveMetaStore.java:356)
 at org.apache.hadoop.hive.metastore.RetryingHMSHandler.<init>(RetryingHMSHandler.java:54)
 at org.apache.hadoop.hive.metastore.RetryingHMSHandler.getProxy(RetryingHMSHandler.java:59)
 at org.apache.hadoop.hive.metastore.HiveMetaStore.newHMSHandler(HiveMetaStore.java:4944)
 at org.apache.hadoop.hive.metastore.HiveMetaStoreClient.<init>(HiveMetaStoreClient.java:171)
 ... 17 more
Caused by: java.lang.ClassNotFoundException: org.datanucleus.api.jdo.JDOPersistenceManagerFactory
 at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
 at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
 at java.security.AccessController.doPrivileged(Native Method)
 at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
 at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
 at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
 at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
 at java.lang.Class.forName0(Native Method)
 at java.lang.Class.forName(Class.java:270)
 at javax.jdo.JDOHelper$18.run(JDOHelper.java:2018)
 at javax.jdo.JDOHelper$18.run(JDOHelper.java:2016)
 at java.security.AccessController.doPrivileged(Native Method)
 at javax.jdo.JDOHelper.forName(JDOHelper.java:2015)
 at javax.jdo.JDOHelper.invokeGetPersistenceManagerFactoryOnImplementation(JDOHelper.java:1162)
 ... 36 more

解决方案:这个问题相当坑爹,个人感觉完全是个bug来的。像这种jar应该是在$SPARK_HOME/bin/compute-classpath.sh计算出来然后export进去的,看看comput-classpath.sh的相关shell代码(从97行往下看,spark版本为1.2):

很遗憾,在sparkSql on yarn-cluster模式这个脚本无法$SPARK_HOME/lib下的datanucleus相关包export进去。经过几番折腾,翻了一遍spark在github上的Pull request终于找到了解决方案:在提交启动sparkSql cli的时候使用--jar将相关datanucleus的jar包export进去就ok了,看命令:

spark-sql --master yarn-cluster  --jars /data1/app/spark-1.2.0-bin-hadoop2.4/lib/datanucleus-api-jdo-3.2.6.jar,/data1/app/spark-1.2.0-bin-hadoop2.4/lib/datanucleus-core-3.2.10.jar,/data1/app/spark-1.2.0-bin-hadoop2.4/lib/datanucleus-rdbms-3.2.9.jar,/data1/app/spark-1.2.0-bin-hadoop2.4/lib/mysql-connector-java-5.1.7-bin.jar  --driver-memory 4G  --executor-cores 32 --queue spark  --executor-memory 70G  --num-executors 7  -e "use test1;
select count(*) from st_pc_lifecycle_list tb2 left outer join
(select ip,count(*) from st_pc_lifecycle_list where dt=‘2014-07-16‘ group by ip) tb1 on(tb1.ip=tb2.ip) where tb2.dt>=‘2014-11-20‘  limit 10;"

3、使用spark-sql on yarn-cluster模式无法连接到hive-site.xml指定的metaStore,use 相关database时候出现找不到库错误。这个问题又是相当隐蔽的问题,刚刚排查的时候也是比较困难的。

详细错误信息:

解决问题思路:

(1)我们观察这个错误,可能会隐隐约约想,这个我明显是连接上了metastore,那么为什么还找不到metastore里边的库啊??呵呵,我当时也是相当郁闷,直到我看到了这么一条提示:metastore.MetaStoreDirectSql: MySQL check failed(上面的错误截图没有截出来),这样我就知道了在计算节点启动的Dirver并没有正常的连接到hive-site.xml指定的metaStore。那么既然driver没有连接上hive-site.xml指定的metaStore,那么为什么看dirver的日志显示的确实可以连接上metaStore,只是无法连接到相应的库的?这下要搜源码了,直接在源码搜索"hive-site.xml",然后在sql-programming-guide.md中看到了这么一段提示信息:

或者再看HiveContext代码:

哈哈,这么一看听明白了:就算用户不指定hive-site.xml文件,也会建立一个默认的hiveContext的,这样说的话在这个hiveContext中肯定是找不到hive-site.xml指定的库了。现在的问题转化成为计算节点上的Dirver找不到hive-site.xml了。启动作业时使用--driver-class-path,--jar,--drier-library-path指定hive-site.xml位置都不管用。直到看到Dirver界面的classpath才有些顿悟:

既然hadoop的conf path已经被export到了classpath中,为何不试试将hive-site.xml丢到hadoop的conf路径试试呢,哈哈试了果然ok,了可以正在连接hive-site.xml指定的ip了(要将hive-site.xml丢到所有计算节点的配置文件夹中,因为Driver可能随机到任何一个计算节点)。呵呵,找不到hive-site.xml的问题已经解决了,但是还是连接不上metaStore,已经卡在连接阶段。哈哈这个比较好解决:在hive-site.xml中将hive.metastore.uris配置上就ok了,给大家个参考:

<property>        <name>hive.metastore.uris</name>                <value>thrift://10.1.80.40:9083</value>          <description>Thrift URI for the remote metastore. Used by metastore client to connect to remote metastore.</description></property><property>        <name>hive.server2.thrift.min.worker.threads</name>        <value>5</value>        <description>Minimum number of Thrift worker threads</description></property><property>        <name>hive.server2.thrift.max.worker.threads</name>        <value>500</value>        <description>Maximum number of Thrift worker threads</description></property><property>        <name>hive.server2.thrift.port</name>        <value>10000</value>        <description>Port number of HiveServer2 Thrift interface. Can be overridden by setting $HIVE_SERVER2_THRIFT_PORT</description></property><property>        <name>hive.server2.thrift.bind.host</name>        <value>slave8040</value>        <description>Bind host on which to run the HiveServer2 Thrift interface.Can be overridden by setting$HIVE_SERVER2_THRIFT_BIND_HOST</description></property><property>        <name>hive.server2.enable.doAs</name>        <value>true</value></property><property>  <name>hive.metastore.warehouse.dir</name>    <value>/user/hive/warehouse</value>    <description>location of default database for the warehouse</description> </property><property>  <name>hive.metastore.local</name>  <value>hive.metastore.local</value>  <description>location of default database for the warehouse</description></property>

配置好了metaStore的uri后,不要忘记了重要的一步,就是启动metaStore服务:进入$HIVE_HOME/bin,运行nohup ./hive --server metastore &

启动完之后看看端口是否正常:

[[email protected] conf]$ jps 23158 SparkSubmitDriverBootstrapper 23510 SparkSubmit 4442 Jps 9866 RunJar [[email protected] conf]$ ps -ef | grep 9866 hadoop 4504 14107 0 16:25 pts/0 00:00:00 grep 9866 hadoop 9866 1 0 Dec27 ? 00:01:54 /usr/local/jdk1.7.0_51/bin/java -Xmx3072m -Djava.net.preferIPv4Stack=true -Dhadoop.log.dir=/data2/hadoop/logs/hadoop -Dhadoop.log.file=hadoop.log -Dhadoop.home.dir=/home/hadoop/hadoop/hadoop-2.5.0 -Dhadoop.id.str=hadoop -Dhadoop.root.logger=INFO,console -Djava.library.path=/home/hadoop/hadoop/hadoop-2.5.0/lib/native -Dhadoop.policy.file=hadoop-policy.xml -Djava.net.preferIPv4Stack=true -Xmx2048m -Dhadoop.security.logger=INFO,NullAppender org.apache.hadoop.util.RunJar /home/hadoop/hadoop/apache-hive-0.13.1-bin/lib/hive-service-0.13.1.jar org.apache.hadoop.hive.metastore.HiveMetaStore [[email protected] conf]$ netstat -antp| grep 9866 (Not all processes could be identified, non-owned process info will not be shown, you would have to be root to see it all.) tcp 0 0 0.0.0.0:9083 0.0.0.0:* LISTEN 9866/java tcp 0 0 10.1.80.40:47635 10.1.80.40:3306 ESTABLISHED 9866/java tcp 0 0 10.1.80.40:47591 10.1.80.40:3306 ESTABLISHED 9866/java tcp 0 0 10.1.80.40:47636 10.1.80.40:3306 ESTABLISHED 9866/java tcp 0 0 10.1.80.40:9083 10.1.80.40:51365 ESTABLISHED 9866/java tcp 0 0 10.1.80.40:47590 10.1.80.40:3306 ESTABLISHED 9866/java tcp 0 0 10.1.80.40:9083 10.1.80.40:51367 ESTABLISHED 9866/java

再次spark-sql on yarn-cluster模式完全ok。

吐槽下:spark还有挺多不完善的东西,小bug挺多,还有官方相关文档不全,像那个配置文档也只是部分配置项的,这个希望以后可以继续完善。不过spark的版本更新速度相当快,还有在github上的提问获得的回答想相当快,这个不错。哈哈,Spark的社区交流还是相当活跃的,呵呵继续爬坑。

4、最后一个坑,持久代OOM问题。

错误信息:使用spark-sql on yarn-cluster的时候启动driver报如下错误:

  1. Exception in thread "Thread-2" java.lang.OutOfMemoryError: PermGen space

哈哈,这个又是相当常见的错误。

解决思路:

直接增大PermGen space,编辑spark-defaults.xml添加:

spark.driver.extraJavaOptions -XX:PermSize=128M -XX:MaxPermSize=256M

再试ok。但是这里还有一个问题:什么使用yarn-client运行spark-sql就不会出现这问题呢?通过一番脚本追踪发现yarn-client模式运行时在$SPARK_HOME/bin/spark-class文件中已经设置了持久代大小,具体看spark-class的116行:JAVA_OPTS="-XX:MaxPermSize=128m $OUR_JAVA_OPTS",问题解决。Spark的各种模式的jvm的内存参数设置比较容易混淆,这里引用http://www.aboutyun.com/thread-9425-1-1.html 里边的小段总结:

总结一下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参数值。

三、总结
    在Spark的使用当中,遇到的各种问题还是挺多的,好在版本更新比较快。另外,spark1.2中将shuffle默认基于sort了,还有采用了netty方式,但是在用的过程中也遇到了一些问题,比如fetch Failure、lost Excutor等等,下篇blog总结吧。生命不断,爬坑不止!

参考文献:http://www.aboutyun.com/thread-9425-1-1.html

时间: 2024-07-30 13:26:11

Spark on Yarn ”爬坑“集锦(spark1.2)的相关文章

Spark on Yarn部署

环境:Linux, 8G 内存,60G 硬盘,Hadoop 2.2.0,Spark 1.0.0, Scala 2.10.3 1. 安装Hadoop Yarn 集群 http://blog.csdn.net/zlcd1988/article/details/36008681 这篇Blog很详细的介绍了如何部署Hadoop Yarn 集群. 2. 安装Scala http://www.scala-sbt.org/download.html 下载 scala-2.10.3.tgz $ tar -zxv

Spark 1.0.0 横空出世 Spark on yarn 部署(hadoop 2.4)

就在昨天,北京时间5月30日20点多.Spark 1.0.0终于发布了:Spark 1.0.0 released 根据官网描述,Spark 1.0.0支持SQL编写:Spark SQL Programming Guide 个人觉得这个功能对Hive的市场的影响很小,但对Shark冲击很大,就像win7和winXP的关系,自相残杀嘛? 这么着急的发布1.x 版是商业行为还是货真价实的体现,让我们拭目以待吧~~~~ 本文是CSDN-撸大湿原创,如要转载请注明出处,谢谢:http://blog.csd

Spark(十二) -- Spark On Yarn &amp; Spark as a Service &amp; Spark On Tachyon

Spark On Yarn: 从0.6.0版本其,就可以在在Yarn上运行Spark 通过Yarn进行统一的资源管理和调度 进而可以实现不止Spark,多种处理框架并存工作的场景 部署Spark On Yarn的方式其实和Standalone是差不多的,区别就是需要在spark-env.sh中添加一些yarn的环境配置,在提交作业的时候会根据这些配置加载yarn的信息,然后将作业提交到yarn上进行管理 首先请确保已经部署了Yarn,相关操作请参考: hadoop2.2.0集群安装和配置 部署完

Spark on YARN的部署

Spark on YARN的原理就是依靠yarn来调度Spark,比默认的Spark运行模式性能要好的多,前提是首先部署好hadoop HDFS并且运行在yarn上,然后就可以开始部署spark on yarn了,假设现在准备环境已经部署完毕,这里是在CDH 环境下部署Spark 除了上面的环境准备,安装Spark前,还应该保证Scala正常安装,基于Scala的情况下,就可以开始部署Spark了, 首先还是解压Spark,安装位置就是/bigdata/spark tar -xvzf spark

spark on yarn 安装笔记

yarn版本:hadoop2.7.0 spark版本:spark1.4.0 0.前期环境准备: jdk 1.8.0_45 hadoop2.7.0 Apache Maven 3.3.3 1.编译spark on yarn 下载地址:http://mirrors.cnnic.cn/apache/spark/spark-1.4.1/spark-1.4.1.tgz 解压后进入spark-1.4.1 执行如下命令,Setting up Maven’s Memory Usage export MAVEN_O

spark on yarn详解

1.参考文档: spark-1.3.0:http://spark.apache.org/docs/1.3.0/running-on-yarn.html spark-1.6.0:http://spark.apache.org/docs/1.6.0/running-on-yarn.html 备注:从spark-1.6.0开始,spark on yarn命令有略微改变,具体参考官方文档,这里以spark 1.3.0集群为主. 2.前期准备 编译spark,参看文档:http://www.cnblogs

安卓易学,爬坑不易——腾讯老司机的RecyclerView局部刷新爬坑之路

针对手游的性能优化,腾讯WeTest平台的Cube工具提供了基本所有相关指标的检测,为手游进行最高效和准确的测试服务,不断改善玩家的体验.目前功能还在免费开放中. 点击地址:http://wetest.qq.com/cube立即体验! 作者:Hoolly,腾讯移动客户端开发工程师. 商业转载请联系腾讯WeTest获得授权,非商业转载请注明出处 WeTest导读 安卓开发者都知道,RecyclerView比ListView要灵活的多,但不可否认的里面的坑也同样埋了不少人.下面让我们看看腾讯开发工程

AngularJs (二) 搭建Deployd 服务爬坑

Deployd 爬坑 按照书上的教程,介绍Deployd 这个东东,首先进入其deployd.com/网页,发现这个东东着实厉害. THE SIMPLEST WAY TO BUILD AN API 按照文档说明我的电脑是windows系统,按照docs说明进入下载,无奈我网络不是很给力,老是不能直接在网站上下载,看到它提供的github下载,下载下来自己新手一个,又不懂怎么安装,顿时就是感觉学习新东西好难啊,自信心顿时消失了一半,还好这个东东是依赖nodeJs和MongoDB的,继续翻阅文档ht

Spark on Yarn年度知识整理

大数据体系结构: Spark简介 Spark是整个BDAS的核心组件,是一个大数据分布式编程框架,不仅实现了MapReduce的算子map 函数和reduce函数及计算模型,还提供更为丰富的算子,如filter.join.groupByKey等.是一个用来实现快速而同用的集群计算的平台. Spark将分布式数据抽象为弹性分布式数据集(RDD),实现了应用任务调度.RPC.序列化和压缩,并为运行在其上的上层组件提供API.其底层采用Scala这种函数式语言书写而成,并且所提供的API深度借鉴Sca