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
- 5113 reads