[Hadoop] 맵리듀스 프로그래밍

맵리듀스 프로그래밍

데이터 셋의 포맷은 Key, Value의 pair(집합)로 고정되어 있고 변경이 불가 (immutable)합니다.

오퍼레이션 또한 2개로 정해져 있습니다. 오퍼레이션은 mapreduce로 데이터 조작이 가능합니다.

맵의 입력은 HDFS 데이터 블록, 리듀스의 출력은 HDFS로 저장

map은 입력으로 들어온 key-value pair를 다른 key-value pair로 만들어주거나 집합(list) 형태로 만들어 주는 것

reducemap에서 같은 키를 갖는 출력을 모아서 새로운 키-벨류 페어를 만들어 줍니다. (셔플링) ⇦ map과 reduce는 서로 다른 서버로 네트워크를 통한 데이터 교환이 필요

맵과 리듀스는 항상 하나의 쌍으로 연속으로 실행됩니다.

맵과 리듀스 안에 함수를 채워주는 역할(오퍼레이션 코드)을 개발자가 하고, 맵과 리듀스의 입력은 맵리듀스 시스템에서 만들어집니다. 

한번으로 원하는 결과를 얻기는 어렵고 맵-리듀스 오퍼레이션을 여러번 실행해서 얻어냅니다.

하둡 1.0인경우 Task manager에 의해 동작, 하둡 2.0에 경우 yarn의 노드매니저에 따라 컨테이너 할당되고 컨테이너 안에서 동작됩니다. 

 

Map

Map
(k, v) → [(k', v')*]
  • 키, 밸류 페어를 새로운 키, 벨류 페어 리스트로 변환(Transformation)
  • 출력은 입력과 동일한 키, 벨류 페어 그대로 출력될 수 도 있고, 출력이 없을 수도 있음
  • 입력은 시스템에 의해서 주어지며 입력으로 지정된 HDFS 파일에서 넘어옴

Reduce (k', [v1', v2', v3', v4', ...]) → (k', v")

Reduce
(k', [v1', v2', v3', v4', ...]) → (k', v")
  • 키와 밸류 리스트를 새로운 키, 벨류 페어로 변환
  • SQL의 GROUP BY와 흡사하고 출력은 시스템에서 HDFS에 저장된다.
  • Map과 마찬가지로 입력은 시스템에 의해 주어짐
    • 맵의 출력 중 같은 키를 갖는 키/밸류 페어를 시스템이 묶어서 입력으로 넣어줌

MapReduce Suffling and Sorting

Suffling 셔플링

  • Mapper의 출력을 Reducer로 보내주는 프로세스
  • 전송되는 데이터의 크기가 크면 네트워크 병목을 초래하고 시간이 오래 걸림 ⇨ Data Skew 데이터 크기 불균형 발생 😱
  • Shuffling 이후에 Data Skew가 발생하기 쉬운데, 시스템이 최적화 해주는 것이 아닌 Reduce 태스크 수를 개발자가 지정

Sorting

  • 모든 Mapper의 출력을 Reducer가 받으면 merge한 뒤 이를 키별로 정렬

문제점

  • 낮은 생산성
    • 2가지 오퍼레이션만 지원
    • 튜닝/ 최적화가 쉽지 않음(데이터 분포가 균등하지 않은 경우)
  • 배치 작업 중심 (Low Latency가 아닌 Throughput에 초점)
    • 데이터 모델과 오퍼레이션에 제약을 둬서 
    • 모든 입출력을 디스크를 통해 이뤄짐

이런 맵리듀스 프로그래밍에 대한 대안으로 더 범용적인 대용량 처리 프레임워크가 등장했습니다. ⇨ YARN, Spark

구조화된 데이터를 처리하기 위해 SQL이 컴백하면서 Hive, Presto가 등장했습니다. 

- Hive(하이브): MapReduce 위에서 구현, Throughput에 초점, 대용량 ETL에 적합
- Presto: Low latency에 초점, 메모리를 주로 사용하며 Adhoc 쿼리에 적합, AWS Athena가 Presto 기반

최근에는 두 개의 기능이 매우 유사해짐