Combine input records가 Map output records보다 많은 이유

팀 매니저님께서 결과를 보시며 의문을 표하시기에, 조사해봄.

일단 Hadoop Definite Guide 책에서 Combiner Function에 대해 찾아보면,

Many MapReduce jobs are limited by the bandwidth available on the cluster, so it pays to minimize the data transferred between map and reduce tasks. Hadoop allows the user to specify a combiner function to be run on the map output—the combiner function’s output forms the input to the reduce function.
from Hadoop Definite Guide 2nd edition, Ch2. MapReduce

이렇게 나와 있다. 대충 정리해보면, map output에 대해 combiner를 적용한 다음, 이 결과가 reduce의 input으로 쓰이며, combiner를 적용함으로써, map에서 reduce로 전송되는 데이터 양을 줄일 수 있다라고 설명하고 있다.

이렇게만 보면, map의 output이 combiner의 input으로 사용되는 것처럼 보이므로, map output records와 combine input records가 일치해야 하는 것처럼 보인다. 그러나 실제로는 combine input records가 더 큰 경우가 많다. (항상 많은지는 모르겠음) 왜 그럴까?

천신만고 끝에 찾은 힌트 하나

After the shuffle each reducer will have one input for each map. The reducer needs to merge these inputs in order to begin processing. It is not efficient to merge too many inputs simultaneously. Thus, if the number of inputs exceeds a certain value, the data will be merged and rewritten to disk before being given to the reducer. During this merge the combiner will be applied in an attempt to reduce the size of the input data.
from Oreilly

나는 지금까지 combiner는 mapper에서만 동작하는지 알았는데, 실제로는 reducer에서 data를 shuffle하는 단계 (정확히는 merge)에서도 combiner가 동작을 한다!

좀 더 자세히 설명을 하면,

image
from Hadoop Definite Guide 2nd edition, Ch6. How MapReduce Works

  1. map의 output을 memory에 쓰다가, 할당된 memory buffer (기본은 100 MB)의 일정 비율 (기본은 80%)을 넘어서면, 현재 memory에 저장된 map의 output을 mapper node의 local file로 쓴다. (이 과정을 spill이라고 함)
  2. 실제 file로 쓰기 전에, 해당 data가 전송될 reducer 단위로 partitioning을 하고, 각각의 partition에 대해 백그라운드 thread가 in-memory sorting을 수행한 다음, sort의 output에 대해 combine 함수가 실행된다.
  3. memory buffer가 spill threashold에 다다르면, 새로운 spill file이 생성되며, 실제 map task가 수행되는 동안, 이러한 spill file이 여러 개 생성된다. map task 가 끝나기 전에, 여러 개의 spill file들을 하나의 파일로 합치게 되는데, 이렇게 하나의 파일로 merge를 하는 단계에서도 combine 함수가 실행된다.
  4. mapper의 결과가 reducer로 copy된 다음, reducer에서 여러 mapper에서 온 결과들을 sort하는 과정을 거치는데, 이 때 각각의 merge 단계에서도 combine 함수가 실행된다.

요약하면, mapper 뿐만이 아니라, reducer 단계에서도 combine 함수가 적용될 수 있으므로, Combine input records의 수가 Map output records의 수 보다 클 수도 있다.

※ 여기서 개발자들이 combiner를 사용할 때 유의해야 할 점은, combiner의 input으로 항상 map의 output이 들어온다 라고 가정을 하면 안 된다는 점이다. 위 설명에서도 알 수 있듯이, combiner의 output이 다시 combiner의 input으로 들어올 수 있다. 그러므로, combiner의 input은 map의 output format 뿐만 아니라, combiner의 output format도 적절히 처리할 수 있어야 한다.

댓글

Designed by JB FACTORY