정말 오랜만에 쓰는 게시글이다.
그동안 게시글을 올리지 않았던 이유로는,
그동안 매일 강의를 들으며 필기한 내용들을 올렸었는데, 시간이 갈수록 필기를 위해 강의를 듣는다는 느낌이 들었다.
블로그에 게시할 목적으로 잘 정리해야한다는 강박에 사로잡혀 강의를 듣다보니, 강의 내용도 잘 들어오지 않았을 뿐더러, 너무 필기와 내용 정리에 시간이 너무 많이 쓰인다는 느낌이 들었다.
때문에, 이는 잘못 되었다고 생각하여 게시글 업로드를 중단하였었다.
그리고 데브코스를 수료한 지금이 되어서야 그동안 배워온 내용들을 리뷰할 겸 TIL을 다시 작성을 시작한다.
1. 빅데이터의 정의와 예
빅데이터의 정의 1
- “서버 한대로 처리할 수 없는 규모의 데이터”
- 예를 들어 pandas로 처리해야할 데이터가 너무 커서 처리가 불가능하다면 어떻게 할 것인가?
빅데이터의 정의2
- “기존의 소프트웨어로는 처리할 수 없는 규모의 데이터”
- 대표적인 기존의 소프트웨어는 오라클이나, MySQL과 같은 관계형 데이터 베이스
- 분산환경을 염두에 두지 않음
- Scale Up 접근 방식
빅데이터의 정의3
- 4V(Volume, Velocity, Variety, Varecity)
- Volume: 데이터의 크기가 대용량
- Velocity: 데이터 처리 속도가 얼마나 중요하느냐
- Variety: 구조화/비구조화 데이터 혹은 둘다냐
- Veracity: 데이터의 품질이 좋은지?
빅데이터의 예: 디바이스 데이터
- 모바일 디바이스
- 스마트 TV
- 각종 센서 데이터(IoT센서)
- 네트워킹 디바이스 등
빅데이터의 예: 웹
- 수십 조개 이상의 웹 페이지가 존재 → 온갖 종류의 지식의 바다
- 웹 검색 엔진 개발은 진정한 대용량 데이터 처리
- 웹 페이지를 크롤하여 중요한 페이지를 찾아내고 (페이지 랭크)인덱싱하고 서빙
- 구글이 빅데이터 기술의 발전에 지대한 공헌
- 사용자 검색어와 클릭 정보 자체도 대용량
- 이를 마이닝하여 개인화 혹은 별도 서비스 개발이 가능
- 검색어를 바탕으로한 트렌드 파악, 통계 기반 번역
- 요즘은 웹 자체가 NLP 거대 모델 개발의 훈련 데이터로 사용되고 있음
2. 빅데이터 처리가 갖는 특징
빅데이터 처리의 특징
- 먼저 큰 데이터를 손실없이 보관할 방법이 필요: 스토리지
- 처리 시간이 오래 걸림: 병렬처리
- 이런 데이터들은 비구조화된 데이터일 가능성이 높음: SQL 만으로는 부족
- 예를 들면 웹 로그 파일, 오디오 파일, 비디오 파일
빅데이터 처리 문제의 해결방안
- 큰 데이터를 손실없이 보관할 방법이 필요
- 큰 데이터 저장이 가능한 분산 파일 시스템이 필요
- 시간이 오래 걸림
- 병렬 처리가 가능한 분산 컴퓨팅 시스템이 필요
- 이런 데이터들은 비구조화된 데이터일 가능성이 높음
→ 결국 다수의 컴퓨터로 구성된 프레임웍이 필요
대용량 분산 시스템이란
- 분산 환경 기반 (1대 혹은 그 이상의 서버로 구성)
- 분산 파일 시스템과 분산 컴퓨팅 시스템이 필요
- Fault Tolerance
- 서버 중에 몇개가 고장나는 경우가 있음
- 소수의 서버가 고장나도 동작해야함
- 큰 파일이 손실 없이 저장되어 있어야함
- 큰 프로세스가 이상없이 수행되어야함
- 확장이 용이해야함
3. 하둡의 등장과 소개
하둡의 등장
- Doug Cutting이 구글랩 발표 논문들에 기반해 만든 오픈소스 프로젝트
- 처음 시작은 Nutch라는 오픈 소스 검색 엔진의 하부 프로젝트
- 2006년에 아파치 톱레벨 별개의 프로젝트로 떨어져나옴
하둡이란?
- 다수의 노드로 구성된 클러스터 시스템
- 마치 하나의 거대한 컴퓨터처럼 동작
- 사실은 다수의 컴퓨터들이 복잡한 소프트웨어로 통제됨
하둡의 발전
- 1.0은 HDFS 위에 MapReduce라는 분산컴퓨팅 시스템이 도는 구조
- MapReduce는 두가지 오퍼레이션만 지원함
- Map
- Reduce
- 때문에 프로그래밍이 너무 어려워짐
- 이를 해결하기 위해 MapReduce 위에서 다양한 컴퓨팅 언어들이 만들어짐
- 2.0에서 아키텍쳐가 크게 변경됨
- 하둡은 YARN이란 이름의 분산처리 시스템 위에서 동작하는 애플리케이션이 됨
- MapReduce가 YARN 위에서 구현된 형태임
- Spark은 YARN 위에서 애플리케이션 레이어로 실행됨
HDFS 분산 파일 시스템
- 데이터를 블록 단위로 나눠 저장
- 블록 복제 방식 (Replication)
- 각 블록은 3 군데에 중복 저장됨
- 하나의 서버에만 저장하면 그 서버가 고장시 모든 블록이 소실되므로 다른 서버로 중복 저장
- Fault tolrerance를 보장할 수 있는 방식으로 이 블록들은 저장됨
- 데이터 블록은 데이터 노드(Slave)에 저장이 됨
- 이 데이터 노드들을 관리하는 노드를 네임 노드(Master)라고 부름
- 블록은 각기 다른 데이터 노드들로 중복 저장됨(3군데)
- 하둡 2.0 네임노드 이중화 지원
- 데이터 노드들에 대한 중요한 정보들을 네임노드가 저장함
- 만일 네임 노드가 문제가 생겼다면, 데이터 노드가 멀쩡해도 의미가 없음
- Active & Standby
- Active 네임노드에 문제가 생기면 Standby 네임노드가 그 역할을 대신 수행함
- 둘 사이에 share edit log가 존재
- Secondary 네임노드는 여전히 존재
MapReduce: 분산 컴퓨팅 시스템
- 하둡 1.0에서 처음 소개됨
- 하나의 잡 트래커(Master)와 다수의 태스크 트래커(Slave)로 구성됨
- 잡 트래커가 일을 나눠서 다수의 태스크 트래커에게 분배
- 실제 MapReduce 코드는 태스크 트래커들에 의해 실행
- Slave에 해당하는 노드에 일반적으로 데이터 노드와 태스크 트래커 둘 모두가 설치되어있음
- 즉 Slave 노드 하나가 데이터 파일 시스템 하나와 데이터 처리 시스템 하나를 가지고 있음
- Master는 네임노드와 잡 트래커를 분리하여 구성하는 것이 일반적
- 중요한 정보들을 담고 있으므로 따로 분리를 하는 것이 일반적임
- MapReduce만 지원
4. YARN의 동작 방식
분산 컴퓨팅 시스템: 하둡 2.0 (YARN 1.0)
- 범용적인 분산 컴퓨팅 시스템 위에 개발자가 원하는 형태의 분산 처리 시스템을 만들 수 있는 구조로 변경됨
- 세부 리소스 관리가 가능한 범용 컴퓨팅 프레임웍 (YARN)
- 리소스 매니저(Master)
- Job Scheduler, Application Manager
- 노드 매니저(Slave)
- 리소스 매니저의 요구에 따라 자신의 자원을 일부 넘겨줌
- 자원: 컨테이너(Java의 JVM과 같다고 보면됨)
- 컨테이너: 두 종류의 프로세스를 지원
- Spark이 이 위에서 구현됨
YARN의 동작

-
클라이언트가 실행 코드와 환경 정보를 Resource Manager에게 제출
- Resource Manager가 지금 실행하려는 Application의 Application Master를 생성함
(YARN Application 마다 하나의 Application Master가 생김)
- 실행에 필요한 파일들은 Application ID에 해당하는 HDFS 폴더에 미리 복사됨
-
Resource Manager가 Node Manager를 통해 Application Master를 실행
- Application Master는 프로그램마다 하나씩 할당되는 프로그램 마스터에 해당
-
Application Master가 Resource Manager로 코드에 실행에 필요한 리소스를 받아옴
- 여기서 리소스는 위에서 언급한 컨테이너가 됨
- Resource Manager는 데이터 지역성을 고려하여 리소스를 할당
-
Application Master이 Node Manager를 통해 컨테이너들을 받아 코드 실행(태스크)
- Node Manger의 컨테이너 안에 클라이언트가 제출했던 코드들을 실행하는 태스크를 만듬
- 이 때 실행에 필요항 파일들이 HDFS에서 컨테이너가 있는 서버로 먼저 복사
-
태스크들은 자신의 상황을 주기적으로 Application Master에게 업데이트(Heartbeat)
- 태스크가 실패하거나 보고가 오랜 시간 없으면 태스크를 다른 컨테이너로 재실행
YARN Application은 기본적으로 HDFS 위에 있다고 가정함
- 여기서 YATN Application은 MapReduce나 Spark 등이 될 수 있음
하둡 1.0 vs 하둡 2.0
- 하둡 2.0에서 소개된 클러스터 자원 관리자를 YARN이라고 부름
- 1.0에서는 HDFS위에 MapReduce만이 바로 올라가는 구조였으나, 2.0에서는 그 사이에 YARN이 들어가게되며, MapReduce 외에도 다른 프로세스들을 지원(Spark 등)
하둡 3.0의 특징
- YARN 2.0을 사용
- YARN 프로그램들의 논리적인 그룹(플로우라고 부름)으로 나눠서 자원관리가 가능
- 이를 통해 데이터 수집 프로세스와 데이터 서빙 프로세스를 나눠서 관리 가능
- 타임라인 서버에서 HBase를 기본 스토리지로 사용(하둡 2.1부터 사용)ㅜ
- 파일 시스템
- 네임 노드의 경우 다수의 스탠바이 네임노드를 지원
- HDFS, S3, Azure Storage 이외에도 Azure Data Lake Storage 등을 지원
5. 맵리듀스 프로그래밍 소개
맵리듀스 프로그래밍의 특징
- 데이터 셋은 Key, Value의 집합이며 변경 불가
- Key는 하나의 값, 여러 필드를 Key로 쓰려면 concat해야함
- Value는 하나의 값 혹은 리스트 혹은 값이 없을 수도 있음
- 데이터 조작은 map과 reduce 두 개의 오퍼레이션으로만 가능
- Map: 입력으로 들어온 Key Value 쌍을 다른 쌍이나 쌍 집합 리스트로 만들어줌, 출력이 없을 수도 있음
- Reduce: Map의 출력 중에 같은 키를 갖는 출력들을 모아서 처리하여 새로운 쌍을 만들어줌
- 이 두 오퍼레이션은 항상 하나의 쌍으로 연속으로 실행됨
- 이 두 오퍼레이션의 코드를 개발자가 채워야함
- 보통 한번의 맵리듀스 연산만으로는 원하는 결과를 얻지 못함, 여러번 하는 경우가 많음
- 맵리듀스 시스템이 Map의 결과를 Reduce단으로 모아줌
- 이 단계를 보통 셔플링이라 부르며 네트웍단을 통한 데이터 이동이 생김
맵리듀스 프로그래밍의 핵심: 맵과 리듀스
- Map: (k, v) → [(k’, v’)*]
- 입력은 시스템에 의해 주어지며 입력으로 지정된 HDFS 파일에서 넘어옴
- 키, 밸류 페어를 새로운 키, 밸류 페어 리스트로 변환(Transformation)
- 출력: 입력과 동일한 키, 밸류 페어를 그대로 출력해도 되고 출력이 없어도 됨
- Reduce: (k’, [v1’, v2’ v3’, v4’, ….]) → (k’’, v’’)
- 입력은 시스템에 의해 주어짐
- 맵의 출력 중 같은 키를 갖는 키/밸류 페어를 시스템니 묶어서 입력으로 넣어줌
- 키와 밸류 리스트를 새로운 키, 밸류 페어로 변횐
- SQL의 GROUP BY와 흡사
- 출력이 HDFS에 저장됨
MapReduce: Shuffling and Sorting
- Shuffling
- Mapper의 출력을 Reducer로 보내주는 프로세스를 말함
- 전송되는 데이터의 크기가 크면 네트웍 병목을 초래하고 시간이 오래 걸림
- Sorting
- 모든 Mapper의 출력을 Reducer가 받으면 이를 키별로 소팅
- 보통은 한번의 MapReduce 연산으로는 원하는 결과를 얻기가 힘듬,
여러번의 연산을 통해 원하는 결과를 출력
MapReduce: Data Skew
각 태스크가 처리하는 데이터 크기에 불균형이 존재한다면?
- 병렬처리의 큰 의미가 없음. 가장 느린 태스크가 전체 처리 속도를 결정
- 특히 Reducer로 오는 ㄴ나눠지는 데이터의 크기는 큰 차이가 있을 수 있음
- Group By 나 Join 등이 이에 해당함
- 처리 방식에 따라 Reducer의 수에 따라 메모리 에러 등이 날 수 있음
- 데이터 엔지니어가 고생하는 이유 중의 하나
MapReduce 프로그래밍의 문제점
- 낮은 생산성
- 프로그래밍 모델이 가진 융통성 부족 (2가지 오퍼레이션만 지원)
- 튜닝/최적화가 쉽지 않음
- 배치작업 중심
- 기본적으로 Low Latency가 아니라 Throughput에 초점이 맞춰짐
MapReduce 대안들의 등장
- 더 범용적인 대용량 데이터 처리 프레임웍들의 등장
- SQL의 컴백
- Hive
- MapReduce 위에서 구현됨. Throughput에 초점. 대용량 ETL에 적합
- Presto
- Low Latency에 초점. 메모리를 주로 사용. Adhoc 쿼리에 적합
- AWS Athena가 Presto 기반
- 요즘에는 2개가 서로 비슷해짐. 즉, 구분이 모호해짐
6. 하둡 설치
우분투 환경에서 하둡을 설치, 자세한 설치 방법은 여기 참조
하둡 환경 관련 파일들
- hadoop-env.sh: 하둡의 마스터 환경 설정 파일
- core-site.xml: 네임 노드와 관계된 정보가 들어가는 파일
- 네임 노드 위치 지정, 네임 노드가 사용하는 tmp dir에 대한 지정 등
- hdfs-site.xml: hdfs와 관계된 정보들, 정확히는 데이터 블록과 관계된 정보들
- 네임 노드와 데이터 노드가 저장하는 로컬 디스크 폴더가 어떻게 되는지
- 하나의 데이터 블록을 몇개의 서버에 중복 저장할 것인지(replication factor)
- mapred-site.xml: MapReduce와 관련된 정보를 지정
- mapreduce를 YARN 위에서 실행시킨다고 지정 등
- yarn-site.xml: 노드 매니저와 리소스 매니저 관계된 정보를 지정
하둡 웹 UI - HDFS
- 네임노드는 포트 번호 9870으로 접속
- 데이터노드는 포트번호 9864로 접속
7. 맵리듀스 프로그래밍 실습
맵리듀스 프로그래밍 - 단어 수 세기
- 예제로 설치되어있는 WordCount 프로그램을 실행하기
- bin/hadoop jar hadoop-*-examples.jar wordcount input output
- input: 입력 데이터가 있는 디렉토리
- output: 출력이 파일 형태로 저장될 디렉토리
- bin/hadoop 과 bin/yarn은 같은 명령어임
- HDFS 입력/출력 살펴보기
- bin/hdfs dfs -ls input
- bin/hdfs dfs -ls output
- output/_SUCCESS: 연산이 성공적으로 끝났음을 알려주는 플래그
- output/part-r-00000: 실제 결과가 저장되어 있는 파일
- 리눅스 명령어 사용 전 dfs라는 명령어를 써줘야함
맵리듀스 프로그래밍 문제점
- 생산성이 떨어짐. 데이터 모델과 오퍼레이션에 제약이 많음
- 모든 입출력이 디스크를 통해 이뤄짐
- 큰 데이터 배치 프로세싱에 적합
- 규모가 작은 빠른 데이터 처리에는 적합하지 않음
- 셔플링 이후에 Data Skew가 발생하기 쉬움
- Reduce 태스크 수를 개발자가 지정해주어야함
- 이는 Spark에서도 발생하는 문제
8. Spark
Spark의 등장
- 아파치 오픈소스 프로젝트로 2013년 시작
- 하둡의 뒤를 잇는 2세대 빅데이터 기술
- YARN등을 분산환경으로 사용
- Scala로 작성됨
- 빅데이터 처리 관련 다양한 기능을 제공
Spark 3.0의 구성

Spark vs MapReduce
- Spark는 기본적으로 메모리 기반
- 디스크 기반인 MapReduce보다 빠름
- 메모리가 부족해지면 디스크 사용
- MapReduce는 하둡(YARN)위에서만 동작
- Spark는 하둡이외에도 다른 분산 컴퓨팅 환경 지원 (K8s, Mesos)
- MapReduce는 키와 밸류 기반 데이터 구조만 지원
- Spark는 판다스 데이터프레임과 개념적으로 동일한 데이터 구조 지원
- Spark은 다양한 방식의 컴퓨팅을 지원
- 배치 데이터 처리, 스트림 데이터 처리, SQL, 머신러닝, 그래프 분석
- MapReduce는 배치 처리만 가능
Spark 프로그래밍 API
- RDD (Resiliemt Distributed Dataset)
- 로우레벨 프로그래밍 API로 세밀한 제어가 가능
- 하지만 코딩 복잡도 증가
- DataFrame & Dataset (판다스의 데이터프레임과 흡사)
- 실제 프로그래밍에서 RDD보다 더 많이 쓰이며, 파이썬은 데이터프레임, 스칼라 혹은 자바로 프로그래밍한다면 Dataset을 주로 쓴다고 보면됨
- 하이레벨 프로그래밍 API로 점점 많이 사용되는 추세
- 구조화 데이터 조작이라면 보통 Spark SQL을 사용
- DataFrame/Dataset이 꼭 필요한 경우는?
- ML 피쳐 엔지니어링을 하거나 Spark ML을 쓰는 경우
- SQL 만으로 할 수 없는 일의 경우
Spark SQL
- Spark SQL은 구조화된 데이터 처리를 SQL로 처리
- 데이터 프레임을 SQL로 처리 가능
- 데이터 프레임은 테이블처럼 SQL로 처리 가능
- 판다스도 동일 기능 제공
- 가독성이 더 좋으므로 구조화된 데이터 처리에 많이 사용함
- Hive 쿼리보다 최대 100배까지 빠른 성능을 보장
- 그러나, Hive도 지금은 메모리도 쓰는 것으로 발전
Spark ML
- 머신러닝 관련 다양한 알고리즘, 유틸리티로 구성된 라이브러리
- Classification, Regression, Clustering 등 다양한 알고리즘을 지원
- RDD 기반과 데이터프레임 기반의 두번이 존재
- spark.mllib: RDD 기반
- spark.ml: 데이터프레임 기반
- 요즘은 spark.ml을 사용
Spark ML의 장점
- 데이터프레임과 SparkSQL등을 이용해 전처리
- Spark ML을 이용해 모델 빌딩
- ML Pipeline을 통해 모델 빌딩 자동화
- MLflow로 모델 관리하고 서빙(MLOps)
- 대용량 데이터도 처리 가능
Spark 데이터 시스템 사용 예들
- 기본적으로 대용량 데이터 배치 처리, 스트림 처리, 모델 빌딩
- 대용량 비구조화된 데이터 처리하기(ETL 혹은 ELT)
- ML 모델에 사용되는 대용량 피쳐 처리 (배치/스트림)
- Spark ML을 이용한 대용량 훈련 데이터 모델 학습
Spark 프로그램의 구조

- YARN 위에서 돈다고 가정
- Driver
- 실행되는 코드의 마스터 역할 수행 (YARN의 Application Manager)
- 사용자 코드를 실행하며 실행 모드(client, cluster)에 따라 실행되는 곳이 달라짐
- client 모드는 주로 학습, 개발 중 디버그 에 이용, 클러스터 밖에서 실행
- cluseter 모드는 개발이 끝난 코드를 클러스터 안에서 실행
- 코드를 실행하는데 필요한 리소스를 지정함
- Executor 수, Executor마다 쓰는 cpu갯수, 메모리 용량 등
- 보통 SparkContext를 만들어 Spark 클러스터와 통신 수행
- Cluster Manager (YARN의 경우 Resource Manger)
- Executor (YARN의 경우 Container)
- 사용자 코드를 실제 Spark 태스크로 변환해 Spark 클러스터에서 실행
- Executor
- 실제 태스크를 실행해주는 역할 수행: Transformations, Actions
- YARN에서는 Container가 됨
Spark 클러스터 매니저 옵션
- local[n]
- 개발 / 테스트 용: Spark Shell, IDE, 노트북
- n은 코어의 수(쓰레드의 수): executor의 수가 됨
- local[*]: 컴퓨터에 있는 모든 코어 사용
- YARN
- 두 개의 실행 모드가 존재: Client, Cluster
- Client: Driver가 Spark 클러스터 밖에서 동작
- YARN 기반 Spark 클러스터를 바탕으로 개발 / 테스트 등 을 할 떄 사용
- Cluster: Driver가 Spark 클러스터 안에서 동작
- 하나의 Executor 슬롯을 차지
- 실제 프로덕션 운영에 사용되는 모드
- K8s
- Mesos
- Standalone