Я постараюсь объяснить.
Часть 1:
Что имел в виду ответчик под ключом «Эти различные» будет частью ключа разделения фазы MapReduce Shuffle «? Не могли бы вы объяснить больше об этом? UDAF GenericUDAFCount
может работать как count
, так и count distinct
. Как это работает для достижения count distinct
?
Давайте возьмем в качестве примера следующий запрос:
select category, count(distinct brand) from market group by category;
Для этого запроса будет запущено одно задание MapReduce.
distinct-by
- это выражения (столбцы) в count(distinct ...
, в данном случае brand
.
partition-by
- это поля, используемые для вычисления кода ha sh для записи в фазе map
. И затем это значение ha sh используется для определения, какой раздел записи должен go. Обычно partition-by
ключи находятся в group by
части запроса SQL. В данном случае это category
.
Фактические output-key
мапперов будут составлять из клавиши partition-by
и клавиши distinct-by
. Для вышеприведенного случая клавиша вывода картографа может быть похожа (напиток, Pepsi).
В этом исполнении все ряды с одинаковым ключом group-by
попадают в один и тот же редуктор.
Здесь value
часть вывода картографов не имеет значения.
Позже на этапе перемешивания записи сортируются по ключам sort-by
, что совпадает с output key
.
Затем на этапе reduce
на каждом отдельном редукторе все записи сначала сортируются по категориям, а затем по брендам. Это позволяет легко получить результат агрегирования count(distinct )
. Каждая отдельная пара (категория, марка) гарантированно обрабатывается только один раз. Агрегация была превращена в count(*)
в каждой группе. Клавиша ввода вызова метода reduce
будет одной из этих отдельных пар. Процессы редуктора отслеживают составной ключ. Всякий раз, когда часть категории меняется, мы знаем, что пришла новая группа, и мы начинаем считать эту группу с 1.
Часть 2:
Почему будет только один редуктор в этом случае? При расчете count distinct
без group by
, например:
select count(distinct brand) from market
Будет работать только один редуктор, который будет выполнять всю работу. Почему? Поскольку ключ partition-by
не существует, или мы можем сказать, что все записи имеют одинаковый код ha sh. Так они попадут в один и тот же редуктор.
Часть 3:
Почему странный внутренний запрос вызовет больше разделов?
Ключ partition-by
внутреннего запроса - это ключ group by
, id
. Существует вероятность того, что значения id
распределены достаточно равномерно, поэтому записи обрабатываются многими различными редукторами. Затем после внутреннего запроса можно с уверенностью заключить, что все id
отличаются друг от друга. Так что теперь просто count(1)
- это все, что нужно.
Но учтите, что на выходе будет запущен только один редуктор. Почему не страдает? Поскольку для count(1)
не требуются подробные значения, агрегация на стороне карты значительно сокращает объем данных, обрабатываемых редукторами.
Еще одна вещь, эта перезапись не гарантированно будет работать лучше, поскольку она вводит дополнительную стадию MR.