Плохая производительность на хэш-джойне с Pig на Tez - PullRequest
0 голосов
/ 02 мая 2018

У меня есть серия сценариев Pig, которые преобразуют сотни миллионов записей из нескольких источников данных, которые необходимо объединить. К концу каждого сценария я достиг точки, где производительность JOIN становится ужасно низкой. Глядя на группу доступности базы данных в Tez View, я вижу, что она разбита на относительно немного задач (обычно 100-200), но каждая задача занимает несколько часов. Описание задачи показывает, что она выполняет HASH_JOIN.

Интересно, что я сталкиваюсь с этим узким местом только при работе на исполнительном движке Tez. На MapReduce это все еще может занять некоторое время, но ничего подобного мучительному сканированию, которое я получаю на Tez. Однако, запуск на MapReduce является проблемой, так как у меня есть проблема с MapReduce, для которой я задал еще один вопрос здесь .

Вот пример моего кода (извинения, я должен был сделать код очень универсальным, чтобы иметь возможность публиковать на межсетях). Мне интересно, что я могу сделать, чтобы устранить это узкое место - поможет ли указание параллелизма? Что-то не так с моим подходом?

-- Incoming data:
-- A: hundreds of millions of rows, 19 fields
-- B: hundreds of millions of rows, 3 fields
-- C: hundreds of millions of rows, 5 fields
-- D: a few thousand rows, 5 fields

J = -- This reduces the size of A, but still probably in the hundreds of millions
    FILTER A
    BY qualifying == 1;

K = -- This is a one-to-one join that doesn't explode the number of rows in J
    JOIN J BY Id
       , B BY Id;

L =
    FOREACH K
    GENERATE J1 AS L1
           , J2 AS L2
           , J3 AS L3
           , J4 AS L4
           , J5 AS L5
           , J6 AS L6
           , J7 AS L7
           , J8 AS L8
           , B1 AS L9
           , B2 AS L10
           ;

M = -- Reduces the size of C to around one hundred million rows
    FILTER C
    BY Code matches 'Code-.+';

M_WithYear =
    FOREACH M
    GENERATE *
           , (int)REGEX_EXTRACT(Code, 'Code-.+-([0-9]+)', 1) AS year:int
           ;

SPLIT M_WithYear
    INTO M_annual IF year <= (int)'$currentYear' -- roughly 75% of the data from M
       , M_lifetime IF Code == 'Code-Lifetime'; -- roughly 25% of the data from M

-- Transformations for M_annual

N =
    JOIN M_WithYear BY Id, D BY Id USING 'replicated';

O = -- This is where performance falls apart
    JOIN N BY (Id, year, M7) -- M7 matches L7
       , L BY (Id, year, L7);

P =
    FOREACH O
    GENERATE N1 AS P1
           , N2 AS P2
           , N3 AS P3
           , N4 AS P4
           , N5 AS P5
           , N6 AS P6
           , N7 AS P7
           , N8 AS P8
           , N9 AS P9
           , L1 AS P10
           , L2 AS P11
           ;

-- Transformations N-P above repeated for M_lifetime
...