Yarn-cluster模式

时间:2016-01-05 22:47:07

标签: scala hadoop apache-spark yarn phoenix

所以我试图通过Oozie工作流在Yarn-cluster模式下运行Spark作业,但是遇到了以下错误(下面相关的堆栈跟踪)

java.sql.SQLException: ERROR 103 (08004): Unable to establish connection.
    at org.apache.phoenix.exception.SQLExceptionCode$Factory$1.newException(SQLExceptionCode.java:388)
    at org.apache.phoenix.exception.SQLExceptionInfo.buildException(SQLExceptionInfo.java:145)
    at org.apache.phoenix.query.ConnectionQueryServicesImpl.openConnection(ConnectionQueryServicesImpl.java:296)
    at org.apache.phoenix.query.ConnectionQueryServicesImpl.access$300(ConnectionQueryServicesImpl.java:179)
    at org.apache.phoenix.query.ConnectionQueryServicesImpl$12.call(ConnectionQueryServicesImpl.java:1917)
    at org.apache.phoenix.query.ConnectionQueryServicesImpl$12.call(ConnectionQueryServicesImpl.java:1896)
    at org.apache.phoenix.util.PhoenixContextExecutor.call(PhoenixContextExecutor.java:77)
    at org.apache.phoenix.query.ConnectionQueryServicesImpl.init(ConnectionQueryServicesImpl.java:1896)
    at org.apache.phoenix.jdbc.PhoenixDriver.getConnectionQueryServices(PhoenixDriver.java:180)
    at org.apache.phoenix.jdbc.PhoenixEmbeddedDriver.connect(PhoenixEmbeddedDriver.java:132)
    at org.apache.phoenix.jdbc.PhoenixDriver.connect(PhoenixDriver.java:151)
    at java.sql.DriverManager.getConnection(DriverManager.java:664)
    at java.sql.DriverManager.getConnection(DriverManager.java:208)
    ...
Caused by: java.io.IOException: java.lang.reflect.InvocationTargetException
    at org.apache.hadoop.hbase.client.ConnectionFactory.createConnection(ConnectionFactory.java:240)
    at org.apache.hadoop.hbase.client.ConnectionManager.createConnection(ConnectionManager.java:414)
    at org.apache.hadoop.hbase.client.ConnectionManager.createConnectionInternal(ConnectionManager.java:323)
    at org.apache.hadoop.hbase.client.HConnectionManager.createConnection(HConnectionManager.java:144)
    at org.apache.phoenix.query.HConnectionFactory$HConnectionFactoryImpl.createConnection(HConnectionFactory.java:47)
    at org.apache.phoenix.query.ConnectionQueryServicesImpl.openConnection(ConnectionQueryServicesImpl.java:294)
    ... 28 more
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
    at org.apache.hadoop.hbase.client.ConnectionFactory.createConnection(ConnectionFactory.java:238)
    ... 33 more
Caused by: java.lang.UnsupportedOperationException: Unable to find org.apache.hadoop.hbase.ipc.controller.ClientRpcControllerFactory
    at org.apache.hadoop.hbase.util.ReflectionUtils.instantiateWithCustomCtor(ReflectionUtils.java:36)
    at org.apache.hadoop.hbase.ipc.RpcControllerFactory.instantiate(RpcControllerFactory.java:58)
    at org.apache.hadoop.hbase.client.ConnectionManager$HConnectionImplementation.createAsyncProcess(ConnectionManager.java:2317)
    at org.apache.hadoop.hbase.client.ConnectionManager$HConnectionImplementation.<init>(ConnectionManager.java:688)
    at org.apache.hadoop.hbase.client.ConnectionManager$HConnectionImplementation.<init>(ConnectionManager.java:630)
    ... 38 more
Caused by: java.lang.ClassNotFoundException: org.apache.hadoop.hbase.ipc.controller.ClientRpcControllerFactory
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:264)
    at org.apache.hadoop.hbase.util.ReflectionUtils.instantiateWithCustomCtor(ReflectionUtils.java:32)
    ... 42 more

一些背景资料:

  • 作业在spark 1.4.1上运行(在spark.conf文件中指定了正确的spark.yarn.jar字段)。
  • oozie.libpath设置为我程序的jar所在的hdfs目录。
  • org.apache.hadoop.hbase.ipc.controller.ClientRpcControllerFactory,未找到的类,存在于phoenix-4.5.1-HBase-1.0-client.jar中。我在spark.conf文件中的spark.driver.extraClassPath和spark.executor.extraClassPath中指定了这个jar。我还在我的pom文件中添加了phoenix-core依赖项,以便该类存在于我的着色项目jar中。

到目前为止的观察:

  • 在我的spark.conf文件spark.driver.userClassPathFirst中添加一个额外字段并将其设置为true可以摆脱classnotfound异常。但是,它也阻止我初始化spark上下文(空指针异常)。从谷歌搜索它似乎包括这个领域弄乱了类路径,所以可能不是这样的方式,因为我甚至无法以这种方式初始化一个火花上下文。
  • 我注意到在oozie stdout日志中,我没有看到凤凰jar的类路径。所以也许由于某种原因spark.driver.extraClassPath和spark.executor.extraClassPath实际上并没有把jar作为extraClassPath?我知道我正在指定正确的jar文件路径,因为其他作业的spark.conf文件具有相同的参数。
  • 我发现了一种hacky方法,通过将jar复制到我的程序jar所在的目录中,使凤凰jar出现在类路径中(在oozie stdout日志中)。无论spark.executor.extraClassPath是否更改为指向新的jar位置,这都有效。但是,classnotfound异常仍然存在,即使我在解压缩jar时清楚地看到ClientRpcControllerFactory jar)

我尝试过的其他事情:

  • 我尝试使用sparkConf.setJars()和sparkContext.addJar()方法,但仍遇到同样的错误
  • 在我的作业属性文件的spark.driver.extraClassPath字段中添加了jar,但它似乎没有帮助(Spark文档表明在客户端模式下运行时此字段是必需的,因此可能与我的相关情况下)

非常感谢任何帮助/想法/建议。

2 个答案:

答案 0 :(得分:0)

我使用CDH 5.5.1 + Phoenix 4.5.2(都安装了包裹)并遇到了同样的问题。我认为在切换到客户端模式后问题就消失了。我无法验证这一点,因为我现在收到群集模式的其他错误。

我试图追踪凤凰源代码,发现了一些有趣的东西。希望Java / Scala专家确定根本原因。

  1. 已加载PhoenixDriver类。 这表明最初发现了罐子。在Class Loader层之后/ 上下文切换(?),jar从类路径中丢失。
  2. 如果我Class.forName()我的程序中存在一个不存在的类,则无需调用sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)。堆栈就像:

    java.lang.ClassNotFoundException: NONEXISTINGCLASS
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:264)
    
  3. 我将Phoenix代码复制到我的程序中进行测试。如果我拨打ClassNotFoundExcpetion,我仍然会收到ConnectionQueryServicesImpl.init (ConnectionQueryServicesImpl.java:1896)。但是,对ConnectionQueryServicesImpl.openConnection (ConnectionQueryServicesImpl.java:296)的调用返回了可用的HBase连接。所以似乎PhoenixContextExecutor导致了罐子的丢失,但我不知道如何。

  4. Cloudera Phoenix 4.5.2的源代码:https://github.com/cloudera-labs/phoenix/blob/phoenix1-4.5.2_1.2.0/phoenix-core/src/main/java/org/apache/

    (不确定我是否应发表评论......但我无论如何也没有声誉)

答案 1 :(得分:0)

所以我设法解决了我的问题,让我的工作得以运行。我的解决方案非常讨厌,但会在此发布,以防将来可能帮助其他人。

基本上,我理解的问题是负责查找#include <stdio.h> #include <string.h> int main() { char *str = "This is a test."; char *token; token = strtok(str," "); } 类的org.apache.hadoop.hbase.util.ReflectionUtils类是从集群中的某个cloudera目录而不是从我自己的jar加载的。当我将ClientRpcControllerFactory设置为true时,它优先从我的jar加载ReflectionUtils类,因此能够定位spark.driver.userClassPathFirst类。但是当我尝试初始化SparkContext时,这搞砸了其他一些类路径并且一直给我一个NullPointerException,所以我找了另一个解决方案。

我试图弄清楚是否可以排除所有默认的cdh jar包含在我的类路径中,但是发现spark.yarn.jar中的值正在拉入所有这些cdh jar,我肯定需要指定那个罐子。

所以解决方案是将所有来自Phoenix jar的ClientRpcControllerFactory下的类包含到spark-assembly jar(spark.yarn.jar指向的jar)中,这样就摆脱了原来的异常并且没有给出尝试初始化SparkContext时,我是一个NPE。我发现现在org.apache.hadoop.hbase类是从spark-assembly jar加载的,因为ReflectionUtils也包含在那个jar中,所以它能够找到它。在此之后,我为Phoenix类遇到了一些classNotFoundExceptions,所以我也将这些类放入spark-assembly jar。

最后,我遇到了ClientRpcControllerFactory问题。我发现我的应用程序jar包含这样的文件,但是将java.lang.RuntimeException: hbase-default.xml File Seems to be for and old Version of HBase更改为true并没有做任何事情。所以我在spark-assembly jar中包含了另一个hbase-default.xml文件,并将skip标志设置为true,它终于工作了。

一些观察结果:

  • 我注意到我的spark-assembly jar完全缺少一个org.apache.hadoop.hbase目录。一位同事告诉我,通常我应该期待在我的火花装配罐中找到一个hbase目录,所以也许我正在使用一个坏的火花装配罐。编辑:我检查了一个我新下载的火花装配罐(v1.5.2)并且它没有它,所以可能没有包含apache.hadoop.hbase包。
  • ClassNotFoundExceptions和类加载器问题很难调试。