3-1. 대규모 분산 처리의 프레임워크
구조화 데이터와 비구조화 데이터
- 스키마: 칼럼명, 데이터형, 테이블 간의 관계 등이 정의된 정보
- 구조화된 데이터 (Structured Data): 스키마가 명확하게 정의된 데이터 (SQL로 집계)
- 비구조화 데이터 (Unstructured Data): 텍스트, 이미지, 동영상 등의 미디어 데이터로 스키마가 없는 데이터 (SQL로 집계 불가)
- 데이터 레이크: 비구조화 데이터를 분산 스토리지 등에 저장하고, 분산 시스템에서 처리하는 것
- 데이터 가공 과정에서 스키마 정의 => 구조화된 데이터로 변환 => 분석에 사용
스키마리스 데이터
- 스키마리스 데이터(shemaless data): CSV, JSON, XML 등 데이터 서식은 정해져 있지만, 칼럼 수나 데이터형은 명확하지 않은 데이터
- 스키마를 정하는 것은 시간과 비용이 소요되기 때문에 JSON은 그대로 저장하고 데이터 분석에 필요한 필드만 추출하는 편이 가장 간단
데이터 구조화의 파이프라인
- 먼저 필요한 것은 스키마를 명확하게 한 테이블 형식의 '구조화 데이터'로 변환하는 것
- 구조화 데이터는 일반적으로 데이터 압축률을 높이기 위해 열 지향 스토리지로 저장
- 데이터 마트는 고려하지 않고, 데이터를 구조화하여 SQL로 집계 가능하게 만드는 것만 생각
열 지향 스토리지의 작성
- 분산 스토리지 상에 작성해 효율적으로 데이터 집계
- MPP 데이터베이스: 제품에 따라 스토리지 형식이 고정되어 있어 사용자가 그 상세를 몰라도 됨
- Hadoop: 사용자가 직접 열 지향 스토리지 형식을 선택, 쿼리 엔진도 선택
- Hadoop에서 선택할 수 있는 열 지향 스토리지 종류:
- Apache ORC: 구조화 데이터를 위한 열 지향 스토리지
- Apache Parquet: 스키마리스에 가까운 구조로 되어있어 JSON 같은 데이터도 그대로 저장 가능
- 비구조화 데이터를 열 지향 스토리지로 변환하는 과정에는 데이터 가공 및 압축을 위해 많은 컴퓨터 리소스가 소비됨
Hadoop - 분산 데이터 처리의 공통 플랫폼
- Hadoop: 분산 시스템을 구성하는 다수의 소프트웨어로 이루어진 집합체 (대규모 분산시스템을 구축하기 위한 공통 플랫폼 역할 담당)
분산 시스템의 구성 요소
Hadoop의 기본 구성 요소
1. HDFS (Hadoop Distributed File System): 분산 파일 시스템
2 YARN (Yet Another Resource Negotiator): 리소스 관리자
3. MapReduce: 분산 데이터 처리
- 그 외의 프로젝트는 Hadoop 본체와 독립적으로 개발되어 Hadoop을 이용한 분산 애플리케이션으로 동작
- Hadoop을 일부만 사용하거나 전혀 사용하지 않게 분산 시스템을 구성할 수도 있다
분산 파일 시스템과 리소스 관리자: HDFS, YARN
- HDFS: Hadoop에서 처리되는 데이터 대부분이 저장됨
- 다수의 컴퓨터에 파일을 복사하여 중복성을 높임
- YARN: CPU나 메모리 등 계산 리소스 관리
- 컨테이너 (container): 애플리케이션이 사용하는 CPU 코어와 메모리를 관리하는 단위
- Hadoop이 분산 애플리케이션을 실행하면 YARN이 클러스터 전체의 부하를 보고 비어있는 호스트부터 컨테이너를 할당
- (Docker 컨테이너와 무관)
- 한정된 리소스를 여러 애플리케이션에 어떻게 할당할 지 관리하므로써 모든 애플리케이션이 차질없이 실행되도록 제어
분산 데이터 처리 및 쿼리 엔진: MapReduce, Hive
- MapReduce: YARN 상에서 동작하는 분산 애플리케이션 중 하나
- Java 프로그램을 실행할 수 있음 - 비구조화 데이터를 가공하는 데 적합
- Apache Hive: SQL 등 쿼리 언어에 의한 데이터 집계시 사용하는 쿼리 엔진
- 초기 Hive: SQL 쿼리를 자동으로 MapReduce 프로그램으로 변환하는 소프트웨어로 개발
Hive on Tez
- Hive를 가속화하기 위해 개발
- 기존 MapReduce는 오버헤드가 매우 컸음 => 애드 혹 쿼리 실행에 부적합
- Tez에서는 스테이지 종료를 기다리지 않고 처리가 끝난 데이터를 차례대로 후속 처리에 전달하므로써 쿼리 전체 실행 시간 단축
대화형 쿼리 엔진
- (Hive 고속화 말고) 처음부터 대화형 쿼리 실행만 전문으로 하는 쿼리 엔진 개발
- Presto, Apache Impala
- 대화형 쿼리 엔진: 순간 최대 속도를 높이기 위해 모든 오버헤드 제거
- 사용할 수 있는 리소스를 최대한 활용하여 쿼리 실행
- MPP 데이터베이스와 비교해도 손색없는 응답 시간 실현
목적에 따른 쿼리 엔진 구분
- Hive: 대량의 비구조화 데이터를 가공하는 무거운 배치 처리에 활용 (높은 처리량 (Throughput)이 특징)
- Presto, Impala: 구조화 데이터를 대화식으로 집계 (적은 지연이 특징)
SQL-on-Haddop: Hadoop 에서 개발된 쿼리 엔진들
- 아직 MPP 데이터베이스 만큼 기능적으로 따라잡지 못한 부분들이 있지만, 분산 스토리지에 저장된 데이터를 신속하게 집계할 수 있는 점에서 우수
Spark - 인 메모리 형의 고속 데이터 처리
Hadoop과는 다른 독립된 프로젝트
- Spark의 대표적 특징: 대량의 메모리를 활용하여 고속화
- MapReduce는 처리 대부분을 디스크 읽고 쓰기에 사용
- 컴퓨터 메모리 성능이 높아짐에 따라, 가능한 한 많은 데이터를 메모리 상에 올려놓고 디스크에는 아무것도 기록하지 않는 것이 현실화됨
MapReduce 대체하기
Spark은 Hadoop을 대체하는 것이 아니라 MapReduce를 대체
- HDFS, YARN 등은 Spark에서도 그대로 사용
- 분산 스토리지로 Amazon S3를 이용하거나 Cassandra 등의 분산 데이터베이스를 사용하는 것도 가능
- Spark 상에서 실행되는 데이터 처리는 스크립트 언어를 사용할 수 있음: Java, Scala, Python, R
- Spark SQL: Spark 상에서 SQL 쿼리 실행
- Spark Streaming: 스트림 처리
3-2. 쿼리 엔진
SQL-on-Hadoop에 의한 데이터 처리의 구체적인 예:
- Hive에 의한 구조화 데이터 생성
- Presto에 의한 대화식 쿼리
데이터 마트 구축의 파이프라인
1. 분산 스토리지에 저장된 데이터를 구조화하고 열 지향 스토리지 형식으로 저장
- 다수의 텍스트 파일을 읽어들여 가공하는 부하가 큰 처리: Hive 사용
2. 완성한 구조화 데이터를 결합, 집계하고 비정규화 테이블로 데이터 마트에 작성
- 열 지향 스토리지를 이용한 쿼리 실행: Presto 사용
- Hive Metastore: Hive에서 만든 각 테이블의 정보
- Hive 뿐만 아니라 다른 SQL-on-Hadoop의 쿼리 엔진에서도 공통의 테이블 정보로 참고됨
Hive에 의한 구조화 데이터 작성
Hive 시작 후 CREATE EXTERNAL TABLE로 외부 테이블 정의
- 외부 테이블 (external table): Hive의 외부에 있는 특정 파일을 참고해 마치 거기에 있는 테이블이 존재하는 것처럼 읽어들일 수 있음
- 텍스트 파일 로드되고 구조화 데이터로 변환됨
- SQL-on-Hadoop의 쿼리 엔진들은 MPP 데이터베이스와 달리, 데이터를 내부로 가져오지 않아도 텍스트 파일을 그대로 집계할 수 있음
- CSV 파일 등을 그대로 집계하는 것은 비효율 (매번 텍스트를 읽어야 하기 때문에 느림)
=> 열 지향 스토리지로 변환
열 지향 스토리지로의 변환: 데이터 집계의 고속화(배치형 쿼리 엔진용)
- 테이블을 열지향 스토리지 형식 (ex. ORC 형식)으로 변환
- 변환에는 다소 시간이 걸리지만, 변환 후 집계 시간 크게 단축
Hive로 비정규화 테이블을 작성하기
- 데이터 구조화가 완료되면 데이터 마트 구축
- Presto 같은 대화형 쿼리 엔진을 사용할 것인지, Hive 같은 배치형 쿼리 엔진을 사용할 것인지 결정
- 시간이 걸리는 배치 처리는 원칙적으로 Hive 사용
- 수억 레코드는 데이터 마트로 내보내는 것만으로도 상당한 시간 소요
- 쿼리 엔진 자체의 성능으 최종적인 실행 시간에 영향 거의 없음
- 리소스 효율 측면에서, 배치형 시스템 사용하는게 더 좋음
- 비정규화 테이블 생성시 효율적일 쿼리를 작성하는 것이 중요
서브 쿼리 안에서 레코드 수 줄이기
- 초기 단계에서 팩트 테이블 작게 하기
데이터 편향 피하기
- 중복 없는 값 세기 (count distinct ...)는 데이터를 한 곳에 모아야 해서 분산 처리하기 어려움
대화형 쿼리 엔진 Presto의 구조
작은 쿼리를 여러 번 실행하는 대화형 데이터 처리에는, 실행의 지연을 감소시키는 것이 필요
- 참고 기술: Dremel
플러그인 가능한 스토리지
Presto의 주요 특징: 하나의 쿼리 안에서 여러 데이터 소스에 연결 가능
- Presto는 전용 스토리지를 갖고 있지 않아, Hive와 마찬가지로 다양한 데이터 소스에서 직접 데이터를 읽어 드림
- MPP 데이터베이스에서는 소티리지와 컴퓨팅 노드가 밀접하게 결합되어 있어 처음에 데이터를 로드하지 않으면 집계를 시작할 수 없음
- Presto가 성능을 최대한 발휘하려면 원래 스토리지가 열 지향 데이터 구조로 되어 있어야 함
- ORC 형식의 로드에 최적화됨
CPU 처리의 최적화
Presto의 SQL 실행
1. 쿼리를 분석하여 최적의 실행 계획 생성
2. Java의 바이트 코드로 변환
3. 바이트 코드는 Presto의 worker 노드로 배포 -> 런타임 시스템에 의해 기계 코드로 컴파일
4. 멀티 스레드화되어 단일 머신에서 수백 태스크로 병렬 실행
- CPU 이용률이 높을 수밖에 없음
- (메모리와 CPU 리소스만 충분하다면) 데이터의 읽기 속도가 쿼리의 실행 시간을 결정
- Presto 쿼리는 일단 실행 시작되면 중간에 끼어들 수 없음
=> 너무 큰 쿼리 실행시, 그 쿼리에 대부분의 리소스가 사용되어 다른 쿼리를 실행할 수 없음
인 메모리 처리에 의한 고속화
- (Hive와 달리) Presto는 디스크에 쓰기를 하지 않음
- 모든 데이터 처리를 메모리상에서 실시하고 메모리가 부족하면 여유가 생길 때까지 기다리거나 오류로 실패
- 효과적인 데이터 처리 방식: 메모리상에서 할 수 있는 것은 메모리상에서 실행하고, 디스크가 있어야 하는 일부 데이터 처리는 Hive 등에 맡기기
- GROUP BY는 단순 반복 처리기 때문에 메모리 소비량이 거의 고정
- 대규모 배치 처리, 거대한 테이블끼리 결합 등에는 디스크 활용 필요
분산 결합과 브로드캐스트 결합
- 테이블의 결합은 종종 대량의 메모리 소비
- 분산 결합 (Distribute Join): 같은 키를 갖는 데이터는 동일한 노드에 모임
- Presto 의 기본 JOIN 방식
- 노드 간 데이터 전송을 위한 네트워크 통신 발생 => 쿼리 지연 초래
- 브로드캐스트 결합 (Broadcast Join): 결합하는 테이블의 모든 데이터가 각 노드에 복사
- 디멘전 테이블은 메모리에 충분히 들어갈 정도로 작은 것이 대부분이므로, 테이블 결합이 훨씬 빨라짐
열 지향 스토리지 집계
- Presto에서는 열 지향 스토리 집계가 매우 빠름
데이터 분석의 프레임워크 선택
MPP 데이터베이스, Hive, Presto, Spark의 장단점 비교
MPP 데이터 베이스
장점
- 완성한 비정규화 테이블의 고속 집계에 적합
- 구조화 데이터를 SQL로 집계하는 것뿐이라면 기존의 데이터 웨어하우스 제품과 클라우드 서비스 이용하는 것이 가장 좋음
- Hadoop이 데이터 웨어하우스를 능가할 수 없다
- 이 장에서 다룬 복잡한 기술 전혀 필요하지 않음
- MPP 데이터베이스는 스토리지 및 계산 노드가 일체화되어 있기 때문에, ETL 프로세스 등으로 데이터 가져오는 절차는 필요
- BI 도구와의 조합도 용이
단점
- 확장성 및 유연성 떨어짐 (아래 경우들 대응 못함)
- 대량의 텍스트 처리가 필요한 경우
- 데이터 처리를 프로그래밍하고 싶은 경우
- NoSQL 데이터베이스에 저장된 데이터를 집계하고 싶은 경우
Hive
장점
- 데이터양에 좌우되지 않음 (높은 안정성)
- Hadoop 상의 분산 애플리케이션이 원래부터 높은 확장성과 내결함성을 목표로 설계됨
- 열 지향 스토리지를 만드는 등의 무거운 처리에 적합
- Tez의 등장으로 대화형 쿼리에도 사용됨
Presto
장점
- 속도 중시 & 대화식으로 특화된 쿼리 엔진 (Hive와 정반대)
- 쿼리가 실패해도 빠르게 재실행 가능
- 많은 데이터 스토어와 조합 가능 - 모든 데이터를 SQL로 집계하게 해줌
단점
- 메모리가 부족하면 쿼리 실행할 수 없음
- 텍스트 처리가 중심이 되는 ETL 프로세스 및 데이터 구조화에는 적합하지 않음
- 열 지향 스토리지를 만드는 데 사용할 수는 있지만 적합하지는 않음
- 단시간에 대량의 리소스 소비
- 너무 무리하게 사용하면 다른 쿼리 실행 불가
Spark
장점
- 분산 시스템을 사용한 프로그래밍 환경 제공
- SQL 뿐만 아니라 스크립트 실행
- 일련의 데이터 파이프라인을 하나의 프레임워크로 작성 가능
- ETL부터 데이터 분석, 머신 러닝 등 모든 데이터 처리 가능
- 인 메모리 데이터 처리로 대화형 쿼리도 가능
단점
- 메모리 관리 등의 러닝 커브 소요
3-3. 데이터 마트의 구축
각종 테이블의 경할과 비정규화 테이블을 만들기까지의 흐름 설명
팩트 테이블 - 시계열 데이터 축적하기
팩트 테이블 작성의 두 가지 방법
1. 추가 (append): 새로 도착한 데이터만 증분으로 추가
2. 치환 (replace): 과거 데이터를 포함하여 테이블 전체 치환
테이블 파티셔닝
추가 (append)의 잠재적 문제
- 결손: 추가 실패를 알아채지 못한 경우
- 중복: 오류로 인해 추가가 여러 번 실행된 경우
- 관리의 복잡성: 팩트 테이블을 다시 만들어야 하는 경우
테이블 파티셔닝: 테이블을 물리적인 여러 파티션으로 나눔으로써 파티션 단위로 정리하여 데이터를 쓰거나 삭제할 수 있도록 함
- 각 파티션은 매번 교체 (이미 존재한다면 덮어쓰도록)하도록 설계
- 중복 해결
데이터 마트의 치환
- 데이터 마트의 양은 한정되어 있기 대문에, 상당히 거대한 테이블을 만들지 않는 한 매번 치환하는 것이 좋음
- 팩트 테이블 전체 치환하는 것의 장점
1. 중복과 결손 해결
2. 스키마 변경 등도 쉬움
- 단점: 처리 시간
- 데이터 양이 너무 많다면 오래 걸림
- 데이터 양이 너무 많다면 마찬가지로 테이블 파티셔닝을 실시하거나 모니터링을 세팅할 필요 있음
- (Small Start) 1시간 이내에 팩트 테이블을 만들 수 있다면, 매번 치환하는 것으로 충분
- 그것이 어려운 경우에만 추가를 이용한 워크플로 고려
집계 테이블 - 레코드 수 줄이기
집계 테이블 (Summary Table): 팩트 테이블을 어느 정도 모아서 집계하여 데이터 양을 줄임
- 일일 보고서를 만드는 데에 daily summary 테이블 자주 사용
- 카디널리티 (Cardinality): 각 칼럼이 취하는 값의 범위
- ex. '성별'의 카디널리티 = 2 (Male, Female), 'IP 주소'의 카디널리티 = 무한(매우 높음)
- 집계 테이블을 작게 하려면 모든 칼럼의 카디널리티를 줄여야 함
- 카디널리티를 무리하게 낮추면 원래 있던 정보가 손실 됨
- 레코드 수가 수억 건 정도면 집계 테이블을 만들지 않고 MPP 데이터베이스로 바로 써내는 것도 좋음
- 숫자 계산에 주의해야 함
- 평균값은 집계 테이블을 사용하면 제대로 계산할 수 없음 (평균의 평균 vs 전체 평균)
- count(distinct ...)도 집계 테이블로 취급하기 어려움 (daily summary table에서 MAU 계산은 불가능)
스냅샷 테이블 - 마스터 상태 기록하기
마스터 데이터처럼 업데이트될 가능성이 있는 테이블을 처리하는 두 가지 방법
1. 스냅샷 테이블 (Snapshot Table): 정기적으로 마스터 데이터를 통째로 저장
2. 이력 테이블 (History Table): 변경 내용만 저장
데이터 분석 입장에서는 스냅샷 테이블이 취급하기 쉬움
- 마스터 테이블의 레코드 수가 많다면 스냅샷 테이블은 거대해지지만 빅데이터 기술은 이걸 별로 개의치 않아도 됨
- 일종의 팩트 테이블로 간주
- 디멘전 테이블로 도 사용
- 이 때 스냅샷 날짜에 주의
- 스냅샷은 하루의 끝에 취득하는 것이 좋음
- ex. 1월 1일 스냅샷을 1월 1일 00:00:00로 하냐 vs 1월 1일 23:59:59로 하냐에 따라 트랜잭션 데이터와 결합 방식이 달라짐
- 후자 방식이 훨씬 좋다: 1월 1일 15:00:00 에 발생한 이벤트를 전자랑 JOIN하려면 데이터가 없음
- 스냅샷 테이블은 나중에 다시 만들 수 없으므로, 영구적인 저장소에 보관하여 삭제되지 않도록 주의
- 스냅샷시 처음부터 비정규화된 것이 편함
이력 테이블 - 마스터 변화 기록하기
- 변경이 있을 대마다 그 내용 기록
- 데이터 양을 줄이는 데 도움이 되지만, 어느 순간의 완전한 마스터 테이블을 나중에 복원하는 것이 어려움
- 디멘전 테이블로 사용하기 위해 별도의 처리를 통해 마스터 테이블로 복원해야 함
[마지막 단계] 디멘전을 추가하여 비정규화 테이블 완성시키기
- 팩트 테이블과 디멘전 테이블을 결합하여 비정규화 테이블 생성