运行hadoop作业时出现java类加载问题

bq8i3lrv  于 2021-05-29  发布在  Hadoop
关注(0)|答案(1)|浏览(818)

我有一个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
rn0zuynd

rn0zuynd1#

我知道了,我在混 Yarn 以及 MapReduce 而这会导致类加载问题。
什么时候 Query() 称为first,它加载所有与Yarn相关的类。例如:

org.apache.hadoop.yarn.client.api.YarnClient from file:/D:/data/hadoop-2
.6.0-SNAPSHOT/share/hadoop/yarn/hadoop-yarn-client-2.6.0-SNAPSHOT.jar

但是,没有加载mapreduce相关的类。例如,不加载以下类:

org.apache.hadoop.mapred.YarnClientProtocolProvider from 
 file:/D:/data/hdoop-2.6.0-SNAPSHOT/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-2.6.0-SNAPSHOT.jar

所以,当 Submit() 调用时,类装入器假定它已装入所有必需的类。但是,班级 YarnClientProtocolProvider 以及 LocalClientProtocolProvider 尚未加载。因此 Submit() 呼叫失败。
强制类加载器加载所有 MapReduce 在相关类中,我在构造函数中为 YarnClientWrapper (这是一个单例类 YarnClient ).

Cluster cluster = new Cluster(configuration);
cluster.getFileSystem();
cluster.close();

这就解决了问题。
但是,更干净的实现将是 MapReduce 中的客户端 Query() 而不是 YarnClient . 这将确保,我们不会进入类加载问题。

相关问题