Apache Pig: FLATTEN и параллельное выполнение редукторов

Я реализовал Apache Pig script. Когда я выполняю script, это приводит к появлению многих параметров для определенного шага, но для этого шага имеет только один редуктор. Из-за этого условия (многие преобразователи, один редуктор) кластер Hadoop почти не работает, пока выполняется единственный редуктор. Чтобы лучше использовать ресурсы кластера, я хотел бы также иметь много редукторов, работающих параллельно.

Даже если я установил parallelism в Pig script с помощью команды SET DEFAULT_PARALLEL, я все равно получаю только 1 редуктор.

Часть кода, выдающая проблему, следующая:

SET DEFAULT_PARALLEL 5;
inputData = LOAD 'input_data.txt' AS (group_name:chararray, item:int);
inputDataGrouped = GROUP inputData BY (group_name);
-- The GeneratePairsUDF generates a bag containing pairs of integers, e.g. {(1, 5), (1, 8), ..., (8, 5)}
pairs = FOREACH inputDataGrouped GENERATE GeneratePairsUDF(inputData.item) AS pairs_bag;
pairsFlat = FOREACH pairs GENERATE FLATTEN(pairs_bag) AS (item1:int, item2:int);

Атрибуты 'inputData' и 'inputDataGrouped' вычисляются в mapper.

"пары" и "парыFlat" в редукторе.

Если я изменю script, удалив строку с помощью команды FLATTEN (парыFlat = FOREACH пары GENERATE FLATTEN (pairs_bag) AS (item1: int, item2: int);), тогда выполнение приводит к 5 редукторам (и, следовательно, в параллельном исполнении).

Кажется, что команда FLATTEN является проблемой и позволяет избежать создания многих редукторов.

Как я могу достичь того же результата FLATTEN, но при выполнении script параллельно (со многими редукторами)?

Edit:

Планирование EXPLAIN при наличии двух FOREACH (как указано выше):

Map Plan
inputDataGrouped: Local Rearrange[tuple]{chararray}(false) - scope-32
|   |
|   Project[chararray][0] - scope-33
|
|---inputData: New For Each(false,false)[bag] - scope-29
    |   |
    |   Cast[chararray] - scope-24
    |   |
    |   |---Project[bytearray][0] - scope-23
    |   |
    |   Cast[int] - scope-27
    |   |
    |   |---Project[bytearray][1] - scope-26
    |
    |---inputData: Load(file:///input_data.txt:org.apache.pig.builtin.PigStorage) - scope-22--------


Reduce Plan
pairsFlat: Store(fakefile:org.apache.pig.builtin.PigStorage) - scope-42
|
|---pairsFlat: New For Each(true)[bag] - scope-41
    |   |
    |   Project[bag][0] - scope-39
    |
    |---pairs: New For Each(false)[bag] - scope-38
        |   |
        |   POUserFunc(GeneratePairsUDF)[bag] - scope-36
        |   |
        |   |---Project[bag][1] - scope-35
        |       |
        |       |---Project[bag][1] - scope-34
        |
        |---inputDataGrouped: Package[tuple]{chararray} - scope-31--------
Global sort: false

План EXPLAIN при наличии только одного FOREACH с FLATTEN, обертывающего UDF:

Map Plan
inputDataGrouped: Local Rearrange[tuple]{chararray}(false) - scope-29
|   |
|   Project[chararray][0] - scope-30
|
|---inputData: New For Each(false,false)[bag] - scope-26
    |   |
    |   Cast[chararray] - scope-21
    |   |
    |   |---Project[bytearray][0] - scope-20
    |   |
    |   Cast[int] - scope-24
    |   |
    |   |---Project[bytearray][1] - scope-23
    |
    |---inputData: Load(file:///input_data.txt:org.apache.pig.builtin.PigStorage) - scope-19--------


Reduce Plan
pairs: Store(fakefile:org.apache.pig.builtin.PigStorage) - scope-36
|
|---pairs: New For Each(true)[bag] - scope-35
    |   |
    |   POUserFunc(GeneratePairsUDF)[bag] - scope-33
    |   |
    |   |---Project[bag][1] - scope-32
    |       |
    |       |---Project[bag][1] - scope-31
    |
    |---inputDataGrouped: Package[tuple]{chararray} - scope-28--------
Global sort: false

Ответ 1

Нет уверенности, если свинья использует значение DEFAULT_PARALLEL для каждого шага свинья script. Попробуйте PARALLEL вместе со своим конкретным шагом присоединения/группы, который вы считаете необходимым (в вашем случае шаг GROUP).

 inputDataGrouped = GROUP inputData BY (group_name) PARALLEL 67;

Если все еще не работает, вам, возможно, придется увидеть ваши данные для проблемы с асимметрией.

Ответ 2

Я думаю, что в данных есть асимметрия. Только небольшое количество преобразователей производит экспоненциально большую мощность. Посмотрите на распределение ключей в ваших данных. Подобные данные содержат несколько групп с большим количеством записей.

Ответ 3

Я попробовал "установить параллель по умолчанию" и "PARALLEL 100", но не повезло. Свинья все еще использует 1 редуктор.

Оказалось, что я должен генерировать случайное число от 1 до 100 для каждой записи и группировать эти записи по этому случайному числу.

Мы тратим время на группировку, но для меня это намного быстрее, потому что теперь я могу использовать больше редукторов.

Вот код (SUBMITTER - мой собственный UDF):

tmpRecord = FOREACH record GENERATE (int)(RANDOM()*100.0) as rnd, data;
groupTmpRecord = GROUP tmpRecord BY rnd;
result = FOREACH groupTmpRecord GENERATE FLATTEN(SUBMITTER(tmpRecord));

Ответ 4

Чтобы ответить на ваш вопрос, мы должны сначала узнать, сколько свиней для свиней применяют для выполнения глобального процесса перераспределения. Потому что, согласно моему пониманию, Generate/Projection не требует ни одного редуктора. Я не могу сказать то же самое о Flatten. Однако из здравого смысла мы знаем, что во время сглаживания цель состоит в том, чтобы обезжирить кортежи из сумок и наоборот. И чтобы сделать это, все кортежи, принадлежащие сумке, обязательно должны быть доступны в одном и том же редукторе. Я могу быть не прав. Но может ли кто-нибудь добавить что-то здесь, чтобы получить ответ от этого пользователя?