我有一个c++服务,它公开了两个接口:
答。submit():用于向yarnrm提交distcp作业
b。query():用于查询应用程序的状态。
此服务在内部调用java客户机(通过jni),该客户机有2个静态函数:
提交()
查询()
submit()用于:
DistCp distCp = new DistCp(configuration, distCpOptions);
Job job = distCp.execute();
Parses the "application ID" from the tracking URL and returns it.
query()执行以下操作:
Takes "application ID" returned in Submit()
YarnClient yarnClient = YarnClient.createYarnClient();
yarnClient.init(new YarnConfiguration());
yarnClient.start();
yarnClient.getApplicationReport(applicationID);
yarnClient.stop();
我面临的问题是,
如果对服务的第一个调用是submit(),那么所有后续调用(submit()和query())都将成功
但是,如果对服务的第一个调用是query(),那么所有submit()调用都将失败。
query()调用在所有条件下都成功。
submit()调用失败并出现错误(下面的第1次调用、第2次调用和第3次调用除外): java.util.ServiceConfigurationError: org.apache.hadoop.mapreduce.protocol.ClientProtocolProvider: Provider org.apache.hadoop.mapred.LocalClientProtocolProvider not found
java.util.ServiceConfigurationError: org.apache.hadoop.mapreduce.protocol.ClientProtocolProvider: Provider org.apache.hadoop.mapred.YarnClientProtocolProvider not found java.io.IOException: Cannot initialize Cluster. Please check your configuration for mapreduce.framework.name and the correspond server addresses.
我调试了这个问题,发现当首先调用query()api时,然后调用类 LocalClientProtocolProvider
以及 YarnClientProtocolProvider
未加载。调用submit()时,类加载器应该加载这些类。但是,这并没有发生。
我还注意到,当首先调用query()api时,hadoop配置会发生更改,并包含许多与“mapreduce.*”配置相关的默认设置。
我尝试使用class.forname()显式加载,只要submit()方法被调用。但是,这也无济于事。
调用submit()时,类加载器为什么不加载所需的类?这是hadoop配置或java类加载器的问题吗?还是因为我混合了mapreduce和yarn api而导致了这个问题?
“mapreduce.framework.name”配置设置为“yarn”。
我的环境是hadoop2.6.0。
我的类路径包含以下路径中的所有hadoop jar:
a. hadoop/common/
b. hadoop/common/lib
c. hadoop/hdfs/
d. hadoop/hdfs/lib
e. hadoop/mapreduce/
f. hadoop/mapreduce/lib
g. hadoop/yarn/
h. hadoop/yarn/lib
1条答案
按热度按时间rn0zuynd1#
我知道了,我在混
Yarn
以及MapReduce
而这会导致类加载问题。什么时候
Query()
称为first,它加载所有与Yarn相关的类。例如:但是,没有加载mapreduce相关的类。例如,不加载以下类:
所以,当
Submit()
调用时,类装入器假定它已装入所有必需的类。但是,班级YarnClientProtocolProvider
以及LocalClientProtocolProvider
尚未加载。因此Submit()
呼叫失败。强制类加载器加载所有
MapReduce
在相关类中,我在构造函数中为YarnClientWrapper
(这是一个单例类YarnClient
).这就解决了问题。
但是,更干净的实现将是
MapReduce
中的客户端Query()
而不是YarnClient
. 这将确保,我们不会进入类加载问题。