WordCount - надём слово которое встречается максимальное число раз
Primary tabs
Forums:
Добавим в public static class IntSumReducer два дополнительных поля для хранения слова которое входит в текст максимум раз и числа вхождений:
Text max_occured_key = new Text(); int max_sum = 0;
И также переопределим родительский метод, который вызывается после того как редуктор отработал:
@Override
protected void cleanup(Context context) throws InterruptedException {
try{
context.write(new Text("maximum===== "), new IntWritable(0)); // для разделения
context.write(max_occured_key, new IntWritable(max_sum)); // максимум (сам ответ)
context.write(new Text("-------------- "), new IntWritable(0)); // для разделения
}
catch(IOException e){
e.printStackTrace();
}
}а вот Job сконфигурируем таким образом:
Job job = new Job(conf, "word count");
job.setJarByClass(WordCount.class);
job.setMapperClass(TokenizerMapper.class);
// job.setCombinerClass(IntSumReducer.class);
job.setReducerClass(IntSumReducer.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
FileInputFormat.addInputPath(job, new Path(otherArgs[0]));
FileOutputFormat.setOutputPath(job, new Path(otherArgs[1]));"Выходной файл" программы будет выглядеть как-то так.
То есть в общем-то всё осталось по-прежнему, но мы убрали локальный редуктор, в качестве которого предлагалось использовать наш основной редуктор - IntSumReducer.class, кстати - если строчку раскомментировать, то мы получим вот такой вывод - то есть локальный редуктор будет запущен (создан) дважды (у нас два файла) - но его работа никак не повлияет на окончательный вывод главного редуктора.
Ещё
Кстати, ещё можно посмотреть когда запускается редуктор, а когда комбинаторы (если строчку раскомментировать) -
чтобы напечатать "относительный момент запуска" -переопределим метод редуктора setup() (вызывается до начала остальных действий редуктора - в начале подзадачи):
@Override
protected void setup(Context context) throws IOException,
InterruptedException{
try{
context.write(new Text("reduser start "), new IntWritable(0));
}
catch(IOException e){
e.printStackTrace();
}
}
Тогда мы получим вот такой вывод.
Отдельный комбинатор
Теперь неплохо было бы выделить комбинатор в отдельный класс - дабы убедиться что это именно комбинатор начинается с данной строки (в файле вывода, так как например здесь не понятно - точно ли первая строка относится к редуктору или же к комбинатору)
Так как в примере выше мы видели, что можно использовать класс типа "редуктор" для комбинатора -поэтому просто скопируем наш IntSumReducer , переименуем его в IntSumCombiner - и поменяем комментарии для выводимых (выходных) данных.
Теперь видно, что редуктор в нашем случае действительно запускается раньше комбинеров, но результат возвращает уже после них.
- Log in to post comments
- 5640 reads