Если мое понимание верно, вы хотите посчитать, сколько различных значений будет иметь ключ.
Простое излучение пар «ключ-значение» в преобразователе, а затем подсчет различных значений для каждого ключа (например, путем добавления их в набор и вывода размера набора в качестве значения редуктора) в редукторе.это один из способов сделать это, но, как вы говорите, немного излишним
Как правило, вы хотите уменьшить сетевой трафик, поэтому вы можете захотеть сделать еще несколько вычислений перед перетасовкой (да, это делает Hadoop).
Два простых способа повышения эффективности:
1) Используйте сумматор, который будет выводить наборы значений, а не отдельные значения.Таким образом, вы будете отправлять меньше пар ключ-значение в редукторы, а также некоторые значения могут быть пропущены, поскольку они уже были в локальном наборе значений того же ключа.
2) Использовать агрегацию на стороне карты.Вместо непосредственного вывода входных пар ключ-значение сохраните их локально в преобразователе (в памяти) в структуре данных (например, hashmap или multimap).Ключ может быть ключом ввода карты, а значение может быть набором значений, которые до сих пор рассматривались для этого ключа.Каждый тип вы встречаете новое значение для этого ключа, вы добавляете его к этой структуре.В конце каждого преобразователя вы генерируете эту структуру (или конвертируете значения в массив) из метода close () (если я помню имя).
Вы можете искать оба метода, используя ключевые слова "объединитель" и "агрегация на стороне карты".
Глобальная сортировка по ключу немного сложнее.Опять же, два основных варианта, но они не очень хороши: 1) вы используете один редуктор, но затем вы ничего не получите от параллелизма, 2) вы используете разделитель общего порядка, который требует дополнительного кодирования.
Кроме этого, вы можете перейти к Spark для более интуитивного и эффективного решения.