我想同时触发一些Hadoop作业。我使用Executors.newFixedThreadPool创建了一个线程池。想法是,如果池大小为2,我的代码将使用'ToolRunner.run'在相同的时间触发2个Hadoop作业。在我的测试中,我注意到这两个线程互相踩踏。
当我深入了解时,我注意到ToolRunner创建了GenericOptionsParser,后者又调用静态方法'buildGeneralOptions'。此方法使用'OptionBuilder.withArgName',它使用名为'argName'的实例变量。这对我来说看起来并不安全,我相信这是我遇到问题的根本原因。
有什么想法吗?
答案 0 :(得分:2)
确认ToolRunner不是线程安全的:
原始代码(遇到问题):
public static int run(Configuration conf, Tool tool, String[] args)
throws Exception{
if(conf == null) {
conf = new Configuration();
}
GenericOptionsParser parser = new GenericOptionsParser(conf, args);
//set the configuration back, so that Tool can configure itself
tool.setConf(conf);
//get the args w/o generic hadoop args
String[] toolArgs = parser.getRemainingArgs();
return tool.run(toolArgs);
}
新代码(有效):
public static int run(Configuration conf, Tool tool, String[] args)
throws Exception{
if(conf == null) {
conf = new Configuration();
}
GenericOptionsParser parser = getParser(conf, args);
tool.setConf(conf);
//get the args w/o generic hadoop args
String[] toolArgs = parser.getRemainingArgs();
return tool.run(toolArgs);
}
private static synchronized GenericOptionsParser getParser(Configuration conf, String[] args) throws Exception {
return new GenericOptionsParser(conf, args);
}