为 YARN / Hadoop2 作业设置 LD_LIBRARY_PATH 或 java.library.path
Set LD_LIBRARY_PATH or java.library.path for YARN / Hadoop2 Jobs
我有一个 Hadoop FileSystem
,它使用带有 JNI 的本地库。
显然我必须独立于当前执行的作业来包含共享对象。但是我找不到一种方法来告诉 Hadoop/Yarn 它应该在哪里寻找共享对象。
我使用以下解决方案部分成功,同时使用 yarn 启动 wordcount 示例。
启动资源和节点管理器时设置export JAVA_LIBRARY_PATH=/path
。
这有助于资源和节点管理器,但实际 Job/Application 失败了。在执行 wordcount 示例时打印 LD_LIBRARY_PATH
和 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:/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
。
第一个 application/job 以某种方式工作并显示
/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.access0(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.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_PATH
或 java.library.path
或者可以建议我可能错过了哪些配置选项吗?非常感谢!
简短回答:在您的 mapred-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 参数会导致实际工作人员使用正确的路径旋转
在您的工作或站点配置中使用 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
。 "Usage of -Djava.library.path can cause programs to no longer function if hadoop native libraries are used."
我有一个 Hadoop FileSystem
,它使用带有 JNI 的本地库。
显然我必须独立于当前执行的作业来包含共享对象。但是我找不到一种方法来告诉 Hadoop/Yarn 它应该在哪里寻找共享对象。
我使用以下解决方案部分成功,同时使用 yarn 启动 wordcount 示例。
启动资源和节点管理器时设置
export JAVA_LIBRARY_PATH=/path
。这有助于资源和节点管理器,但实际 Job/Application 失败了。在执行 wordcount 示例时打印
LD_LIBRARY_PATH
和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:/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
。第一个 application/job 以某种方式工作并显示
/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.access0(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.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_PATH
或 java.library.path
或者可以建议我可能错过了哪些配置选项吗?非常感谢!
简短回答:在您的 mapred-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 参数会导致实际工作人员使用正确的路径旋转
在您的工作或站点配置中使用 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
。 "Usage of -Djava.library.path can cause programs to no longer function if hadoop native libraries are used."