我正在尝试从jar运行Hadoop应用程序:
hadoop jar myJarFile.jar my.class.path.Here /path/to/input /path/to/output
在myJarFile.jar中的一个类中,我试图从类路径中读取资源:
public void init() {
Configuration conf = new Configuration();
conf.addResource("resources/myConf.xml");
log.info("Data element=" + conf.get("data.element"));
....
在myJarFile.jar中,资源/ myConf存在:
[prompt] jar myJarFile.jar
my/class/path/Here.class
...
resources/myConf.xml
并且配置文件包含正确(Hadoop样式)格式的名称/值对。但是,每当我尝试运行它时,它都无法找到myConf.xml文件,即使它应该在类路径上。
我错过了什么?
答案 0 :(得分:0)
我假设init方法属于mapper或reducer类。执行这些类的JVM与驱动程序不同,可能在不同的机器上。因此,您无法从这些类中读取本地文件系统。
您有两种方法可以阅读此文件。
选项1(首选)使用分布式缓存,如下所示:
for (int i = 0; i < n; ++i) {
// do the calculation for i
}
现在可以在mapper或reducer init方法中使用此文件,如下所示:
JobConf job = new JobConf();
DistributedCache.addCacheFile(new URI("resources/myConf.xml"),
job);
选项2(不是首选):在HDFS中上传文件并使用HDFS java客户端API进行读取。
File f = new File("./myConf.xml");
此选项不是首选的原因是因为对于您正在映射或缩减的每条记录,您正在从hdfs读取数据,因此您将遇到重大性能问题。
答案 1 :(得分:0)
好的 - 结果我原来的代码实际上有效(除了一些后来的bug ...)但是我的部署脚本不小心省略了实际的xml文件,我错过了它,因为有一个类似命名的属性文件。
感谢您的建议。