Skip to content

[pig] map reduce for unbalanced key distribution

dsindex edited this page Jul 30, 2014 · 5 revisions

입력 데이터의 key값 분포가 불균형하게 한쪽으로 심하게 몰려있는 경우(skewed), 이 데이터를 'LOAD'해서 바로 'GROUP BY'하면 heap size error가 떨어지는 경우가 많다. 이를 해결하기 위해서는 reducer들의 입력을 고르게 만들기 위해 partitioner등을 구현해서 사용할수도 있지만, key를 재분산시키는 것 자체가 불가능할 경우라면 어떻게 해야할까? (사실 대부분의 문제가 그렇다)

모든 문제에 적용되는 것은 아니겠지만, 간단한 원칙이 하나 있다.

divide and conquer

reducer에서 처리할 일을 mapper로 당겨서 어느정도 처리해주는 방식이다. (merge sort 알고리즘과 비슷한 개념)

개별 mapper에 같은 key를 가진 데이터들이 많이 몰릴수록 reducer가 처리할 데이터가 줄어들게 되어서 메모리 관련 오류를 피할수 있게된다. ( 여기서도 또 하나의 tip이 있는데, pig에서 데이터를 'LOAD'하고 바로 'STORE'를 하면 key값이 분산되어 있는 part 파일들을 읽어서 같은 key값을 갖는 데이터를 모아주는 연산이 수행된다. )

sample pig script

데이터 단순 정렬 및 분산

A = LOAD '$output1' USING PigStorage('\t');   
STORE A INTO '$output2' USING PigStorage('\t'); <-- 같은 종류의 key값을 가급적 하나의 파일로 모은다. 정렬 및 block 단위로 입력 분산   

reducer에서 할일을 mapper에서 전처리

define mapcmd    `$progname1` ship('$progpath1');
define reducecmd `$progname2` ship('$progpath2');

A = LOAD '$input' USING PigStorage('\t');

B = STREAM A THROUGH mapcmd AS (key1, key2, val1, val2, val3);  <-- 부분 병합 처리

C = GROUP B BY (key1, key2);
D = FOREACH C GENERATE FLATTEN($1);
E = STREAM D THROUGH reducecmd AS (key1, key2, val1, val23);    <-- 전체 병합 처리
F = ORDER E BY key1 ASC, key2 ASC;
STORE F INTO '$output' USING PigStorage('\t');

idea behind

general

  • 이 문서를 참고
  • map-reduce performance 튜닝을 위한 요소로 존재하는 combiner에 주목

combiner

  • 데이터 단순 정렬 및 분산은 combiner의 효율성을 높이기 위해서 미리 key값이 같은 경우 같은 파일에 모이게 한다. 물론, 여러개의 파일에 걸쳐서 같은 key값이 존재할 수 있다.

  • reducer에서 할 일을 mapper에서 전처리는 사실상 combiner와 동일한 기능을 수행한다. combiner를 구현하기 위해서는 여기 언급된 것과 같이 여러가지 조건이 필요하지만, streaming을 사용하는 구현에서는 map 프로그램의 내부에서 자체적으로 구현하면 된다.

Clone this wiki locally