Моя существующая система читала все файлы из определенной папки и запускала MapReduce на ней. Приведенный ниже код:
Path path = new Path(inputPath)
if (!FileSystem.get(conf).exists(path)) {
System.out.println("Path does not exist (skipping): " + path);
return 1;
}
FileInputFormat.setInputPaths(conf, inputPath);
Это бежало без проблем. Теперь последние изменения файла потребовали от меня указать, какие файлы использовать в качестве входных данных. Я изменил код на это:
for(String fileName:filePath.split(",")){
MultipleInputs.addInputPath(conf, new Path(fileName), TextInputFormat.class, RawLogMapper.class);
// MultipleInputs.addInputPath(conf, new Path(fileName), TextInputFormat.class);
}
где filePath - список абсолютных путей файлов, разделенных запятыми, которые необходимо обработать. Я использую mapred, а не mapreduce.
import org.apache.hadoop.mapred.Reporter;
import org.apache.hadoop.mapred.TextInputFormat;
import org.apache.hadoop.mapred.lib.MultipleInputs;
import org.apache.hadoop.mapred.lib.MultipleTextOutputFormat;
После изменения кода я столкнулся со следующей ошибкой:
14/09/08 13:50:05 INFO mapred.JobClient: Task Id : attempt_201408201501_1196_m_000000_1, Status : FAILED
java.lang.RuntimeException: Error in configuring object
at org.apache.hadoop.util.ReflectionUtils.setJobConf(ReflectionUtils.java:109)
at org.apache.hadoop.util.ReflectionUtils.setConf(ReflectionUtils.java:75)
at org.apache.hadoop.util.ReflectionUtils.newInstance(ReflectionUtils.java:133)
at org.apache.hadoop.mapred.MapTask.runOldMapper(MapTask.java:413)
at org.apache.hadoop.mapred.MapTask.run(MapTask.java:332)
at org.apache.hadoop.mapred.Child$4.run(Child.java:268)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:396)
at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1438)
at org.apache.hadoop.mapred.Child.main(Child.java:262)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.ja
Не уверен, что это потому, что я не указывал TextInputFormat, я добавил эту часть в функцию addInputPath, и ошибка остается.
Нашел проблему. Существует вызов, следующий вниз по течению в картографе
String filename = conf.get("map.input.file");
pos = conf.get((new File(filename)).getName().split("-")[0]);
Когда я указываю файлы, вместо того, чтобы указывать папку, имя файла возвращается null и, следовательно, NPE. Интересно, почему conf.get("map.input.file"), когда я указываю входные файлы.
https://issues.apache.org/jira/browse/MAPREDUCE-1743
Это означает, что мне нужно знать имя файла при запуске конфигурации:
((FileSplit) context.getInputSplit()).getPath().toString();
, поскольку я использую mapred, а не mapreduce.public void configure(JobConf conf) { String filename = conf.get("map.input.file"); merchant = conf.get((new File(filename)).getName().split("-")[0]); if (merchant == null) { merchant = "unknown_merchant"; } }
Поблагодарите за любой вклад, чтобы решить эту проблему.
Спасибо, Jeevan
Используемый
FileInputFormat.addInputPath(conf, new Path(fileName));
И все выглядит хорошо.
FileInputFormat.addInputPath
в и без того длинный вопрос, так как я нашел это как временное решение проблемы. Хотел позволить другим людям, которые ищут решение той же проблемы, начать работу. :)