Количество редукторов в группе по и подсчету (отдельные)
Мне сказали, что счетчик (отдельный) может привести к перекосу данных, потому что используется только один редуктор.
Я провел тест, используя таблицу с 5 миллиардами данных с 2 запросами,
Запрос A:
select count(distinct columnA) from tableA
Запрос B:
select count(columnA) from
(select columnA from tableA group by columnA) a
На самом деле запрос A занимает около 1000-1500 секунд, а запрос B - 500-900 секунд. Результат кажется ожидаемым.
Однако я понимаю, что оба запроса используют 370 mappers
а также 1 reducers
и у них почти same cumulative CPU seconds
. А это значит, что у них нет естественной разницы, а разница во времени может быть вызвана загрузкой кластера.
Я не понимаю, почему все используют редукторы one 1, и я даже попробовал mapreduce.job.reduces
Но это не работает. Кстати, если все они используют редукторы 1, почему люди предлагают не использоватьcount(distinct )
и кажется, что перекоса данных нельзя избежать?
1 ответ
Оба запроса используют одинаковое количество средств сопоставления, которое ожидается, и один конечный редуктор, что также ожидается, потому что вам нужен один результат скалярного подсчета. Несколько редукторов в одной вершине работают независимо, изолированно, и каждый будет производить свой собственный результат, поэтому на последнем этапе есть один редуктор. Разница в плане.
При выполнении первого запроса единственный редуктор считывает каждый вывод сопоставителя и выполняет отдельный подсчет для всех данных, он обрабатывает слишком много данных.
Второй запрос использует промежуточную агрегацию, и конечный редуктор получает частично агрегированные данные (отдельные значения, агрегированные на предыдущем шаге). Конечному редуктору необходимо снова агрегировать частичные результаты, чтобы получить окончательный результат, это может быть намного меньше данных, чем в первом случае.
Начиная с Hive 1.2.0, есть оптимизация для подсчета (отдельного), и вам не нужно переписывать запрос. Установите это свойство:hive.optimize.distinct.rewrite=true
Также существует агрегация маппера (маппер также может предварительно агрегировать данные и создавать отдельные значения в рамках своей части данных - разбиения). Установите это свойство, чтобы разрешить агрегирование на стороне карты: hive.map.aggr=true
используйте команду EXPLAIN, чтобы проверить разницу в плане выполнения.
См. Также этот ответ: /questions/44631260/v-hive-kakoj-zapros-luchshe-i-pochemu/44631278#44631278