【问题标题】:Set LD_LIBRARY_PATH or java.library.path for YARN / Hadoop2 Jobs为 YARN / Hadoop2 作业设置 LD_LIBRARY_PATH 或 java.library.path
【发布时间】:2017-02-21 04:27:04
【问题描述】:

我有一个 Hadoop FileSystem,它使用带有 JNI 的本机库。

显然我必须独立于当前执行的作业包含共享对象。但我找不到告诉 Hadoop/Yarn 应该在哪里寻找共享对象的方法。

我使用以下解决方案部分成功,同时使用 yarn 开始 wordcount 示例。

  • 在启动资源和节点管理器时设置export JAVA_LIBRARY_PATH=/path

    这有助于资源和节点管理器,但实际的作业/应用程序失败。在执行 wordcount 示例时打印 LD_LIBRARY_PATHjava.library.path 会产生以下结果。什么

    /logs/userlogs/application_x/container_x_001/stdout
    ...
    java.library.path : /tmp/hadoop-u/nm-local-dir/usercache/u/appcache/application_x/container_x_001:/usr/java/packages/lib/amd64:/usr/lib/x86_64-linux-gnu/jni:/lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu:/usr/lib/jni:/lib:/usr/lib
    LD_LIBRARY_PATH : /tmp/hadoop-u/nm-local-dir/usercache/u/appcache/application_x/container_x
    
  • 设置yarn.app.mapreduce.am.env="LD_LIBRARY_PATH=/path"

    这确实帮助了一些工作。实际的 map/reduce 工作确实有效(至少我得到了正确的结果),但调用确实失败并出现错误 no jni-xtreemfs in java.library.path

    不知何故,第一个应用程序/作业确实有效并显示了

     /logs/userlogs/application_x/container_x_001/stdout
    ...
    java.library.path : /tmp/hadoop-u/nm-local-dir/usercache/u/appcache/application_x/container_x_001:/path:/usr/java/packages/lib/amd64:/usr/lib/x86_64-linux-gnu/jni:/lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu:/usr/lib/jni:/lib:/usr/lib
    LD_LIBRARY_PATH : /tmp/hadoop-u/nm-local-dir/usercache/u/appcache/application_x/container_x_001:/path
    

    但是第二个和其余的确实失败了:

     /logs/userlogs/application_x/container_x_002/stdout
    ...
    java.library.path : /tmp/hadoop-u/nm-local-dir/usercache/u/appcache/application_x/container_x_002:/opt/hadoop-2.7.1/lib/native:/usr/java/packages/lib/amd64:/usr/lib/x86_64-linux-gnu/jni:/lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu:/usr/lib/jni:/lib:/usr/lib
    LD_LIBRARY_PATH : /tmp/hadoop-u/nm-local-dir/usercache/u/appcache/application_x/container_x_002/opt/hadoop-2.7.1/lib/native
    

    后面的堆栈跟踪显示,执行YarnChild时发生错误:

    2015-08-03 15:24:03,851 FATAL [main] org.apache.hadoop.mapred.YarnChild: Error running child : java.lang.UnsatisfiedLinkError: no jni-xtreemfs in java.library.path
        at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1886)
        at java.lang.Runtime.loadLibrary0(Runtime.java:849)
        at java.lang.System.loadLibrary(System.java:1088)
        at org.xtreemfs.common.libxtreemfs.jni.NativeHelper.loadLibrary(NativeHelper.java:54)
        at org.xtreemfs.common.libxtreemfs.jni.NativeClient.<clinit>(NativeClient.java:41)
        at org.xtreemfs.common.libxtreemfs.ClientFactory.createClient(ClientFactory.java:72)
        at org.xtreemfs.common.libxtreemfs.ClientFactory.createClient(ClientFactory.java:51)
        at org.xtreemfs.common.clients.hadoop.XtreemFSFileSystem.initialize(XtreemFSFileSystem.java:191)
        at org.apache.hadoop.fs.FileSystem.createFileSystem(FileSystem.java:2653)
        at org.apache.hadoop.fs.FileSystem.access$200(FileSystem.java:92)
        at org.apache.hadoop.fs.FileSystem$Cache.getInternal(FileSystem.java:2687)
        at org.apache.hadoop.fs.FileSystem$Cache.get(FileSystem.java:2669)
        at org.apache.hadoop.fs.FileSystem.get(FileSystem.java:371)
        at org.apache.hadoop.fs.FileSystem.get(FileSystem.java:170)
        at org.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:163)
        at java.security.AccessController.doPrivileged(Native Method)
        at javax.security.auth.Subject.doAs(Subject.java:415)
        at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1657)
        at org.apache.hadoop.mapred.YarnChild.main(YarnChild.java:158) 
    
  • 通过命令行参数-files 提供libjni-xtreemfs.so

    这确实有效。我假设 .so 被复制到 tmp 目录。但这不是可行的解决方案,因为它需要用户在每次调用时提供 .so 的路径。

现在有没有人可以全局设置LD_LIBRARY_PATHjava.library.path,或者可以建议我可能错过的配置选项?非常感谢!

【问题讨论】:

  • 您找到这个问题的答案了吗?我想我也有类似的问题。
  • 很遗憾没有。最后,我们为我们的 Hadoop 文件系统实现引入了一个配置参数,它指向可以找到共享对象的目录,并从那里手动加载它。这并不完美,但它确实有效,而且我们没有用户在每次调用中提供 .so 的路径
  • 谢谢,非常感谢您回来回答。
  • @Tim 和 ae35 你能解释一下你是如何使用 Hadoop FileSystem 的配置参数来加载共享对象文件的吗...?
  • @GurinderbeerSingh 我在我编写的 Flink 应用程序的上下文中遇到了这个问题,解决方案是将 -Djava.library.path=/path 参数直接添加到应用程序运行时。

标签: hadoop hadoop-yarn


【解决方案1】:

简短答案:在您的 ma​​pred-site.xml 中输入以下内容

<property>
<name>mapred.child.java.opts</name>
<value>-Djava.library.path=$PATH_TO_NATIVE_LIBS</value>
</property>

说明: Job/Applications 不是由 yarn 而不是由 mapred (map/reduce) 容器执行的,其配置由 mapred-site.xml 文件控制。在那里指定自定义 java 参数会导致实际工作人员以正确的路径旋转

【讨论】:

  • 呃。谢谢?这有帮助吗?我只是有点困惑,因为我花了一个小时寻找这个,终于找到了没有投票的答案:)
  • OP 使用不同的方法来解决问题,但 IMO(我有偏见)这是正确的方法,这也是我们在使用 spark 之前使用的方法。文档说“如果使用 hadoop 本机库,使用 -Djava.library.path 可能会导致程序不再运行。这些值应该使用 mapreduce.map.env 在 map / reduce JVM env 中设置为 LD_LIBRARY_PATH 的一部分和 mapreduce.reduce.env 配置设置。”但我似乎找不到有关这些参数的文档
  • 嘿,我这样做的唯一原因是因为我们正在尝试使用 sqoop 将数据从 RDBMS 复制到 HDFS,然后由 Spark 处理 :)
  • 如果是这样,请注意指定的设置仅指 hadoop map reduce 任务,不确定 scoop 是如何工作的,但对于 spark 配置文件中有类似的设置。正如我原来的帖子所说 - 你需要找到一种方法在运行实际任务的 JVM 上设置它
  • 是的,Spark 似乎可以为我提供开箱即用的功能。 Sqoop 正在创建常规 Hadoop mapreduce 作业,因此您的建议效果很好。
【解决方案2】:

在您的工作或网站配置中使用 mapreduce.map.env

用法如下:

<property>
             <name>mapreduce.map.env</name>
             <value>LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path/to/my/libs</value>
</property>

注意: Hadoop 文档鼓励在mapred.child.java.opts 上使用mapreduce.map.env。 “如果使用 hadoop 本机库,使用 -Djava.library.path 可能会导致程序不再运行。”

【讨论】:

    猜你喜欢
    • 2018-09-20
    • 2014-07-25
    • 2019-06-23
    • 2015-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多