← 목록으로
AI·데이터
#MapReduce#Hadoop#분산처리#Map#Reduce#Shuffle#데이터지역성#빅데이터배치
최종 업데이트 · 2026-09-28

MapReduce 기반 대규모 분산 데이터 처리

1. 개요

가. 정의

MapReduce란 대규모 입력을 키-값(key-value) 레코드로 나누어 여러 노드에서 Map 연산을 병렬 수행하고, 같은 중간 키를 가진 값을 모아 Reduce 연산으로 집계하는 분산 처리 프로그래밍 모델이자 실행 프레임워크이다.

MapReduce의 핵심은 개발자가 업무 계산을 map 함수와 reduce 함수로 표현하면 실행 시스템이 입력 분할, 스케줄링, 네트워크 전송, 정렬, 장애 복구를 대신한다는 점이다. 따라서 개발자는 노드 간 통신과 개별 서버 장애를 모두 직접 구현하지 않고도 수백 대 이상의 범용 서버에서 배치 계산을 확장할 수 있다.

이 모델은 Google이 2004년 발표한 논문에서 대규모 데이터 처리를 단순화하기 위한 추상화로 체계화되었고, 오픈소스 Hadoop MapReduce를 통해 널리 확산되었다. 오늘날에는 Spark·Flink·분산 SQL과 같은 엔진이 더 빠른 반복 계산이나 스트림 처리를 담당하는 경우가 많지만, MapReduce의 분할·셔플·집계 개념은 여전히 데이터 플랫폼의 기본 원리로 활용된다.

나. 등장 배경과 필요성

전통적인 단일 서버 배치 프로그램은 데이터가 서버의 메모리와 디스크 용량을 넘으면 수직 확장에 의존해야 한다. 그러나 로그, 클릭스트림, 센서, 거래 기록은 저장량과 유입량이 빠르게 증가하므로 한 대의 서버를 더 큰 장비로 교체하는 방식만으로는 비용과 장애 위험을 동시에 관리하기 어렵다.

분산 처리는 여러 서버에 데이터를 나누고 계산을 병렬화하여 처리량을 높인다. 하지만 직접 분산 프로그램을 작성하면 작업 분할, 노드 장애, 재시도, 결과 병합, 네트워크 병목을 모두 애플리케이션이 책임져야 한다. MapReduce는 이 공통적인 복잡성을 프레임워크 계층으로 이동시켜 비즈니스 로직을 두 함수 중심으로 단순화한다.

특히 데이터가 저장된 노드에서 계산을 수행하는 데이터 지역성(data locality)은 대규모 처리에서 중요하다. 모든 데이터를 중앙 서버로 끌어오면 네트워크가 병목이 되지만, MapReduce는 가능한 한 입력 블록이 있는 노드에 map 작업을 배치하여 네트워크 전송량을 줄인다.

다. 핵심 목표

MapReduce 설계의 목표는 단순히 여러 서버를 사용하는 데 있지 않다. 처리량 확장성, 장애 허용성, 프로그래밍 단순성, 데이터 지역성, 운영 자동화를 함께 달성하는 것이 목적이다.

첫째, 입력을 독립적인 조각으로 분할하여 map 작업을 병렬화한다. 둘째, 같은 키를 기준으로 중간 결과를 재분배하여 집계의 기준을 명확하게 한다. 셋째, 실패한 작업만 재실행하여 일부 노드 장애가 전체 배치 실패로 이어지지 않게 한다.

다만 MapReduce는 여러 단계의 중간 결과를 디스크에 기록하는 배치 모델이다. 따라서 짧은 지연시간의 온라인 조회나 반복적인 머신러닝 알고리즘에는 추가적인 메모리 기반 엔진이 더 적합할 수 있다.

2. 프로그래밍 모델과 실행 구조

가. 키-값 추상화

MapReduce는 입력과 출력의 본질을 <key, value> 쌍으로 본다. 입력 키는 파일 위치, 레코드 번호, 데이터베이스 기본키일 수 있고 입력 값은 한 줄의 텍스트, JSON 문서, 센서 레코드일 수 있다.

map 함수는 하나의 입력 레코드를 읽어 0개 이상의 중간 키-값 쌍을 내보낸다. reduce 함수는 하나의 중간 키와 그 키에 연결된 값들의 목록을 받아 더 작은 결과를 생성한다.

map(k1, v1) -> list(k2, v2)
reduce(k2, list(v2)) -> list(k3, v3)

이 추상화는 특정 업무를 숨기지 않고 계산의 경계를 명확히 한다. map은 레코드 단위 변환과 필터링을 맡고, reduce는 동일한 논리 키의 집계와 병합을 맡는다.

나. 전체 아키텍처

flowchart LR
    IN[입력 파일·테이블] --> SPLIT[Input Split]
    SPLIT --> MR[Mapper]
    MR --> COMB[Combiner 선택]
    COMB --> PART[Partitioner]
    PART --> SHUF[Shuffle·Sort]
    SHUF --> RED[Reducer]
    RED --> OUT[분산 파일시스템 출력]
    RM[ResourceManager] -.스케줄·자원.-> MR
    RM -.스케줄·자원.-> RED
    NM[NodeManager] -.실행·상태보고.-> MR
    NM -.실행·상태보고.-> RED

Hadoop 환경에서는 ResourceManager가 애플리케이션 자원과 작업 배치를 조정하고, NodeManager가 각 작업 노드의 컨테이너 실행과 상태 보고를 담당한다. 애플리케이션별 ApplicationMaster는 map·reduce 태스크의 진행을 관리하고 실패 태스크의 재실행을 요청한다.

입력은 InputFormat과 RecordReader를 통해 논리적인 레코드로 변환된다. 예를 들어 텍스트 파일은 한 줄을 하나의 값으로 읽고, 오프셋을 입력 키로 사용할 수 있다. 파일을 단순히 바이트 단위로 자르는 것이 아니라 레코드 경계가 보존되도록 처리하는 것이 데이터 정확성의 전제다.

각 map 태스크는 입력 split을 읽어 중간 결과를 로컬 디스크에 버퍼링한다. 중간 결과는 파티션별로 나뉘고 키 순으로 정렬되며, reducer가 가져갈 수 있는 파일과 인덱스 형태로 저장된다. 이 중간 결과는 최종 출력이 아니므로 작업이 성공하기 전까지 임시 산출물로 관리된다.

다. 처리 수명주기

  1. 클라이언트가 입력 경로, 출력 경로, mapper, reducer, 파티션 수를 포함한 작업 구성을 제출한다.
  2. 프레임워크가 입력 파일을 블록 또는 논리 레코드 경계에 따라 split으로 나눈다.
  3. 각 split에 대해 map 태스크를 배치하고 가능한 경우 데이터가 있는 노드에 우선 배치한다.
  4. mapper가 레코드를 읽어 중간 키-값 쌍을 생성하고 필요하면 필터링·변환한다.
  5. combiner가 동일 map 태스크 안의 부분 집계를 수행하여 셔플할 데이터 양을 줄인다.
  6. partitioner가 중간 키를 reducer로 보낼 파티션에 배정한다.
  7. reducer가 여러 mapper의 파티션을 원격으로 가져오고(shuffle), 키 순으로 병합 정렬한다.
  8. 동일 키의 값 목록을 reducer에 전달하여 집계·병합·조인을 수행한다.
  9. 출력 포맷이 결과를 분산 파일시스템에 기록하고 작업 성공 상태를 커밋한다.

이 순서에서 shuffle은 단순한 네트워크 복사가 아니다. 각 mapper의 출력에서 특정 reducer가 책임질 구간을 가져오고, 여러 파일을 키 순서로 병합하여 reduce 함수가 그룹화된 입력을 받도록 만드는 가장 비용이 큰 단계다.

sequenceDiagram
    participant C as 클라이언트
    participant AM as ApplicationMaster
    participant M as Mapper 노드
    participant R as Reducer 노드
    C->>AM: 작업 제출(Input·Output·함수)
    AM->>M: split별 map 태스크 배치
    M->>M: 중간 키-값 생성·로컬 정렬
    M->>R: 파티션별 shuffle 전송
    AM->>R: reduce 태스크 실행
    R->>R: 키별 그룹화·집계
    R-->>C: 출력 커밋·상태 보고

이 흐름에서 ApplicationMaster는 데이터 자체를 중앙에서 처리하지 않는다. 태스크의 위치와 상태를 조정하고 실패한 실행을 다시 요청하는 제어면이며, 실제 레코드 계산은 mapper와 reducer가 담당한다.

3. Map과 Reduce 구성요소의 원리

가. Mapper

Mapper는 입력 레코드 하나를 독립적으로 처리하는 것을 기본 전제로 한다. 따라서 한 레코드의 출력이 다른 레코드의 처리 순서를 요구하지 않으면 map 단계는 높은 병렬성을 얻는다.

예를 들어 웹 로그에서 상태 코드가 500인 요청만 추출하려면 mapper가 로그 한 줄을 파싱하고, 서비스명이나 날짜를 키로 하여 <서비스명, 1>을 내보내면 된다. 유효하지 않은 로그는 map 단계에서 버려 전체 셔플 비용을 줄일 수 있다.

Mapper에는 입력과 중간 출력의 타입 변환, 데이터 정제, 파티션 키 설계가 포함된다. 키를 잘못 설계하면 동일한 업무 집계 대상이 여러 키로 쪼개지거나 한 키에 데이터가 집중되어 reducer 병목이 발생한다.

나. Combiner

Combiner는 mapper와 reducer 사이에서 선택적으로 수행하는 로컬 집계 함수다. 단어 개수 세기에서 한 mapper가 cloud를 10,000번 읽었다면 <cloud, 1>을 그대로 전송하는 대신 <cloud, 10000>으로 압축할 수 있다.

그러나 모든 reduce 함수가 combiner로 안전한 것은 아니다. 함수가 교환법칙과 결합법칙을 만족하고 부분 결과를 다시 합쳐도 최종 결과가 같아야 한다. 합계, 개수, 최솟값, 최댓값은 일반적으로 적합하지만 평균은 합계와 개수를 함께 전달하지 않으면 단순 평균의 combiner가 될 수 없다.

Combiner는 실행 여부와 실행 횟수가 보장되지 않는다. 그러므로 업무적으로 필수인 계산을 combiner에만 두면 안 되고, 최종 정확성은 reducer가 보장해야 한다.

다. Partitioner

Partitioner는 중간 키를 어느 reducer가 처리할지 결정한다. 기본적으로 해시 기반으로 hash(key) mod R을 적용하지만, 날짜·지역·고객군처럼 업무 기준의 범위 분할이 필요하면 사용자 정의 partitioner를 사용할 수 있다.

좋은 partitioner는 같은 키를 반드시 같은 reducer로 보내고, reducer 간 데이터량을 균등하게 분배해야 한다. 키 분포가 치우친 경우 특정 reducer에 모든 인기 상품, 특정 지역, 한 날짜의 데이터가 몰리는 데이터 스큐가 발생한다.

스큐를 완화하려면 키에 소금값(salt)을 붙여 여러 파티션으로 나눈 뒤 두 번째 집계 단계에서 다시 합치거나, 인기 키를 별도 경로로 처리할 수 있다. 다만 임의의 소금값은 같은 논리 키의 최종 결합 단계를 추가하므로 처리 정확성과 단계 수를 함께 검토해야 한다.

라. Shuffle과 Sort

Shuffle은 map 출력의 파티션을 reducer로 이동시키는 과정이다. 네트워크 대역폭과 디스크 I/O가 동시에 사용되므로 전체 MapReduce 작업의 지연시간과 비용을 지배하는 경우가 많다.

Sort는 동일한 키가 연속해서 reducer에 전달되도록 중간 결과를 정렬하고 병합하는 단계다. reducer는 키별 값 목록을 직접 구성하지 않고 스트리밍 방식으로 그룹을 순회할 수 있어, 모든 데이터를 메모리에 올리지 않아도 된다.

셔플을 최적화하는 기본 방법은 mapper에서 불필요한 필드를 제거하고, combiner로 부분 집계를 수행하고, 압축을 적용하며, 적절한 파티션 수를 선택하는 것이다. 하지만 압축 CPU 비용이 너무 크거나 데이터가 이미 작다면 압축이 오히려 느려질 수 있다.

마. Reducer

Reducer는 동일한 중간 키에 대한 값들을 받아 합계, 정렬, 조인, 중복 제거, 통계 계산을 수행한다. reducer의 입력은 키 순으로 정렬되어 있으므로 키가 바뀌는 시점을 이용해 그룹별 상태를 정리할 수 있다.

Reducer는 재실행될 수 있으므로 외부 시스템에 부작용을 남기는 코드는 멱등적으로 설계해야 한다. 예를 들어 결과를 외부 API에 매번 전송하면 태스크 재시도 때 중복 요청이 발생할 수 있으므로, 임시 출력 후 원자적 커밋이나 멱등 키를 사용해야 한다.

4. 장애 허용성과 성능 설계

가. 태스크 재실행과 작업 의미

대규모 클러스터에서는 디스크 고장, 네트워크 단절, 프로세스 중단, 노드 과부하가 정상적으로 발생할 수 있다. MapReduce는 작업 전체를 처음부터 재실행하기보다 실패한 map 또는 reduce 태스크를 다른 노드에서 다시 실행한다.

입력 데이터가 분산 파일시스템에 복제되어 있으면 실패한 map 태스크를 다른 복제본이 있는 노드에서 재실행할 수 있다. 이 방식은 장애 복구와 데이터 지역성을 동시에 고려한다.

같은 태스크가 다른 태스크보다 지나치게 느린 straggler가 되면 speculative execution으로 동일 작업을 다른 노드에서 중복 실행하고 먼저 성공한 결과를 채택할 수 있다. 그러나 외부 부작용이 있는 mapper·reducer라면 중복 실행이 중복 결제를 일으킬 수 있으므로 순수 함수 또는 멱등성 보장이 필요하다.

나. 데이터 지역성과 파일 설계

MapReduce 성능은 CPU보다 데이터 이동량에 의해 제한되는 경우가 많다. 입력 블록이 있는 노드에서 map을 실행하면 네트워크를 거치지 않고 로컬 디스크를 읽을 수 있지만, 스케줄러가 자원 균형을 위해 원격 노드에 배치하면 전송 비용이 증가한다.

너무 작은 파일이 많으면 파일마다 split과 태스크가 만들어져 작업 시작 비용과 메타데이터 부하가 커진다. 반대로 거대한 파일을 지나치게 적은 split으로 만들면 병렬성이 낮아진다. 파일 크기, 블록 크기, 태스크 수, 노드 수를 함께 조정해야 한다.

다. 시간·공간 복잡도

map 자체의 계산량을 (M), 중간 레코드 수를 (I), reducer 수를 (R)이라 하면 전체 비용은 map 계산, 중간 데이터 기록, (I)의 셔플·정렬, reduce 계산의 합으로 생각할 수 있다. 특히 (I)가 원본보다 크게 증가하면 네트워크와 디스크 비용이 급증한다.

이론적으로 map 단계는 입력 분할 수에 비례해 병렬화되지만, shuffle은 모든 mapper와 reducer 사이의 데이터 이동 경로를 만든다. 따라서 단순히 reducer 수를 늘리는 것만으로 성능이 선형 개선되지 않으며, 파티션 불균형과 작은 파일 문제를 먼저 측정해야 한다.

라. 관측성과 운영 지표

운영자는 전체 작업 시간만 보지 말고 map 입력량, map 출력량, combiner 절감률, 셔플 바이트, 셔플 대기시간, reducer별 입력 편차, 실패·재시도 횟수를 관찰해야 한다.

특정 reducer만 오래 걸리면 파티셔너나 키 분포를 조사해야 하며, 모든 reducer의 셔플 대기시간이 길면 네트워크·디스크·압축 설정을 확인해야 한다. map 출력량이 입력보다 지나치게 크면 필터링과 집계 위치를 앞당길 수 있다.

작업별 SLA를 운영할 때는 평균 시간보다 95·99 백분위 지연시간과 재실행 횟수를 함께 관리해야 한다. 배치가 매일 반복된다면 이전 실행의 입력량과 처리량을 기준선으로 두어 데이터 급증을 조기에 감지한다.

5. 예제와 응용 사례

가. WordCount

WordCount는 MapReduce의 구조를 설명하는 대표 사례다. mapper는 문장을 단어로 분리하여 <단어, 1>을 출력하고, combiner는 같은 map 태스크 안에서 단어별 부분 합계를 계산하며, reducer는 모든 부분 합계를 더해 <단어, 전체 개수>를 출력한다.

이 사례의 핵심은 업무 계산이 간단해서가 아니라 키를 기준으로 데이터가 자동 그룹화된다는 점이다. 파일이 여러 노드에 나뉘어 있어도 cloud라는 동일 키는 하나의 논리 그룹으로 모이고, reducer는 자신에게 배정된 키만 처리한다.

나. 역색인

검색 시스템의 역색인은 문서 ID와 단어의 관계를 뒤집어 단어별 문서 목록을 만드는 작업이다. mapper는 문서를 읽어 <단어, 문서ID>를 출력하고, reducer는 같은 단어의 문서 ID를 정렬·중복 제거하여 posting list를 만든다.

대규모 문서 집합을 처리할 때 문서별 처리는 병렬화하기 쉽지만 인기 단어에 값이 집중될 수 있다. 따라서 빈도수가 높은 불용어를 사전에 제거하거나, 분할된 목록을 후속 단계에서 병합하는 설계가 필요하다.

다. 로그와 거래 데이터 집계

일별 서비스별 오류 건수는 mapper가 로그를 파싱해 <일자|서비스, 1>을 만들고 reducer가 합산하는 방식으로 계산할 수 있다. 거래 데이터의 고객별 총액도 <고객ID, 금액>을 만들고 합계하는 구조로 표현된다.

다만 규제 대상 거래나 개인정보가 포함된 경우 원본 로그의 접근권한, 암호화, 마스킹, 보존기간을 별도로 설계해야 한다. 분산 처리 프레임워크를 사용한다고 해서 데이터 거버넌스 책임이 사라지는 것은 아니다.

6. 비교 — MapReduce와 대안 기술

MapReduce는 디스크 기반 단계 실행과 자동 재시도를 강점으로 한다. 반면 반복 알고리즘에서 매 단계마다 중간 결과를 저장하면 지연시간이 커진다. 기술 선택은 데이터 크기만이 아니라 지연시간, 재사용성, 상태 유지, 데이터 형태에 따라 결정해야 한다.

구분 MapReduce Spark 분산 SQL 스트림 처리 엔진
기본 처리 배치·단계형 메모리 기반 DAG·배치 선언적 질의 이벤트 연속 처리
중간 데이터 주로 디스크 캐시·메모리 활용 가능 엔진이 계획 상태 저장·체크포인트
강점 단순 모델·장애 재실행 반복 계산·낮은 지연 SQL 생산성·최적화 실시간성·윈도우
약점 셔플·디스크 지연 메모리 관리·튜닝 복잡한 사용자 코드 제약 상태·순서·중복 관리
적합 사례 대규모 정기 집계 ML·반복 변환 BI·애드혹 분석 알림·실시간 지표

Spark는 map과 reduce의 아이디어를 포함하지만 RDD·DataFrame·DAG로 여러 변환을 묶고 캐시할 수 있다. 따라서 같은 데이터를 반복 참조하는 알고리즘에서는 MapReduce보다 유리할 수 있으나, 메모리 압박과 셔플 관리가 사라지는 것은 아니다.

분산 SQL은 사용자가 실행 계획을 직접 작성하지 않아도 조인 순서, 필터 푸시다운, 파티션 프루닝을 최적화한다. 그러나 비정형 사용자 정의 로직이나 복잡한 외부 시스템 연동은 MapReduce·범용 데이터플로가 더 자연스러울 수 있다.

스트림 처리 엔진은 무한한 입력을 시간 윈도우와 상태로 나누어 계산한다. MapReduce의 유한 입력·재실행 중심 모델과 달리 이벤트 시간, 워터마크, 지연 도착, 중복 이벤트, 정확히 한 번 처리의 의미를 별도로 설계해야 한다.

7. 심화 — 현대 데이터 플랫폼에서의 위치와 예상 출제

MapReduce는 독립적인 제품 이름보다 분산 데이터 처리의 사고방식으로 이해하는 것이 좋다. 입력 분할, 키 기반 재분배, 부분 집계, 정렬, 최종 병합이라는 단계는 분산 SQL의 실행 계획과 데이터플로 엔진의 셔플 단계에서도 반복된다.

클라우드 오브젝트 스토리지와 컨테이너 환경에서는 저장 계층과 계산 계층이 분리되는 경향이 있다. 이 경우 전통적인 데이터 지역성의 의미가 로컬 디스크가 아니라 데이터 포맷, 파티션, 캐시, 네트워크 비용 최적화로 이동한다.

컬럼형 파일 포맷과 파티션 프루닝은 MapReduce 입력량을 줄이는 보완 기술이다. 날짜와 지역을 파티션 키로 설계하면 전체 파일을 읽지 않고 필요한 범위만 읽을 수 있지만, 파티션 수가 지나치게 많아지면 작은 파일 문제가 생긴다.

기술사 답안에서는 Map → Combine → Partition → Shuffle/Sort → Reduce의 처리 흐름을 그림으로 제시하고, WordCount나 로그 집계로 키-값 그룹화 원리를 설명하는 것이 효과적이다. 그 다음 데이터 지역성, 장애 재실행, 데이터 스큐, 셔플 병목을 성능·운영 관점에서 연결하면 단순 정의를 넘어선 논술이 된다.

예상 문제는 MapReduce의 구성요소와 처리 절차, Hadoop 환경의 장애 허용 메커니즘, Combiner와 Reducer의 차이, MapReduce·Spark·스트림 처리 비교, 데이터 스큐와 셔플 최적화 방안의 형태로 출제될 수 있다.

8. 고려사항 및 시사점

  • 업무를 키-값으로 표현할 수 있는지 먼저 검토한다. 모든 문제를 map과 reduce로 억지로 표현하면 다단계 조인과 중간 결과가 폭증한다. 업무의 집계 키와 데이터 흐름을 먼저 모델링하고, 적합하지 않으면 SQL·그래프·스트림 엔진을 선택해야 한다.

  • 셔플을 비용센터로 관리한다. 입력 데이터보다 중간 출력이 큰지, reducer별 입력 편차가 큰지, 네트워크와 로컬 디스크가 포화되는지를 측정한다. 필터링·부분 집계·압축·파티션 키 개선을 순서대로 적용하되 CPU 비용과 정확성을 함께 검증한다.

  • Combiner의 선택 실행을 전제로 한다. Combiner는 최적화 장치이지 정확성 보장 장치가 아니다. 교환법칙·결합법칙을 만족하는 부분 집계만 넣고, 최종 결과는 reducer만으로도 동일해야 한다.

  • 재실행 안전성을 확보한다. 태스크는 장애나 speculative execution 때문에 여러 번 실행될 수 있다. 외부 DB 기록, 파일 이동, 메시지 발행은 멱등 키·임시 경로·원자적 커밋으로 중복 효과를 차단한다.

  • 데이터 스큐를 업무적으로 해소한다. 단순히 reducer 수를 늘리면 인기 키 하나의 병목은 해결되지 않는다. 키 분할, 두 단계 집계, 인기 키 별도 처리, 사전 빈도 분석을 조합해야 한다.

  • 입력 파일과 파티션 수를 함께 설계한다. 작은 파일을 합치고 적정한 블록·split 크기를 사용하되, 지나치게 큰 split으로 병렬성을 떨어뜨리지 않는다. 파일 포맷과 파티션 프루닝이 실제 읽기량을 줄이는지도 검증한다.

  • 보안과 거버넌스를 실행 경로에 포함한다. 분산 노드에 복제되는 원본과 중간 파일의 암호화, 접근권한, 개인정보 마스킹, 감사로그, 보존·삭제 정책을 데이터 수명주기 전반에 적용한다.

  • 기술 선택을 SLA와 비용으로 평가한다. 정기 대용량 배치에는 MapReduce가 견고할 수 있지만, 초 단위 응답이나 반복 머신러닝에는 다른 엔진이 적합하다. 처리시간뿐 아니라 클러스터 비용, 운영 난이도, 장애 복구시간, 팀 역량을 함께 비교한다.

참고자료


한 줄 요약: MapReduce는 입력을 키-값으로 분할해 Map·Combine·Shuffle/Sort·Reduce 단계로 병렬 처리하고, 데이터 지역성·태스크 재실행·키 기반 집계를 통해 대규모 배치의 확장성과 장애 허용성을 확보하는 분산 처리 모델이다.