Есть ли способ передать аргументы конструктора Mapper в Hadoop?Возможно, через какую-то библиотеку, которая оборачивает создание задания?
Вот мой сценарий:
public class HadoopTest {
// Extractor turns a line into a "feature"
public static interface Extractor {
public String extract(String s);
}
// A concrete Extractor, configurable with a constructor parameter
public static class PrefixExtractor implements Extractor {
private int endIndex;
public PrefixExtractor(int endIndex) { this.endIndex = endIndex; }
public String extract(String s) { return s.substring(0, this.endIndex); }
}
public static class Map extends Mapper<Object, Text, Text, Text> {
private Extractor extractor;
// Constructor configures the extractor
public Map(Extractor extractor) { this.extractor = extractor; }
public void map(Object key, Text value, Context context) throws IOException, InterruptedException {
String feature = extractor.extract(value.toString());
context.write(new Text(feature), new Text(value.toString()));
}
}
public static class Reduce extends Reducer<Text, Text, Text, Text> {
public void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException {
for (Text val : values) context.write(key, val);
}
}
public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
Job job = new Job(conf, "test");
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(Text.class);
job.setMapperClass(Map.class);
job.setReducerClass(Reduce.class);
job.setInputFormatClass(TextInputFormat.class);
job.setOutputFormatClass(TextOutputFormat.class);
FileInputFormat.addInputPath(job, new Path(args[0]));
FileOutputFormat.setOutputPath(job, new Path(args[1]));
job.waitForCompletion(true);
}
}
Как должно быть понятно, поскольку Mapper предоставляется только для Configuration
в качестве ссылки на класс (Map.class
), Hadoop не может передать аргумент конструктора и сконфигурировать конкретный Extractor.
Существуют интегрированные среды Hadoop, такие как Scoobi, Crunch, Scrunch (и, вероятно, многие другие, которых я не знаюо) которые, кажется, имеют такую возможность, но я не знаю, как они это делают. РЕДАКТИРОВАТЬ: После еще большей работы со Скуби, я обнаружил, что я был частично неправ в этом.Если вы используете внешне определенный объект в «mapper», Scoobi требует, чтобы он был сериализуемым, и будет жаловаться во время выполнения, если это не так.Поэтому, возможно, правильный путь - просто сделать мой сериализуемый Extractor
и десериализовать его в методе установки Mapper ...
Кроме того, я на самом деле работаю в Scala, так что решения на основе Scala определенно приветствуются (если не поощряется!)