为YARN / Hadoop2作业设置LD_LIBRARY_PATH或java.library.path

时间:2015-08-03 14:09:38

标签: hadoop yarn

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

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

我使用以下解决方案获得部分成功,同时使用yarn启动wordcount示例。

  • 启动资源时设置export JAVA_LIBRARY_PATH=/path和nodemanager。

    这有助于资源和节点管理器,但实际的作业/应用程序失败。执行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) 
    
  • 通过命令行参数libjni-xtreemfs.so

    提供-files

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

现在有人如何全局设置LD_LIBRARY_PATHjava.library.path或者可以建议我可能错过哪些配置选项?我会非常感激的!

2 个答案:

答案 0 :(得分:5)

简答:在您的 mapred-site.xml 中添加以下内容

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

说明: 作业/应用程序不是由纱线而是由mapred(map / reduce)容器执行,其配置由mapred-site.xml文件控制。指定自定义java参数会导致实际工作人员使用正确的路径旋转

答案 1 :(得分:2)

在作业或网站配置中使用 mapreduce.map.env

用法如下:

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

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

相关问题