spark 1.1.0 编译使用 & 爬坑记录

虽然1.2.1版本也已经出来了,估计还是有很多人在用1.1.0或者1.0.0 版本。所以把编译和使用1.1.0版本时遇到的一些问题和解决思路写在这里,供参考。

因为我们对cdh版本的hadoop做了一些生产环境相关的修改,所以每次升级spark都需要基于源码自己进行编译。编译方法很简单,而且我在这篇文章 http://blog.csdn.net/amber_amber/article/details/41041787 也写过了,所以就不说了。

其实不管任何技术的学习,都是个逐步上手的过程。一步一步来,越来越熟悉的时候,你遇到的问题也就越来越少,遇到问题也知道应该从何处入手了。所以现在我们的环境已经升级到spark 1.2.1版本了,遇到的问题却显然没有当时钻研1.1.0时那么多了,而且也顺手了很多。


=========================================================

1. 重新编译spark(spark1.1.0-hadoop2.3.0)后,从client提交job,无法成功提交,报错如下:

[html]  view plain  copy
  1. <span style="font-family:Microsoft YaHei;font-size:14px;"><span style="font-family:Microsoft YaHei;font-size:14px;">        14/12/24 10:58:39 INFO ConfiguredRMFailoverProxyProvider: Failing over to rm2  
  2.         14/12/24 10:59:18 INFO ConfiguredRMFailoverProxyProvider: Failing over to rm1  
  3.         14/12/24 10:59:18 WARN RetryInvocationHandler: Exception while invoking class org.apache.hadoop.yarn.api.impl.pb.client.ApplicationClientProtocolPBClientImpl.getClusterMetrics. Not retrying because failovers (30) exceeded maximum allowed (30)  
  4.         java.net.ConnectException: Call From sjs/x.x.x.x to 0.0.0.0:8032 failed on connection exception: java.net.ConnectException: Connection refused; For more details see:  http://wiki.apache.org/hadoop/ConnectionRefused  
  5.                 at sun.reflect.GeneratedConstructorAccessor3.newInstance(Unknown Source)  
  6.                 at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)  
  7.                 at java.lang.reflect.Constructor.newInstance(Constructor.java:526)  
  8.                 at org.apache.hadoop.net.NetUtils.wrapWithMessage(NetUtils.java:783)  
  9.                 at org.apache.hadoop.net.NetUtils.wrapException(NetUtils.java:730)  
  10.                 at org.apache.hadoop.ipc.Client.call(Client.java:1413)  
  11.                 at org.apache.hadoop.ipc.Client.call(Client.java:1362)  
  12.                 at org.apache.hadoop.ipc.ProtobufRpcEngine$Invoker.invoke(ProtobufRpcEngine.java:206)  
  13.                 at com.sun.proxy.$Proxy7.getClusterMetrics(Unknown Source)  
  14.                 at org.apache.hadoop.yarn.api.impl.pb.client.ApplicationClientProtocolPBClientImpl.getClusterMetrics(ApplicationClientProtocolPBClientImpl.java:152)  
  15.                 at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)  
  16.                 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)  
  17.                 at java.lang.reflect.Method.invoke(Method.java:606)  
  18.                 at org.apache.hadoop.io.retry.RetryInvocationHandler.invokeMethod(RetryInvocationHandler.java:186)  
  19.                 at org.apache.hadoop.io.retry.RetryInvocationHandler.invoke(RetryInvocationHandler.java:102)  
  20.                 at com.sun.proxy.$Proxy8.getClusterMetrics(Unknown Source)  
  21.                 at org.apache.hadoop.yarn.client.api.impl.YarnClientImpl.getYarnClusterMetrics(YarnClientImpl.java:294)  
  22.                 at org.apache.spark.deploy.yarn.Client.logClusterResourceDetails(Client.scala:101)  
  23.                 at org.apache.spark.deploy.yarn.Client.runApp(Client.scala:60)  
  24.                 at org.apache.spark.deploy.yarn.Client.run(Client.scala:96)  
  25.                 at org.apache.spark.deploy.yarn.Client$.main(Client.scala:182)  
  26.                 at org.apache.spark.deploy.yarn.Client.main(Client.scala)  
  27.                 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)  
  28.                 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)  
  29.                 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)  
  30.                 at java.lang.reflect.Method.invoke(Method.java:606)  
  31.                 at org.apache.spark.deploy.SparkSubmit$.launch(SparkSubmit.scala:328)  
  32.                 at org.apache.spark.deploy.SparkSubmit$.main(SparkSubmit.scala:75)  
  33.                 at org.apache.spark.deploy.SparkSubmit.main(SparkSubmit.scala)  
  34.         Caused by: java.net.ConnectException: Connection refused  
  35.                 at sun.nio.ch.SocketChannelImpl.checkConnect(Native Method)  
  36.                 at sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:739)  
  37.                 at org.apache.hadoop.net.SocketIOWithTimeout.connect(SocketIOWithTimeout.java:206)  
  38.                 at org.apache.hadoop.net.NetUtils.connect(NetUtils.java:529)  
  39.                 at org.apache.hadoop.net.NetUtils.connect(NetUtils.java:493)  
  40.                 at org.apache.hadoop.ipc.Client$Connection.setupConnection(Client.java:604)  
  41.                 at org.apache.hadoop.ipc.Client$Connection.setupIOstreams(Client.java:699)  
  42.                 at org.apache.hadoop.ipc.Client$Connection.access$2800(Client.java:367)  
  43.                 at org.apache.hadoop.ipc.Client.getConnection(Client.java:1461)  
  44.                 at org.apache.hadoop.ipc.Client.call(Client.java:1380)  
  45.                 ... 23 more  
  46.         Call From sjs/x.x.x.x to 0.0.0.0:8032 failed on connection exception: java.net.ConnectException: Connection refused; For more details see:  http://wiki.apache.org/hadoop/ConnectionRefused</span></span>  

【SOLUTION】

这是因为无法获取到resourcemanager.namenode的缘故,所以客户端试图连接的是0.0.0.0作为rm,所以连接失败。如果出现这个问题,可能是由于yarn本身的bug造成的,因为我改用spark1.1.0-cdh5.1.0后就不再出现这个问题。
另外,看到一篇文章中介绍说在spark-env.sh中配置spark-yarn的环境变量,如果改用cdh没有奏效的话也可以试试这个方法:
export SPARK_YARN_USER_ENV="CLASSPATH=/search/hadoop/etc/hadoop"

2. spark on yarn-client模式提交作业,从client端连接时报错如下:

[html]  view plain  copy
  1. <span style="font-family:Microsoft YaHei;font-size:14px;"><span style="font-family:Microsoft YaHei;">       15/01/07 10:24:03 INFO util.Utils: Successfully started service 'sparkYarnAM' on port 43505.  
  2.         15/01/07 10:24:04 INFO yarn.ExecutorLauncher: Registering the ApplicationMaster with appUIAddress: sjs:4040  
  3.         15/01/07 10:24:04 INFO yarn.ExecutorLauncher: Waiting for Spark driver to be reachable.  
  4.         15/01/07 10:24:04 ERROR yarn.ExecutorLauncher: Failed to connect to driver at sjs:40900, retrying ...  
  5.         15/01/07 10:24:04 ERROR yarn.ExecutorLauncher: Failed to connect to driver at sjs:40900, retrying ...  
  6.         15/01/07 10:24:04 ERROR yarn.ExecutorLauncher: Failed to connect to driver at sjs:40900, retrying ...  
  7.         15/01/07 10:24:04 ERROR yarn.ExecutorLauncher: Failed to connect to driver at sjs:40900, retrying ...  
  8.         15/01/07 10:24:04 ERROR yarn.ExecutorLauncher: Failed to connect to driver at sjs:40900, retrying ...  
  9.         15/01/07 10:24:04 ERROR yarn.ExecutorLauncher: Failed to connect to driver at sjs:40900, retrying ...  
  10.         15/01/07 10:24:05 ERROR yarn.ExecutorLauncher: Failed to connect to driver at sjs:40900, retrying ...</span></span>  

【SOLUTION】

这是因为yarn-client模式中,driver进程是在客户端启动的。而客户端机器一般是一些虚拟机,hostname是简单的一些名字(类似my_machine这样的),其他服务器无法用这个hostname准确连接客户端机器。所以yarn集群无法正确解析driver机器的域名,无法正确连接,所以报错。
解决方法: spark中给出了对driver的DNS或者IP配置的一个配置变量,在提交作业之前执行如下命令:
export SPARK_JAVA_OPTS="-Dspark.driver.host=x.x.x.x"    

** 注意,这个系统属性不可以永久性地配置在spark-default.conf里,因为在yarn-cluster模式中,driver是运行在yarn集群的AM中的,这个指定会强制将driver的hostname指向所配置的域名,从而导致yarn-cluster模式执行报错。

update: 最近使用1.2.1时又出现这个问题,想着改源码来永久性解决这个问题。然后在源码中发现一个参数配置 SPARK_LOCAL_HOSTNAME,获取hostname时会首先去取这个环境配置。如果client的hostname不可用的,可以在spark-env.sh中把这个参数配置成ip地址,然后client端的任务提交,不管是yarn-cluster还是yarn-client都没有问题。但不知道为什么,这个配置貌似没有在官网中给出,不读源码还真发现不了啊。


3. spark on yarn-client模式,作业实际执行失败了的,console显示的失败原因是第一个stage中的一个task尝试失败次数超过4次所以整个application退出。但是在yarn中却显示这个作业是执行成功了的。

【SOLUTION】
目前还没有解决,看看1.2.1版本是不是解决了这个问题。

4. spark on yarn的UI界面无法访问,报错如下:

[html]  view plain  copy
  1. <span style="font-family:Microsoft YaHei;font-size:14px;"><span style="font-family:Microsoft YaHei;font-size:14px;">        HTTP ERROR 500  
  2.         Problem accessing /proxy/application_1420532637225_0054/. Reason:  
  3.             Connection refused  
  4.         Caused by:  
  5.         java.net.ConnectException: Connection refused  
  6.             at java.net.PlainSocketImpl.socketConnect(Native Method)  
  7.             at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:339)  
  8.             at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:200)  
  9.             at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:182)  
  10.             at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)  
  11.             at java.net.Socket.connect(Socket.java:579)  
  12.             at java.net.Socket.connect(Socket.java:528)  
  13.             at java.net.Socket.<init>(Socket.java:425)  
  14.             at java.net.Socket.<init>(Socket.java:280)  
  15.             at org.apache.commons.httpclient.protocol.DefaultProtocolSocketFactory.createSocket(DefaultProtocolSocketFactory.java:80)  
  16.             at org.apache.commons.httpclient.protocol.DefaultProtocolSocketFactory.createSocket(DefaultProtocolSocketFactory.java:122)  
  17.             at org.apache.commons.httpclient.HttpConnection.open(HttpConnection.java:707)  
  18.             at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:387)  
  19.             at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171)  
  20.             at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397)  
  21.             at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:346)  
  22.             at org.apache.hadoop.yarn.server.webproxy.WebAppProxyServlet.proxyLink(WebAppProxyServlet.java:186)  
  23.             at org.apache.hadoop.yarn.server.webproxy.WebAppProxyServlet.doGet(WebAppProxyServlet.java:338)  
  24.             at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)  
  25.             at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)  
  26.             at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)  
  27.             at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1221)  
  28.             at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:66)  
  29.             at com.sun.jersey.spi.container.servlet.ServletContainer.doFilter(ServletContainer.java:900)  
  30.             at com.sun.jersey.spi.container.servlet.ServletContainer.doFilter(ServletContainer.java:834)  
  31.             at org.apache.hadoop.yarn.server.resourcemanager.webapp.RMWebAppFilter.doFilter(RMWebAppFilter.java:84)  
  32.             at com.sun.jersey.spi.container.servlet.ServletContainer.doFilter(ServletContainer.java:795)  
  33.             at com.google.inject.servlet.FilterDefinition.doFilter(FilterDefinition.java:163)  
  34.             at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:58)  
  35.             at com.google.inject.servlet.ManagedFilterPipeline.dispatch(ManagedFilterPipeline.java:118)  
  36.             at com.google.inject.servlet.GuiceFilter.doFilter(GuiceFilter.java:113)  
  37.             at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1212)  
  38.             at org.apache.hadoop.http.HttpServer2$QuotingInputFilter.doFilter(HttpServer2.java:1183)  
  39.             at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1212)  
  40.             at org.apache.hadoop.http.NoCacheFilter.doFilter(NoCacheFilter.java:45)  
  41.             at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1212)  
  42.             at org.apache.hadoop.http.NoCacheFilter.doFilter(NoCacheFilter.java:45)  
  43.             at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1212)  
  44.             at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:399)  
  45.             at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)  
  46.             at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)  
  47.             at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:766)  
  48.             at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:450)  
  49.             at org.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:230)  
  50.             at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)  
  51.             at org.mortbay.jetty.Server.handle(Server.java:326)  
  52.             at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)  
  53.             at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:928)  
  54.             at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:549)  
  55.             at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:212)  
  56.             at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)  
  57.             at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:410)  
  58.             at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)</span></span>  

【SOLUTION】
首先,发现1.0.2中不存在这个问题,1.1.0里存在,而我的1.0.2是基于hadoop2.2.0编译的,1.1.0是基于cdh5.1.0编译的,所以第一步需要定位是hadoop的问题还是spark的问题。所以又编译了1.1.0-hadoop2.2.0发现是可以正常访问spark UI的,所以问题是和cdh5.1.0有关。
接下来,看看是不是protobuf的问题,但是对比两个jar包中的文件,以及编译过程中的输出,发现on hadoop2.2.0和on cdh5.1.0的编译中,使用的protobuf版本是完全一致的,所以排除protobuf的问题。
然后查看sparkUI的源码,在源码中加print打印,一步步查看sparkUI的启动过程,发现SPARKUI的实际启动地址是类似http://slave machine:37483这样的URL。然后访问这个URL,发现在on hadoop2.2.0的版本上,这个URL是可以正常访问的,但是在on cdh5.1.0版本中,这个URL不能正常访问,报错和上面的一致。
进一步推测问题可能是spark UI没有正常启动。继续看sparkUI的源码和启动过程,以及把两个版本的job执行的日志进行对照,并没有发现异常,也就是说sparkUI没有抛出异常,也就是很有可能已经正常启动了。
那么就很有可能是访问权限的问题了。
所以接下来看了看spark的安全权限控制,并试着用各种方法配置了下spark的web访问,发现都没有用.spark.ui.filters这个参数的值更是已经被写死在代码里了,也不是官方文档中介绍的默认为none,给databricks跪了。。。。。
然后发现,这时候只剩下一个proxy没有啃了,而hadoop为了防攻击,web端的访问都是通过proxy的,也就是说我用http://slave machine:37483这个URL访问sparkUI,也会经过proxy跳转。所以开始看proxy。果然发现,在返回HTTP 500错误的时候,hadoop的日志中会报connection refused的错误。继续看proxy相关的文档和介绍,官方介绍说,proxy默认是作为RM的一个子进程启动的,除非通过hadoop.web-proxy.address单独配置并启动。为了方便排查,我就修改了集群的proxy配置,把proxy配置成了独立启动的服务。然后,就这样,这个问题就解决了。。。。
最终推测,应该还是要总结为spark和yarn的交互的问题吧,应该是proxyserver作为yarn的一个组件,和作为单独的server启动,运行机制不同,而spark很有可能是更支持作为一个单独server的proxy代理的。这只是推测,后续进一步看看proxy server相关的源码和运行机制。

最终solution: 把proxy独立成proxy server进行提供(hadoop.web-proxy.address),然后对spark做一些限制,关闭sparkUI能kill application的功能(spark.ui.killEnabled)。


http://blog.csdn.net/amber_amber/article/details/44019725

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值