MapReduce and Spark
Last updated
Last updated
데이터 용량이 매우 커서 메모리에 올라가지 못하는 경우 파일을 다운로드하면 컴퓨터가 먹통이 될 수 있음. 따라서 네트워크로 연결된 여러 대의 PC를 사용하여 데이터를 분산 처리해야 함.
데이터를 여러 파일 서버에 분산 저장함.
프로그램이 분산된 데이터를 로컬에서 접근하고 저장할 수 있게 함.
Name Node(master)와 Data Node(chunk)로 구성됨:
Name Node: 파일이 어디에 저장되었는지에 대한 메타데이터를 관리, 이 노드가 손상되면 파일 위치 정보를 잃기 때문에 안정적이고 내구성이 강해야 함
Data Node: 각 서버에서 데이터를 저장하며, 일반적으로 6~128MB 크기의 블록 단위로 데이터를 저장, 동일한 데이터를 2배 혹은 3배 복사해 여러 노드에 분포시키며 장애가 발생하더라도 복구 가능하도록 설계
클라이언트는 Master(Name Node)에게 Chunk Server(Data Node)의 위치를 요청하고, Master로부터 정보를 받은 후 직접 Chunk Server와 통신함
데이터를 순차적으로 읽고 처리하는 분산 프로그래밍 모델
Map: 데이터를 입력받아 단일 요소로 분할 (key-value 쌍 생성)
같은 Key에 대해 많은 Pair가 생성되면 공간 문제 발생 가능. 이를 줄이기 위해 Combiner를 사용
Combiner는 Reduce Function이 덧셈의 교환법칙 및 결합법칙을 만족해야만 사용할 수 있음
Group by Key: 데이터를 Key별로 그룹화하고, 정렬 및 셔플링(shuffle) 수행
Reduce: Aggregation, Summarization, Filtering, Transformation 등을 수행
Map Worker Failure: 작업 중이거나 완료되지 않은 작업을 초기화한 후, 남아 있는 다른 Worker가 작업을 재할당받아 처리함
Reduce Worker Failure: 진행 중인 작업만 초기화되고, 다른 Worker가 이를 재시작함
Master Failure: Master가 중단되면 전체 프로그램이 종료되고, 클라이언트에 오류를 알림
MapReduce는 반복(iterative) 처리로 매번 데이터를 디스크에 저장했다가 다시 읽어야 하므로 속도가 느리며 디스크 I/O와 네트워크 비용이 많이 발생해 성능 저하(Overhead)가 발생함 Spark는 데이터를 Disk 대신 RAM에 저장하고, 캐싱(Caching)을 통해 빠르게 데이터를 처리하기 위해 설계됨
Spark가 사용하는 읽기 전용 데이터의 기본 단위
특징:
RDD는 불변(Immutable)하며, 한 번 생성된 RDD는 변경되지 않음
변환(Transformation) 결과는 지연(Lazy) 평가되어, Action 명령이 실행될 때 수행됨
작동 방식:
Transformation: 기존 RDD를 변환해 새로운 RDD를 생성
변환은 지연 수행되어 Action이 실행될 때만 계산됨
Action: RDD 변환을 실행하고 결과를 반환
RDD 사용 방법:
Create:
변수로 생성: rdd = sc.parallelize([1, 2, 3])
파일에서 생성: rdd = sc.textFile('data.txt')
Transformation:
flatMap()
: 데이터를 1차원 배열로 변환 ->rdd2 = rdd.flatMap(lambda x: x.split(' '))
map()
: Key-Value 쌍 생성 ->rdd3 = rdd2.map(lambda x: (x, 1))
reduceByKey()
: Key별로 데이터 집계 ->rdd4 = rdd3.reduceByKey(lambda a, b: a + b)
Action:
rdd.collect()
: RDD 결과를 배열로 반환
rdd.take(x)
: 상위 x개의 데이터를 반환
rdd.count()
: RDD 요소 개수를 반환
rdd.first()
: 첫 번째 요소 반환
데이터 처리
Disk 기반
In-Memory 기반
구현
상대적으로 어려움
상대적으로 쉬움
성능
상대적으로 낮음
상대적으로 높음
메모리 사용
낮음
높음