실습 챕터

6-1. 스키마리스 데이터의 애드 혹 분석

스키마리스 데이터 수집하기

- API 활용

대화식 실행 환경의 준비

- Jupyter Notebook

- python pandas

Spark에 의한 분산 환경

- pyspark: 파이썬으로 대화식의 Spark 실행

- Spark는 마스터/슬레이브 형의 분산 시스템으로 클라이언트로부터 마스터에 명령을 보냄으로써 프로그램 실행

    - 클라이언트 = 드라이버 프로그램: 주피터와 조합 가능

    - 드라이버 프로그램은 로컬 노트북에서 실행 가능 => 실제 실행 환경은 보통 데이터 센터의 Spark 클러스터에 접속

- Spark의 데이터프레임은 pandas와 달리, 실제로 무언가의 처리를 요구할 때까지는 메모리상에서 DAG가 조림됨

    - RDD (Resilient Distributed Dataset): Spark의 로우 레벨 데이터 구조

데이터를 집계해서 데이터 마트 구축하기

- 데이터 마트를 만들 때의 선택지들

    - Spark에 ODBC/JDBC로 접속

    - MPP 데이터베이스에 비정규화 테이블 제작

    - 데이터를 작게 집약하여 CSV 파일에 출력

BI 도구로 데이터 시각화하기

- 탐색적 데이터 분석시에는 시행착오를 노트북에 축적하자

- 계속 모니터링해야 한다면 워크플로화 해서 자동화하자

- BI 도구: 데스크톱 형 vs 웹 형

    - 시각화는 이미지 처리, 필연적으로 데스크톱형의 도구가 우수

    - 네트워크에 의한 지연: 데이터 마트를 작게 만드는 것의 목적은 이런 문제를 제거하기 위한 것

    - 대시보드와 보고서 작성: 워크플로로 자동화 하려면 웹 형도구 필요

6-2. Hadoop에 의한 데이터 파이프라인

일일 배치 처리를 태스크화하기

1. 정기적으로 데이터 전송

2. 데이터 분석을 위해 Hive로 열 지향 스토리지 제작

3. Presto로 집계

[태스크 1] Embulk에 의한 데이터 추출

- 시간과 저장 공간을 멱등하게 처리

[태스크 2] Hive에 의한 데이터 구조화

- 열 지향 스토리지에 저장

- 파티셔닝을 통해 태스크 멱등성 확보

[태스크 3] Presto에 의한 데이터 집계

- 열 지향 스토리지에 저장된다면 장기간 집계도 고속화됨

- BI 도구에 읽어들임으로써 최종적인 데이터 파이프라인 완성

    - 파라미터를 교체해서 실행 자동화 가능

6-3. 워크플로 관리 도구에 의한 자동화

Airflow: 스크립트 형의 워크플로 관리

워크플로 정의

태스크 정의

워크플로를 터미널로부터 실행하기

스케줄러를 기동하여 DAG를 정기 실행하기

- 스케줄러: 데이터베이스의 상태를 정기적으로 점검하고 그 다음으로 실행 가능한 태스크를 찾음 -> 실행 가능한 태스크가 발견되면 워크 프로세스에 전달해 실행

- 오류로부터의 복구 염두한 설계

태스크가 소비하는 자원 제어하기

태스크의 분산 처리: 원격으로 워커 실행

- 데이터 처리의 실행은 Airflow 내에서 하는 것은 부적합

    - 데이터 처리는 분산 시스템에 맡기고 Airflow는 그 실행만 관리

Hadoop의 데이터 파이프라인을 실행하기

6-3. 클라우드 서비스에 의한 데이터 파이프라인

데이터 분석과 클라우드 서비스의 관계

- 클라우드 서비스의 장점

    - 자원 증감이 용이

    - 이용자는 설정 값만 신경 쓰면 됨

아마존 웹 서비스 (AWS)

- 기능마다 서비스가 나누어져 있어 이용자는 자신에게 필요한 것만 선택하고 연결함으로써 시스템 구축 가능

- 조합의 자유도가 높지만, 전체를 제대로 연결하려면 어느 정도 지식과 기술 요구

- 사용자가 직접 초기 설정하거나 워크플로 안에서 API를 서로 호출해야 함

    => 전체 구성을 직접 설계할 수 있음 (장점이자 단점)

- 빅데이터 관련 서비스 list

    - S3: 객체 스토리지

    - DynamoDB: NoSQL 데이터베이스

    - EMR: Hadoop&Spark

    - Athena: 쿼리 엔진 (Presto)

    - Elasticsearch: 검색엔진

    - Kinesis: 메시지 브로커

    - Kinesis Streams: 스트림 처리

    - Redshift: MPP 데이터베이스

    - QuickSight: BI 도구

구글 클라우드 플랫폼 (GCP)

- 애드 혹 데이터 분석과 처리 속도에 대한 요구가 큰 데이터 엔지니어 및 데이터 사이언티스트에게 유력한 선태기

- 빅데이터 관련 서비스 list

    - Cloud Storage: 객체 스토리지

    - Cloud Datastore: NoSQL 데이터베이스

    - Dataproc: Hadoop & Spark

    - Dataflow: 데이터 플로우 (배치, 스트리밍)

    - Colab: 노트북, 시각화

    - Pub/Sub: 메시지 브로커

    - BigQuery: 쿼리 엔진

    - Looker Studio: BI 도구

 

Amazon Redshift vs Google BigQuery

- Redshift

    - 전용 리소스 (dedicated resource): 스토리지와 계산 노드가 일체화 => 성능 안정적

- BigQuery

    - 공유 리소스 (shared resource): 수천 대의 하드 디스크에 데이터 분산 => 고속화 => 자신의 노드를 관리할 필요 없는 풀 매니지드형 서비스

트레주어 데이터

- 오픈소스의 스트리밍 형 전송 도구인 Fluentd와 벌크 형 전송 도구인 Embulk 개발사

- AWS, GCP와 달리 모든 서비스가 포함된 상태로 제공 (풀 매니지드형 서비스)

    - 외부 시스템과의 연계도 통합되어 있음

- 직접 컨트롤 할 수 있는 게 거의 없음 (장점이자 단점)

- 빅데이터 관련 서비스 list

    - Data Collection: 데이터 수집(스트리밍, 벌크)

    - Data Set Management: 분산 스토리지, 구조화 데이터

    - Data Processing: 쿼리 엔진 (Hive, Presto)

    - Data Delivery and Activation: ETL 프로세스

    - Treasure Workflow: 워크플로 관리

    - Treasure Reporting: BI 도구

    - DigDag: 선언형의 워크플로 관리

 

5-1. 워크플로 관리

[기초 지식] 워크플로 관리: 데이터의 흐름을 일원 관리하기

- 워크플로 관리(workflow management): 기업 내의 정형적인 업무 프로세스(신청, 승인, 보고 등)와 같이 정해진 업무를 원할하게 진행하기 위한 구조

    - 매일 매일의 태스크를 관리하는 구조가 정기적인 배치 처리 실행에도 유용하기 때문에 데이터 처리 현장에서도 자주 이용

- 일반적인 데이터 워크플로 관리:

    - 태스크는 정해진 스케줄에 따라 자동으로 실행

    - 무언가 비정상적 일이 발생한 경우에는 사람이 개입하여 문제 해결

워크플로 관리 도구

- 워크플로 관리 도구의 주요 역할: 

    - 정기적으로 태스크를 실행

    - 비정상적인 상태를 감지하여 그것에 대한 해결

- 대표적인 오픈소스 워크플로 관리 도구: Airflow, Digdag, Oozie

 

워크플로 관리 도구와 태스크

- 태스크(Task): 실행되는 개별 데이터 처리 단위

 

기본 기능과 빅데이터에서 요구되는 기능

- 워크플로 관리 도구가 필요한 이유: 태스크 실행에 실패할 수 있기 때문

- 아래 기능이 필요 (모든 태스크를 일원 관리하기 쉽게 해야 함)

    - 태스크를 정기적인 스케줄로 실행하고 결과 통지

    - 태스크 간의 의존 관계 정하고 정해준 순서대로 빠짐없이 실행

    - 태스크 실행 결과를 보관하고, 오류 발생 시에는 재실행할 수 있도록

 

선언 형과 스크립트 형

선언형(Declarative): XML, YAML 등의 서식으로 워크플로 기술

    - ex. Oozie

    - 미리 제공된 기능만 이용

    - 누가 작성해도 동일한 워크플로가 되기 때문에 유지 보수성이 높아짐

스크립트형 (Scripting): 스크립트 언어(ex. python)로 워크플로를 정의

    - ex. Airflow

    - 유연함: 태스크 정의를 프로그래밍할 수 있음

- 데이터 수집 과정에서는 스크립트 형의 도구를 사용하여 유연하게 워크플로를 조립하고, 데이터가 모아지면 정형적인 처리만 하게 되므로 이후에는 선언형 도구를 사용할 수 있다

오류로부터의 복구 방법 먼저 생각하기

빅데이터를 취급하고 있으면 다양한 오류가 발생

- 미리 예기치 못한 오류가 발생할 가능성을 고려하여 오류 발생 시의 대처 방법을 결정해두는 것이 중요

 

복구와 플로우의 재실행

- 수작업에 의한 복구를 전제한 태스크 설계

    - 오류로부터 자동 회복할 수 있다는 점은 고려하지 않는 것이 좋다 (오류의 종류는 수많기 때문에 전부 대응하는 것은 불가능)

- 플로우: 일련의 태스크

- 복구의 기초

    - 각 플로우 실행시 날짜를 파라미터화 한다

    - 동일 플로우에, 동일 파라미터를 건넬 시 동일한 태스크가 실행될 수 있다 => 플로우가 도중에 실패해도 나중에 동일 파라미터로 재실행 가능

 

워크플로의 버전 관리

- 복잡화된 데이터 파이프라인의 구축은 더 이상 시스템 개발고 ㅏ다른 분야가 아니기 대문에 소프트웨어 개발 분야에서 연마되어 온 버전 관리 기법을 도입하는 것을 추천 (Git)

 

태스크를 되도록 작게 유지하기

- 큰 태스크는 나누어 적당히 작은 복수의 태스크로 플로우를 구성하자

    - 문제가 발생해도 도중에 재개할 수 있음

 

재시도

- 여러 차례 반복하는 오류는 자동화

- 오류의 원인을 그때마다 조사하여 대책 마련

 

백필

- 일정 기간의 플로우를 연속해서 실행하는 구조

- 대량의 태스크를 실행할 때에는 성능상의 주의가 필요

    - 테스트 삼아 조금씩 백필 실행

 

 

멱등한 조작으로 태스크를 기술하기

- 멱등성: 동일한 태스크를 여러 번 실행해도 동일한 결과가 된다

    - 재실행의 안전성을 확보하는 데에 가장 중요

    - 태스크를 도중까지 실행하다 실패했을 때 도중 경과가 남아있으면, 태스크 재실행에 의해 데이터가 혼재 될 수 있음

    - 각 태스크는 원칙적으로 '마지막까지 성공'하거나 '실패하면 아무것도 남지 않음' 이 둘 중 하나만 존재해야 함

        - '도중가지 성공'이라는 어정쩡한 상황은 허가하지 않아야 함

 

원자성 조작

- 원자성 조작(atomic operation): 각 태스크가 시스템에 변경을 가하는 것을 한 번만 할 수 있도록 하는 것

- 워크플로에 포함된 태스크를 모두 원자성 조작으로 구현함으로써 재시도의 안전성을 높일 수 있음

- 원자성 조작이 문제를 야기하는 경우:

    - 원자성 조작 직후에 문제가 발생하면, 워크플로 관리 도구에서 이를 오류로 여겨 재시도 하는 경우

    -> 재시도로 인한 중복 발생

 

멱등한 조작 - 추가와 치환

- 멱등한 조작(idempotent operation): 동일한 태스크를 여러 번 실행해도 동일한 결과가 되도록 하는 것

    - 안정성을 확보하는 가장 확실한 방법

- 위 예시에서 멱등한 조작이면 재실행 해도 중복 발생 안함

- 원칙적으로는 항상 데이터를 덮어써야 함

    - 추가 (append)는 데이터가 중복되지만, 치환 (replace, overwrite)은 반복해도 결과가 변하지 않음

- 태스크에 부여된 파라티러를 잘 이용해 여러 번 실행해도 항상 치환이 되도록 설계

 

멱등한 추가

- 테이블 파티셔닝하여, 파티션 단위로 치환하도록 한다

- 태스크를 멱등으로 구성하는 것이 어렵다면, 그것을 포기하고 원자성을 지닌 추가로 운용

    - 오류 발생 시, 수작업으로 복구

 

원자성을 지닌 추가

- 하나의 테이블에 몇 번이고 데이터를 써넣을 때가 있음

    - 이 경우 추가를 반복하지 말고 중간 테이블을 만들어 처리한 후, 마지막에 목적 테이블에 한 번에 추가하는 것이 안전

 

워크플로 전체를 멱등으로 하기

- 데이터 파이프라인을 안정적으로 운용하기 위해서는 거기에 포함된 태스크나 플로우를 가능한 한 멱등으로 해야 함

- 데이터 마트를 구축하는 플로우에서도 되도록 추가는 삼가고 테이블마다 치환

    - 멱등한 태스크는 실패시 안전하게 재실행할 수 있음

태스크 큐: 자원의 소비량 컨트롤하기

- 워크플로 관리 도구에서 요구되는 커다란 역할 중 하나가 부하 컨트롤

- 병렬화가 필요한 경우

    - 너무 대량의 태스크를 동시 실행하면 서버에 과부하가 걸리므로 어느 정도 제한을 해야 함

- 잡 큐 (job queue) (= 태스크 큐(task queue)) 구조

    - 모든 태스크는 일단 큐에 저장되고 일정 수의 워커 프로세스가 그것을 순서대로 꺼내면서 병렬화가 실현

병목 현상의 해소

- 워크플로 실행 시 자주 발생하는 문제 (서버의 내부적인 요인)

    1. CPU 사용률 100% -> CPU 코어 수를 늘린다. 서버를 증설한다.

    2. 메모리 부족 -> 메모리를 증설한다. 스왑 디스크를 추가한다. 태스크를 작게 분할한다.

    3. 디스크 넘침 -> 각 태스크가 임시 파일을 삭제하고 있는지 확인한다. 디스크를 증설한다.

    4. 디스크 I/O의 한계 -> SSD 등의 고속 디스크를 사용한다. 여러 디스크로 분산한다.

    6. 네트워크 대역의 한계 -> 고속 네트워크를 사용한다. 데이터의 압축률을 높인다.

    7. 통신 오류나 타임 아웃 -> 시스템 상의 한계일 가능성이 있다. 서버를 분리한다.

- 서버 외부 요인이 원인인 병목 현상은 문제를 제거할 수 없다.

 

태스크 수의 적정화 - 너무 크거나 너무 작지 않은 정도로 잘 분할하기

- 작은 태스크를 자주 실행하면 오버헤드만 커짐

- 태스크가 너무 클 경우에는 나누고, 너무 작을 경우에는 하나로 모음으로써 각 태스크가 적절한 크기가 될 수 있도록 조정

 

 

5-2. 배치 형의 데이터 플로우

MapReduce의 시대는 끝났다 - 데이터 플로우와 워크플로

- 데이터 플로우(data flow): 다단계의 데이터 처리를 그대로 분산 시스템 내부에서 실행 (워크플로와 구분해서 사용)

MapReduce의 구조

- 과거 빅데이터의 대표적인 기술이었지만 이제 새롭게 사용되는 일은 없어짐

    - Google: MillWheel
    - Hadoop: Tez
- MapReduce의 개념
    1. Split: 분산 처리를 위해 데이터 파일을 일정 크로 나눔
    2. Map: 분할된 데이터를 처리 (함수 적용 ex. count)
    3. Reduce: 분산된 결과를 모아서 집계

- 하나의 사이클이 끝나지 않으면 다음 처리로 이동하지 못함

    - 하나의 사이클에서 다음 사이클로 이동할 때까지의 대기 시간이 긴 단점

- 애드 혹 분석에서는 실현 어려움

 

MapReduce를 대신할 새로운 프레임워크 - DAG에 의한 내부 표현

- DAG(Directed Acyclic Graph) 데이터 구조로 새로운 프레임워크에서 사용

    - 데이터 플로우에서 실행해야 할 일련의 태스크를 DAG에 의핸 데이터 구조로 표현

    - 화살표는 태스크 실행 순서

    - 의존 관계를 유지하며 실행 순서를 알맞게 정하면 모든 태스크를 빠짐없이 완료할 수 있음

    - DAG는 시스템 내부적인 표현으로 이용자가 존재를 의식할 일 거의 없음: 데이터 플로우에 국한되지 않고, Hive on Tez나 Presto같은 쿼리 엔진에서도 DAG 구조 채택

Spark에서의 DAG

- Spark과 같은 데이터 플로우 프레임워크서는 프로그래밍 언어를 사용하여 DAG를 직접 조립

    - 처리 내용이 복잡해지면 DAG도 그만큼 복잡해짐

- 지연 평가 (lazy evaluation): 프로그램의 각 행은 실제로는 DAG 데이터 구조를 조립할 뿐, 후에 실행 결과를 요구할 때 데이터 처리가 시작됨

    => 내부 스케줄러가 분산 시스템에 효과적인 실행 계획을 세울 수 있음

데이터 플로우와 워크플로를 조합하기

- 태스크를 정기적으로 실행하거나, 실패한 태스크를 기록하여 복구하는 것은 데이터 플로우에서 할 수 없음. 워크플로 관리 필요

    - 데이터 플로우의 프로그램도 워크플로의 태스크로 고려할 수 있음

- 분산 시스템 외부와 데이터를 주고받을 경우도 워크플로 안에서 실행하는 것이 바람직

데이터를 읽어들이는 플로우

- 워크플로 조합

    - Task 1: 데이터 소스에서 분산 스토리지로 벌크 전송

    - Task 2: 데이터 플로우로 필요한 연산, 분산 스토리지에서 실행

데이터를 써서 내보내는 플로우

- 워크플로 조합

    - Task 1: 데이터 플로우를 통해 CSV 같이 취급하기 쉬운 형식으로 변환

    - Task 2: 외부로 전송

 

데이터 플로우와 SQL을 나누어 사용하기

- 데이터 웨어하우스 파이프라인 (SQL을 MPP 데이터베이스에서 실행)

    - 데이터 플로우: DB에서 분산 스토리지로 벌크 전송 -> 데이터 웨어하우스로 로드

    - SQL: 배치 처리 (시각화)

- 데이터 마트 파이프라인 (쿼리 엔진은 분산 시스템에서 실행)

    - 데이터 플로우: DB에서 분산 스토리지로 벌크 전송

    - SQL: 쿼리 엔진으로 배치 처리 (마트 제작)

대화식 플로우 - 애드혹 분석의 파이프라인

- 데이터 처리를 수작업으로 시행하므로 워크플로는 필요하지 않음

- 구조화되어 있지 않은 데이터를 애드 혹 분석시, 데이터 플로우가 매우 유용

- 구조화된 데이터는 쿼리 엔진을 사용

 

5-3. 스트리밍 형의 데이터 플로우

배치 처리와 스트림 처리로 경로 나누기

- 배치 처리 중심의 데이터 파이프라인의 결점은 데이터가 분석할 수 있게 될 때까지 시간이 걸림

- 실시간: 이벤트 발생에서 몇 초 후에는 결과를 알 수 있는 것

- 실시간성이 높은 데이터 처리 시스템 예

    - 시스템 모니터링

    - 로그 관리 시스템

    - 복합 이벤트 처리 (Complex Event Processing, CEP)

- 스트림 처리 (streaming processing): 분산 스토리지를 거치지 않고 처리를 계속하는 것

- 스트림 처리는 실시간성이 우수하지만, 과거 데이터를 취급하는 데에는 부적합

배치 처리와 스트림 처리 통합하기

- 배치 처리: 먼저 데이터가 있고, 그것을 작게 나눠서 DAG에 흘려 넣음 (유한 데이터 bounded data)

- 스트림 처리: 끊임없이 데이터가 생성되며, 그것이 DAG 안에 흘러들어옴 (무한 데이터 unbounded data)

- DAG를 사용한 데이터 플로우에서는 배치 처리와 스트림 처리를 동일하게 프로그래밍하는 것이 가능

Spark 스트리밍의 DAG

- 데이터를 읽고 쓰는 초기화 부분(socketTextStream("localhost", 9999))에 차이가 있을 뿐, 데이터 처리 중심부 (Map -> Reduce)는 동일

- 배치 처리는 데이터 처리가 끝나면 종료되는데, 스트림 처리는 프로그램을 정지할 때까지 끝없이 실행

 

스트림 처리의 결과를 배치 처리로 치환하기

- 스트림 처리의 두 가지 문제

    1. 잘못된 데이터 수정하기 어려움

    2. 늦게 전송된 데이터 취급

- 배치 처리를 실행해 스트림 처리의 문제를 대처

    - 스트림 처리 결과는 배치 처리 결과가 나올 때까지의 잠정 값으로 이용

람다 아키텍처: 배치 레이어, 서빙 레이어, 스피드 레이어

- 배치 레이어: 과거 데이터를 장기적인 스토리지에 축적하고, 여러 번이고 다시 집계

    - 대규모 배치 처리를 실행할 수 있는 반면, 1회 처리에는 긴 시간 걸림

- 서빙 레이어: 응답이 빠른 데이터베이스 설치

    - 배치 뷰: 서빙 레이어에서 얻어진 결과

        - 정기적으로 업데이트되지만, 실시간 정보를 얻을 수 없음

- 스피드 레이어: 스트림 처리

    - 실시간 뷰: 배치 뷰가 업데이트될 동안까지 이용되고 오래된 데이터는 순서대로 삭제

- 장점: 실시간 뷰의 결과는 나중에 배치 뷰로 치환

- 단점: 나쁜 개발 효율

    - 스피드 레이어와 배치 레이어 모두 똑같은 처리를 구현하는 비효율

 

카파 아키텍처

- 카파 아키텍처: 람다 아키텍처를 단순화함

- 배치 레이어, 서빙 레이어 제거하고 스피드 레이어만 남김

- 메시지 브로커의 데이터 보관 기간을 충분히 길게 함

    - 스트림 처리를 멱등으로 구현하여, 과거 데이터 보정(백필)을 가능하도록 함

- 단점: 부하가 높아짐

    - 클라우드 서비스 보급에 의해 자원 확보가 어렵지 않게 되었으므로 '스트림 처리르 다시 하는 것이 간단하다'는 게 카파 아키텍처의 철학

 

아웃 오브 오더의 데이터 처리

- 아웃 오브 오더(out of order) 데이터: 늦게 도달하는 메시지, 프로세스 시간과 이벤트 시간의 차이

 

원래 데이터의 모습은 '이벤트 시간'으로 얻을 수 있다

- 이벤트 시간으로 집계한 것이 올바른 결과

이벤트 시간 윈도잉

: 이벤트 시간에 의해 윈도우를 나누는 것

- 과거 이벤트 상태를 보관하면서, 데이터가 도달할 때마다 해당하는 윈도우를 재집계할 필요 있음

- 일정 시간 늦게 온 데이터는 무시

4-1. 벌크 형과 스트리밍 형의 데이터 수집

데이터 전송의 두 종류

- 벌크 형

- 스트리밍 형

객체 스토리지와 데이터 수집

빅데이터는 단지 수집만 해서는 안 되고 나중에 처리하기 쉽도록 준비해 둘 필요가 있다

- 대략 1MB ~ 1GB

데이터 수집: 수집한 데이터를 가공하여 집계 효율이 좋은 분산 스토리지를 만드는 일련의 프로세스

- 데이터 수집

- 구조화 데이터 작성

- 분산 스토리지 장기적 저장

벌크 형의 데이터 전송: ETL 서버의 설치 필요성

벌크 형 (전통적인 데이터 웨어하우스에서 사용)

- 데이터베이스, 파일 서버 또는 웹 서비스 등에서 각각의 방식 (SQL, API 등)으로 정리해 데이터를 추출

- 원래 데이터가 처음부터 분산 스토리지에 저장되어 있는 것이 아니라면 데이터 전송을 위한 ETL 서버를 설치

 

파일 사이즈의 적정화는 비교적 간단하다

- 하루마다 또는 1시간 마다의 간격으로 정기적인 실행을 하므로 그동안 축적된 데이터를 하나로 모아서 전송 (=> 파일 사이즈 결정)

- 너무 많은 양의 데이터를 한꺼번에 전송하려 하는 것은 위험: 너무 큰 데이터라면 전송 도구에서 나눌 수 있음

    - 한 번의 태스크 실행이 커지지 않도록 조정

 

데이터 전송의 워크플로 - 워크플로 관리 도구와의 친화성

- (스트리밍은 재실행이 어려운 방면) 문제가 발생했을 때 여러 번 데이터 전송을 재실행할 수 있다는 점이 벌크 형의 장점

    - 워크플로 관리도구(ex. Airflow) 와 궁합이 뛰어남 

 

스트리밍 형의 데이터 전송

- 계속해서 전송되어 오는 작은 데이터를 취급하기 위한 전송 방식

    - 지금 바로 생성되어 아직 어디에도 저장되지 않은 데이터는 그 자리에서 바로 전송할 수밖에 없음

- 예: '웹 브라우저', '모바일 앱', 센서 기기 등의 '디바이스'에서의 데이터 수집

    - 다수의 클라이언트에서 계속해서 작은 데이터가 전송됨 (= 메시지 배송)

- 메시지 배송 시스템은 전송되는 데이터양에 비해 통신을 위한 오버헤드가 커짐

    => 이를 처리하는 서버는 높은 성능을 요구

- 메시지 저장 방식

    1. NoSQL 데이터베이스 사용

    2. 메시지 큐, 메시지 브로커 등의 중계 시스템 사용

 

웹 브라우저에서의 메시지 배송

- 로그 수집 소프트웨어 자주 사용

- 웹 이벤트 추적: 자바스크립트 사용

모바일 앱으로부터의 메시지 배송

- 메시지 배송 방식이 웹 브라우저와 동일

- 백엔드 서비스 (Mobile Backend as a Service)를 이용할 수도 있음

- 모바일용 SDK를 사용하기도 함

- 데이터가 중복될 가능성도 높아, 중복 제거 구조가 필요할 수도

디바이스로부터의 메시지 배송

- MQTT (MQ Telemetry Trnasport)

    - Topic, 구독

메시지 배송의 공통화

- 클라이언트 (Client): 메시지가 처음 생성되는 기기

- 프론트 엔드 (Frontend): 해당 메시지를 먼저 받는 서버

    - 프론트 엔드의 역할: 클라이언트와의 통신 프로토콜을 제대로 구현하는 것

- 메시지 브로커: 프론트 엔드가 받은 메시지를 전송 받음

    - 이후 분산 스토리지에 데이터 저장

- 역할 분리를 통해 프론트 엔드는 단지 데이터를 받는 것에만 전념하고 거기에서 그 이후의 어려운 문제에 대해서는 백 엔드에 존재하는 공통 시스템에 맡길 수 있음

4-2. [성능 x 신뢰성] 메시지 배송의 트레이드 오프

메시지 브로커 - 스토리지의 성능 문제를 해결하는 중간층의 설치

- 대량의 메시지를 안정적으로 받기 위해서는 빈번한 쓰기에도 견딜 수 있도록 성능이 매우 높고 필요에 따라 성능을 얼마든지 올릴 수 있는 스토리지 필요

    - 분산 스토리지가 그런 성격을 갖고 있지 못함

- 메시지 브로커(Message Broker): 데이터를 일시적으로 축적하는 중간층

    - 오픈 소스: Apache Kafka

    - 클라우드 서비스: Amazon Kinesis

 

푸시 형, 풀 형 - 확장성 향상과 파일 사이즈의 적정화

메시지 브로커는 높은 빈도의 데이터 쓰는 것에  최적화 됨 + 여러 대 노드에 부하 분산하여 성능을 끌어올릴 수 있는 뛰어난 확장성 구현

- 푸시 (Push)형: 송신 측의 제어로 데이터를 보내는 방식

- 풀 (Pull)형: 수신 측의 주도로 데이터를 가져오는 방식

- 생산자 (Producer): 메시지 브로커에 데이터를 넣는(push) 것

- 소비자 (Consumer): 메시지 브로커로부터 데이터를 꺼내오는(pull) 것

    - 소비자는 메시지 브로커로부터 일정한 간격으로 데이터를 취함으로써 적당히 모아진 데이터를 분산 스토리지에 기록

 

메시지 라우팅

- 스트림 처리 (Stream Processing): 짧은 간격으로 차례대로 데이터를 꺼내서 처리하는 것

- 메시지 라우팅 (Message Routing): 메시지가 복사되어 데이터를 여러 경로로 분기시킨 것

    - 메시지 브로커에 써넣은 데이터는 복수의 다른 소비자가 읽을 수 있음

    - ex. 일부는 장애 감지에 사용 + 장기적인 데이터 분석을 위한 분산 스토리지에 저장

 

메시지 배송을 확실하게 실시하는 것은 어렵다 : 신뢰성 문제와 세 가지 설계 방식

- 신뢰성 문제: 모바일 회선과 같은 신뢰성이 낮은 네트워크에서는 반드시 메시지 중복이나 누락이 발생

- 메시지 처리 시스템의 설계 방식

    1. at most once: 메시지는 한 번만 전송. 그러나 도중에 전송에 실패해서 사라질 가능성 있음 (누락)

    2. exactly once: 메시지는 손실되거나 중복 없이 한 번만 전달

    3. at least once: 메시지는 확실히 전달. 단 같은 것이 여러 번 전달될 가능성 있음 (중복)

 

at most once

- 무슨 일이 일어나도 절대로 메시지를 다시 보내지 않음

- 그러나 대개는 데이터 결손을 피하고자 재전송(retransmission)이 이루어짐 - 재전송하는 시스템에서는 at most once를 보장하는 것이 어려움

exactly once

- 양 쪽 통신 내용을 보장하려면 그 사이를 중계하는 coordinator의 존재가 필수

    - 송신 측과 수신 측 모두 서로의 정보를 코디네이터에게 전달함으로써 문제가 발생한 경우에는 코디네이터의 지시에 따라 해결

- 근본적인 두 가지 문제 

    1. 분산 시스템에서는 coordinator가 항상 존재한다고 가정할 수 없음

        - coordinator와의 통신이 끊기는 경우도 있고, coordinator 자체가 정지될 수도 있음

        - coordinator 부재 (장애)의 경우 어떻게 할 것이가에 대한 합의 필요 => 분산 시스템 설계에 어려움 가중

    2. coordinator 의 판단에만 의존하면 시간이 너무 소요됨

 

at least once: 중복 제거는 사용자에게 맡긴다

- 위의 이유로, 대부분 메시지 배송 시스템에서는 coordinator를 도입하지 않고 at least once로 구축

    - 중복 제거는 메시지 소비자부터의 사용자에게 맡기고 있음

 

중복 제거는 높은 비용의 오퍼레이션

중복 제거의 여러 방법들과 철학

오프셋을 이용한 중복 제거

- 메시지가 중복되어도 같은 파일의 같은 장소 덮어쓰기

- 벌크 형의 데이터 전송과 같이 데이터 양이 고정된 경우에 잘 작동

- 스트리밍 형식의 메시지 배송에서는 채택 거의 안함

고유 ID에 의한 중복 제거

- 모든 메시지에 UUID (Universally Unique IDentifier) 지정

- 메시지가 늘어남에 따라 ID가 폭발적으로 증가 - 이에 대한 관리 필요

    - 과거 전송된 모든 ID를 기억하는 것은 비현실적이고, ID를 파기하면 늦게 도착한 메시지가 중복됨

    - 현실적인 타협: 최근 ID만 기억하고 (최근 n시간) 이후 중복은 허용

        - 중복은 일시적인 통신 오류 때문이므로 이를 제거하면 99%의 신뢰도 달성

종단간(End to End)의 신뢰성

- 빅데이터의 메시지 배송에서는 신뢰성보다는 '효율'쪽이 중시됨

    - 중간 경로에 'at least once'를 보장하는 한편, 중복 제거는 하지 않는 것이 표준적인 구현

- 이론상 스트리밍에서 중복 제거가 완벽히 되려면, 송신과 수신 양 쪽 모두 중복제거를 잘 해야 한다

    - 매우 어려움

- 중간 경로를 모두 at least once로 통일하고 클라이언트 상 모든 메시지에 고유 ID를 포함하도록 하여 경로 말단에서 중복 제거를 실행하자 (일반적인 설계)

경로 말단에서 고유 ID를 사용한 중복 제거의 방법 - NoSQL 데이터베이스 vs SQL

1. 분산 스토리지로 NoSQL 데이터베이스 이용

    - Cassandra, Elasticsearch 등은 데이터 쓸 때 고유 ID를 반드시 지정 => 동일한 ID의 데이터는 덮어씀

2. SQL로 중복 제거 (SELECT DISTINCT ...)

    - 대규모 데이터 처리이므로 메모리 실행은 거의 불가능하고 Hive같은 배치형 쿼리 엔진에서 실행

 

데이터 수집의 파이프라인 - 장기적인 데이터 분석에 적합한 스토리지

데이터 수집 파이프라인

이처럼 일련의 프로세스를 거친 다음, 마지막으로 데이터를 구조화해서 열 지향 스토리지로 변환

=> 장기간 데이터 분석에 적합한 스토리지 완성

 

중복을 고려한 시스템 설계 - 빅데이터 시스템에 있어서의 '중복'에 대한 사고방식

- 일반적으로 스트리밍 형의 메시지 배송에서는 중간에 명시적으로 중복 제거 방식을 도입하지 않는 한 항상 중복의 가능성이 있다고 생각하는 것이 좋다

    - 빅데이터 시스템은 매우 높은 성능을 요구하기 때문에 아주 작은 중복은 무시하는 경향

    - 중복이 있어도 문제가 되지 않는 시스템을 설계하자

- 신뢰성이 중시되는 경우에는 스트리밍 형의 메시지 배송은 피하는 것이 가장 좋다

    - ex. 과금에 필요한 데이터 (오차가 허용되지 않음)

        - 트랜잭션 처리를 지원하는 데이터베이스에 애플리케이션이 직접 기록

        - 이후 벌크 형의 데이터를 전송 함으로써 중복도 결손도 확실하게 피함

 

4-3. 시계열 데이터의 최적화

스티리밍 형의 메시지 배송에서는 '메시지가 도착할 때까지의 시간 지연'이 문제

프로세스 시간과 이벤트 시간

- 이벤트 시간 (event time): 클라이언트 상에서 메시지가 생성된 시간

- 프로세스 시간 (process time): 서버가 처리하는 시간

- 데이터 분석의 대상이 되는 것은 '이벤트 시간'

 

프로세스 시간에 의한 분할과 문제점 - 최대한 피하고 싶은 풀 스캔

- 늦게 도달하는 데이터가 있다는 것은 과거 집계 결과가 매일 조금씩 바뀜

   - 보다 실태에 가까운 집계 결과를 얻기 위해서는 '이벤트 시간'보다 며칠 지난 시점에서 소급해 집계 해야 함

- 이벤트 시간으로 데이터가 정렬되어 있지 않으면, 모든 데이터를 로드(풀 스캔)해야만 이벤트 시간을 검색할 수 있음

 

시계열 인덱스 - 이벤트 시간에 의한 집계의 효율화 1

- 시계열 인덱스 (time-series index): 이벤트 시간에 대해 인덱스를 만드는 것

    - ex. Cassandra는 시계열 인덱스를 사용하는 데이터베이스

- 장점: 매우 짧은 범위의 특정 시간에 맞춘 데이터 집계 빠르게 실행 가능

- 단점: 장기간에 걸쳐 대량의 데이터를 집계하는 경우에는 비효율적

조건절 푸시 다운 - 이벤트 시간에 의한 집계의 효율화 2

- 배치 처리를 통해, 이벤트 시간으로 데이터 정렬 후 열 지향 스토리지로 변환

- 조건절 푸시 다운(predicate pushdown): 정렬된 데이터의 칼럼 단위 통계 정보를 이용한 최적화

    - 각 칼럼의 최솟값, 최댓값을 메타 정보로 저장

이벤트 시간에 의한 분할 - 테이블 파티셔닝, 시계열 테이블

- 시계열 테이블 (time-series table): 시간을 이용하여 물리적으로 파티셔닝한 테이블

    - 이벤트 발생 시간을 파티션으로 하여 새로운 데이터가 들어올 때 (늦게 올 때)마다 추가

- 잠재적 문제: 시계열 테이블을 구성하는 각 파티션에 매일 조금씩 데이터가 추가됨

    => 분산 스토리지에 대량의 작은 파일이 만들어지고 점차 쿼리 성능이 악화됨

    => 작은 데이터를 효율적으로 추가할 수 있는 분산 데이터베이스를 사용하거나 너무 오래된 데이터는 버려야 함

데이터 마트를 이벤트 시간으로 정렬하기

- 데이터 마트 제작시 이벤트 시간에 의한 정렬

    - 수집 단계에서는 프로세스 시간으로 저장

- 항상 최적의 데이터를 유지할 수 있는 좋은 방법

 

모바일 기기의 시계는 미쳤다(!?)

- 시간이 이상한 데이터는 가급적 이른 단계에서 찾아 제외

    - 집계 효율에 문제 일으킬 수도

 

4-4. 비구조화 데이터의 분산 스토리지

NoSQL 데이터베이스의 몇 가지 특징

참고: https://db-engines.com/en/ranking

[기본 전략] NoSQL 데이터베이스에 의한 데이터 활용

- 객체 스토리지 상의 파일은 교체하기 어려움

- 쓰기 빈도가 높은 데이터는 RDB로 저장하고, 정기적으로 스냅샷을 하거나 다른 '분산 데이터베이스'에 저장하도록 해야 함

- 객체 스토리지는 '데이터를 기록하고 곧바로 활용'하는 것은 부족

    - 실시간 집계와 검색에 적합한 데이터 저장소가 필요

- NoSQL 데이터베이스: 특정 용도에 최적화된 데이터 저장소

분산 KVS: 디스크로의 쓰기 성능 높이기

- 분산 KVS (Distributed Key-Value Store): 모든 데이터를 key-value 쌍으로 저장하도록 설계된 데이터 저장소

    - (객체 스토리지도 넓은 의미에서는 분산 KVS의 일종이지만, 여기서는 좀 더 '작은 데이터'를 가정)

- 작동 방식    

    1. 모든 데이터에 고유의 키를 지정 - 부하 분산을 위해 이용

    2. 키가 정해지면 그 값을 클러스터 내의 어느 노드에 배치할 것인지 결정 - 부하를 균등 분산하고 노드를 증감하여 클러스터 성능 변경

Amazon DynamoDB

- 데이터의 읽기 쓰기에 지연이 발생하면 곤란한 애플리케이션에 유용

- P2P형: 모든 노드가 대등한 관계

    - 참고) 마스터/슬레이브형: 1대의 마스터가 전체를 관리

- Amazon EMR, Amaozon Redshift 등과 결합함으로써 Hive 배치 처리 및 데이터웨어하우스에 데이터 전송 등이 가능

- DynamoDB Streams로 실시간 스트림 처리도 가능

 

NoSQL 데이터베이스 자체는 대량의 데이터를 집계하는 기능이 없는 것이 많아 데이터 분석을 위해서는 외부로 데이터 추출 해야 함

 

[기초 지식] ACID, CAP

ACID: 트랜잭션 처리에 요구되는 4가지 성질 (일반적인 RDB는 이들을 충족)

- Atomicity: 원자성

- Consistency: 일관성

- Isolation: 독립성

- Durability: 내구성

 

CAP: 분산 시스템은 ACID 특성을 만족하는게 어려워, 그 한계로 제창 (일반적으로 분산 시스템에서는 다음 3가지를 동시 충족시킬 수 없어 어느 하나가 희생될 수 있음)

- Consistency: 일관성

- Availability: 가용성

- Partition-Tolerance: 분단 내성

 

결과 일관성

- NoSQL 데이터베이스 일부는 CAP의 '일관성'이나 '가용성' 중 하나 선택

- 일관성 우선하고 가용성 포기 = 단시간의 장애 발생 수용

- 가용성을 우선하고 일관성을 포기 = 오래된 데이터 읽을 수 있지만, 써 넣은 데이터를 바로 읽을 수 없는 경우 존재

 

 

와이드 칼럼 스토어: 구조화 데이터를 분석해서 저장하고

- 와이드 칼럼 스토어 (wide-column store) 분산 KV를 발전시켜 2개 이상의 임의의 키에 데이터를 저장할 수 있도록 한 것

    - Goggle Cloud Bigtable, Apache HBase, Apache Cassandra

- 행 추가 뿐만 아니라 칼럼 추가도 얼마든지 할 수 있음 (이론 상 수억의 칼럼 만들 수 있음)

    - 가로, 세로 2차원 (또는 그 이상)의 데이터 구조

 

Apache Cassandra

- 별도의 쿼리 언어 존재 (CQL)

- 테이블의 스키마를 결정하여 구조화 데이터만 취급

- 동일한 키를 가진 레코드가 존재하면 INSERT INTO로 덮어쓸 수 있음 

- P2P 형의 분산 아키텍처: 저장한 키에 의하 결정한 노드에 해당 키와 관련된 모든 값을 저장

    - 다수의 독립적인 키가 있는 경우 처리를 잘 분산

- 데이터를 집계하는 데에는 적합하지 않음: 집계를 위해서는 분산된 모든 노드에서 데이터를 모아야 함

    - Hive, Presto, Spark 등의 쿼리 엔진 모두 Cassandra로부터의 로드에 대응

도큐먼트 스토어: 스키마리스 데이터 관리하기

- 데이터 처리의 유연성이 목적

- JSON처럼 복잡하게 뒤얽힌 스키마리스 데이터를 그대로의 형태로 저장

- 장점: 스키마를 정하지 않고 데이터 처리할 수 있음

    - 외부 시스템의 데이터 및 로그 저장 등에 적합

- 최근 RDB에서도 도큐먼트 스토의 기능이 포함됨

MongoDB

- 성능을 우선하여 신뢰성을 희생

- 그 자체는 대량의 데이터 집계에 적합하지 않음. 분석이 목적인 경우에 쿼리 엔진으로부터 접속

 

검색 엔진: 키워드 검색으로 데이터 검색

- 텍스트 데이터를 전문 검색하기 위해 '역 색인 (inverted index)'을 만들어 사용

    - 데이터를 기록하는 리소스는 커지지만, 그 덕분에 키워드 검색이 훨씬 고속화됨

- 역 색인(inverted index): 텍스트에 포함된 단어를 분해하고 어떤 단어가 어떤 레코드에 포함되어 있는가 하는 인덱스를 미리 만들어 둠으로써 검색을 고속화

- NoSQL이 index 제작을 최소화하는 반면, 검색 엔진은 index를 적극적으로 제작

    - 검색 엔진은 데이터 집계에 적합

    - 비정상적인 상태 감지 및 보안 체크, 고객 서포 등 민첩성이 요구되는 용도에 사용

    - (장기적 데이터 축적보다는) 실시간 집계 시스템의 일부로 이용

 

Elasticsearch

- 오픈소스 검색 엔진

- ELK 스택

    - 검색엔진 소프트웨어: Elasticsearch

    - 로그 수집 소프트웨어: Logstash

    - 시각화 소프트웨어: Kibana

Splunk

- 비정형 데이터(웹 로그, JSON 파일 등)에 특화

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하려면 데이터가 없음

- 스냅샷 테이블은 나중에 다시 만들 수 없으므로, 영구적인 저장소에 보관하여 삭제되지 않도록 주의

- 스냅샷시 처음부터 비정규화된 것이 편함

 

이력 테이블 - 마스터 변화 기록하기

- 변경이 있을 대마다 그 내용 기록

- 데이터 양을 줄이는 데 도움이 되지만, 어느 순간의 완전한 마스터 테이블을 나중에 복원하는 것이 어려움

    - 디멘전 테이블로 사용하기 위해 별도의 처리를 통해 마스터 테이블로 복원해야 함

 

[마지막 단계] 디멘전을 추가하여 비정규화 테이블 완성시키기

- 팩트 테이블과 디멘전 테이블을 결합하여 비정규화 테이블 생성

2-1. 크로스 집계의 기본

트랜잭션 테이블, 크로스 테이블, 피벗 테이블

- 크로스 테이블: 행과 열이 교차하는 부분에 숫자 데이터가 들어가 있는 테이블. 보고서의 기본

- 트랜잭션 테이블: 행 방향으로만 증가하고 열 방향으로는 증가하지 않는 테이블 (데이터 베이스에 새로운 행을 추가하는 것은 간단하지만, 열을 늘리는 것은 간단하지 않음)

- 크로스 집계: 트랜잭션 테이블에서 크로스 테이블로 변환하는 과정 (ex. 스프레드시트의 pivot table 기능)

룩업 테이블

- 추가 정보를 참고하고 싶을 때 사용 (트랜잭션 테이블에 추가하는 것은 간단하지 않으므로)

 

SQL에 의한 테이블의 집계

- 스프레드시트, BI 도구, pandas는 대량의 데이터를 크로스 집계하기에 부적합 (느려져서 불편)

- 대량의 데이터를 집계하는 데에 뛰어난 SQL로 먼저 양을 줄이고(데이터 집계 프로세스), 시각화 도구로 크로스 집계하는 것(시각화 프로세스)이 가능

 

데이터 집계 -> 데이터 마트 -> 시각화

데이터 마트: 데이터 집계와 시각화 사이에 있음

- 데이터 마트의 크기에 따라 시스템 구성이 결정

- trade-off: 데이터 마트가 작을수록 시각화하는 것이 간단하지만, 많은 정보를 잃어 시각화 프로세스에서 할 수 있는 것이 적어짐 <-> 데이터 마트를 크게 유지하면 시각화하는 것이 복잡해짐

 

2-2. 열 지향 스토리지에 의한 고속화

데이터베이스의 지연 줄이기

3계층의 데이터 집계 시스템: "데이터 레이크" -> (데이터 집계) -> "데이터 마트" -> (크로스 집계) -> "시각화 도구"

데이터 처리의 지연

latency를 줄이는 두 가지 방법

1. 모든 데이터를 메모리에 올리는 것

2. RDB를 사용하는 것: RDB는 원래 지연이 적고 많은 수의 클라이언트가 동시 접속해도 성능이 나빠지지 않음

- 하지만 RDB는 메모리가 부족하면 급격히 성능이 저하됨 (디바이스 I/O 발생)

'압축'과 '분산'에 의해 지연 줄이기: MPP 기술

MPP (Massive Parallel Processing): 분산된 데이터를 읽기 위해 멀티 코어를 활용하면서 디스크 I/O를 병렬 처리 하는 아키텍처

ex. Amazon Redshift, Google BigQuery

- 데이터 집계에 최적화 됨

- 데이터 웨어하우스, 데이터 분석용 데이터베이스에 활용

 

열 지향 데이터베이스 접근 

- 행 지향 데이터베이스: 레코드 단위의 읽고 쓰기에 최적화 (일반적인 운영용 데이터베이스) (ex. Oracle, MySQL)

- 열 지향 데이터베이스: 칼럼 단위 집계에 최적화 (데이터 분석에 사용되는 데이터베이스)

 

행 지향 데이터베이스

- 매일 발생하는 대량의 트랜잭션을 지연 없이 처리하기 위해 데이터 추가를 효율적으로 할 수 있도록 함

- 데이터 검색을 고속화하기 위해 index를 만듬 -> 디스크 I/O를 최적화하기 위해 적절한 index 튜닝이 중요

- 필연적으로 대량의 데이터 분석은 항상 디스크 I/O를 동반하기 때문에 index에 의지하지 않는 고속화 기술 필요

 

열 지향 데이터베이스

- 미리 칼럼 단위로 정리해 둠으로써 필요한 칼럼만 로드하여 디스크 I/O를 줄임

- 데이터 압축 효율도 우수

 

MPP 데이터베이스의 접근 방식

쿼리 지연을 줄이는 또 다른 방법은 MPP 아키텍처에 의한 데이터 처리의 병렬화

- 열 지향 데이터베이스는, 디스크에서 대량의 데이터를 읽기 때문에 1번의 쿼리 실행시간이 길어짐 + 압축된 데이터의 전개 등 CPU 리소스 필요 => 멀티 코어를 활용하여 고속화하는 것이 좋음

- MPP: 하나의 쿼리를 다수의 작은 태스크로 분해하고 이를 가능한 한 병렬로 실행

 

MPP 데이터베이스와 대화형 쿼리 엔진

- MPP를 사용한 데이터 집계는 CPU 코어수에 비례하여 고속화

    - 이를 위해 데이터가 고르게 분산되어 있어야 함 (쿼리가 잘 병렬화되도록)

- 일부 MPP 제품은 하드웨어(MPP 데이터베이스), 소프트웨어를 통합된 제품으로 제공 (CPU, 디스크가 모두 균형있게 늘어야 성능이 확보됨)

- 다른 MPP 아키텍처는 Hadoop과 함께 사용되는 대화형 쿼리 엔진으로도 채택

    - 그러나 데이터를 열 지향으로 압축하지 않는 한 MPP 데이터베이스만큼의 성능 확보가 안됨 - Hadoop 상의 열 지향 스토리지를 만들기 위해 여러 라이브러리 개발 (Ch.3에서 언급 예정)

 

2-3. 애드 혹 분석과 시각화 도구

Jupyter Notebook에 의한 애드 혹 분석

- 어떻게 해서든 자동화를 해야겠다는 강한 이유가 없는 한, 노트북을 중심으로 하는 애드 혹 분석 환경을 갖추는 것이 우선 과제

 

대시보드 도구

- 최신의 집계 결과를 즉시 확인할 수 있길 기대

- 스몰 데이터만을 처리하는 데는 로컬 호스트 메모리에서의 처리가 가장 좋다: 네트워크 I/O, 디바이스 I/O를 모두 없앤 상테에서 데이터 집계까 가장 빠르기 때문

Redash

Superset

Kibana: Elasticsearch의 프론트엔드에서 실시간으로 작성

 

BI 도구

- 시각화에 적합 데이터 마트를 만들어 읽고 쓰는 것을 전제로 함

Tableau

 

2-4. 데이터 마트의 기본 구조

시각화에 적합한 데이터 만들기 - OLAP

OLAP (Online Analytical Processing)

- 데이터 집계를 효율화하는 접근 방법 중 하나

- 운영에서의 RDB는 표 형식으로 모델링된 데이터를 SQL로 집계 <-> OLAP에서는 '다차원 모델'의 데이터 구조를 MDX(multidimensional expressions)등의 쿼리 언어로 집계

- OLAP 큐브: 데이터 분석을 위해 만들어진 다차원 데이터

- OLAP: OLAP 큐브를 크로스 집계하는 구조

- BI 도구는 본래 OLAP 구조를 사용해 데이터를 집계하기 위한 소프트웨어 -> 데이터 마트도 이전에는 OLAP 큐브로 작성되어 있었음

 

MPP 데이터베이스와 비정규화 테이블

- 최근, MPP 데이터베이스와 인 메모리 데이터베이스 등의 보급으로 사전에 OLAP 큐브를 만드는 등의 필요가 사라짐

- BI 도구와 MPP 데이터베이스를 조합하여 크로스 집계하는게 보편화

- MPP 데이터베이스는 다차원 모델의 개념이 없기 때문에, 이를 대신에 '비정규화 테이블' 준비

- 시각화에 적합한 데이터를 만드는 것 = BI 도구를 위한 비정규화 테이블을 만든느 것

 

테이블을 비정규화하기

- 트랜잭션: 시간과 함께 생성되는 데이터를 기록한 것 (한 번 기록하면 변화하지 않음)

- 마스터: 트랜잭션에서 참고되는 각종 정보 (상황에 따라 덮어씌워짐)

- 데이터 분석의 경우, 정규화된 관계형 모델에서 출발해 반대의 비정규화를 진행

팩트 테이블과 디멘션 테이블

데이터 웨어하우스에서의 개념

- 팩트 테이블 (fact table): 트랜잭션처럼 사실이 기록된 것 - 집계의 기반이 되는 숫자 데이터(ex. 판매액)를 기록

- 디멘전 테이블 (dimension table): 마스터 테이블 - 데이터를 분류하기 위한 속성값

 

스타 스키마와 비정규화: 팩트 테이블을 중심으로 여러 디멘션 테이블을 결합

- 스타 스키마 (star schema): 팩트 테이블을 중심으로 여러 디멘전 테이블을 결합

- 장점 1. 구축이 단순: 데이터 분석을 쉽게할 수 있음

- 장점 2. 성능상 좋음: 팩트 테이블을 될 수 있는 한 작게 유지하는 것이 고속화에 유리

 

비정규화 테이블: 데이터 마트에 정규화는 필요 없다

- MPP 데이터베이스와 같은 열 지향 스토리지를 갖는 시스템이 보편화되며 사정이 바뀜

- 열 지향 스토리지는 칼럼 단위로 데이터가 저장되므로 칼럼의 수가 아무리 늘어나도 성능에 영향 주지 않음

    => 처음부터 팩트 테이블에 모든 칼럼을 포함해두고, 쿼리 실행시 테이블 결합을 하지 않는 편이 바람직

- 비정규화 테이블(denormalized table): 스타 스키마에서 좀 더 비정규화를 진행해 모든 테이블을 결합한 팩트 테이블

 

다차원 모델 시각화에 대비하여 테이블 추상화하기

다차원 모델: BI 도구의 기본이 되는 데이터 모델 - 테이블 및 칼럼 집합을 알기 쉽게 정리해 이름을 붙인 것

- 시각화를 위해 비정규화 테이블에서 다차원 모델로 추상화한다

- 측정값(measure): 숫자 데이터와 그 집계 방법을 정의하는 것

- 디멘전(dimension): 크로스 집계에 있어서 행과 열을 이용하는 것

- ex.

비정규화 테이블

매출일 점포명 지역 상품명 상품 카테고리 금액
2025-01-01 점포 A 서울 상품 A 식료품 1000
2025-01-01 점포 A 서울 상품 B 전자제품 20000
...          

 

다차원 모델

- 디멘전

이름 쿼리
매출일 "매출일"
점포명 "점포명"
지역 "지역"
상품명 "상품명"
상품 카테고리 "상품 카테고리"

 

- 측정값

이름 쿼리
금액 sum("금액")

 

 

모델의 정의 확장

다차원 모델의 정의는 나중에 확장할 수 있음 - 데이터 분석의 요구에 따라 비정규화 테이블에는 다수의 칼럼이 추가

브레이크 다운 분석(Breakdown Analysis): 전용의 디멘전을 팩트테이블에 추가하고 그룹명을 써 넣음 ->그룹별로 대시보드 작성 (필터링 활용)

고대 유물 같은 iMac 2012 를 당근마켓에 내놓고자 포맷하던 중 삽질 기록

 

1. 포맷을 하니 OS까지 다 날아가버림

-> 파티션 삭제로 해결

도움된 블로그: https://workatlotus.tistory.com/1506

 

2. 구버전 OS(Lion 10.7)가 자동 설치됨

브라우저가 너무 구버전이라 인터넷 접근이 안됨

-> https://support.apple.com/en-gb/102662에서 제공하는 OS 버전을 curl -O로 다운로드

-> dmg 파일 실행해서 installer 설치

-> installer 실행

머리말

- 이 책의 주제: '자동화된 데이터 처리'

    - 데이터 처리를 어떻게 시스템화 하는가

    - 소프트웨어, 데이터베이스, 프로그래밍 언어, 워크플로 관리, 스트림 처리 등 데이터 처리 자동화 기술

- 주요 독자: 데이터 취급 업무 종사자, 데이터 처리 시스템 개발자

- 다루지 않는 내용: 비즈니스 인텔리전스, 데이터 마이닝

- 구성

    1. 빅데이터 기초 지식: 역사적 배경 및 기본 용어 + 스몰 데이터 기술

    2. 빅데이터의 검색: 대화적인 집계와 시각화 + 데이터 마트

    3. 빅데이터의 분산 처리: Hadoop, Spark 등의 '분산 처리 프레임워크'

    4. 빅데이터의 축적: '데이터를 수집해서 보존하는' 절차 + 분산 스토리지, 데이터 수집(data ingestion)

    5. 빅데이터의 파이프라인: '데이터 처리 자동화하기' ('배치 처리', '스트림 처리') + 워크플로 관리

    6. 빅데이터 분석 기반의 구축: 응용 + Spark, Airflow, 클라우드 서비스

 

 

1-1. [배경] 빅데이터의 정착

분산 시스템에 의한 데이터 처리의 고속화

빅데이터 기술의 요구

- Hadoop: 다수의 컴퓨터에서 대량의 데이터 처리하기 위한 시스템

- NoSQL 데이터베이스: 빈번한 읽기/쓰기 및 분산 처리가 강점

- Hadoop과 NoSQL 데이터베이스의 조합: NoSQL 데이터베이스에 기록하고 Hadoop으로 분산 처리

 

분산 시스템의 비즈니스 이용 개척

- 가속도적으로 늘어나는 데이터의 처리는 Hadoop에 맡기고, 비교적 작은 데이터, 또는 중요한 데이터만을 데이터 웨어하우스에 넣는 식으로 사용

 

직접 할 수 있는 데이터 분석 폭 확대

- 클라우드를 통해 분산 처리에 필요한 자원을 확보할 수 있게 됨

- *스몰 데이터: 한 대의 노트북에서 큰 부담 없이 처리할 수 있는 만큼의 데이터 (수백만 ~ 수천만 건, GB 단위 데이터)

데이터 디스커버리의 기초지식

데이터 디스커버리: '셀프서비스용 BI 도구'

- BI 도구: 예전부터 데이터 웨어하우스와 조합되어 사용됨 (대기업의 IT 부서에 의해 도입)

-> 셀프서비스용 BI 도구는 이것을 개인도 도입할 수 있을 정도로 단순화 한 것

 

1-2. 빅데이터 시대의 데이터 분석 기반

빅데이터 기술이 기존 데이터 웨어하우스와 다른 점: 다수의 분산 시스템을 조합하여 확장성이 뛰어난 데이터 처리 구조를 만든다는 점

 

[재입문] 빅데이터 기술

데이터 파이프라인(data pipeline): 차례대로 전달해나가는 데이터로 구성된 시스템

- 어디에서 데이터를 수집하여 무엇을 실현하고 싶은지에 따라 변화

 

데이터 수집

- 데이터 전송(data transfer)의 두 가지 방법

    - 벌크형 (bulk)

    - 스트리밍형 (streaming)

 

스트림 처리와 배치 처리

- 실시간 데이터 처리와 장기적인 데이터 분석 결과를 하나의 시스템으로 실현하는 것은 쉽지 않음

 

분산 스토리지: 여러 컴퓨터와 디스크로 구성된 스토리지 시스템

- 객체 스토리지 (ex. Amazon S3)

- NoSQL 데이터베이스

 

분산 데이터 처리: 분산 스토리지 에 저장된 데이터를 처리하는 데에 필요한 프레임워크

- 빅데이터를 SQL로 집계하는 두 가지 방법

1. 쿼리 엔진 도입: ex. Hive, 대화형 쿼리 엔진

2. 데이터 웨어하우스 제품 이용: 분산 스토리지에서 추출한 데이터를 데이터 웨어하우스에 적합한 형식으로 변환해야 함

-> ETL

 

워크플로 관리

- 오류 발생 처리와 재실행 기능이 반드시 필요

데이터 웨어하우스와 데이터 마트

데이터 웨어하우스: RDB와 달리 대량의 데이터를 장기 보존하는 것에 최적화

- data source: RDB, 로그 파일 등

- ETL Process: data source에 보존된 raw data를 추출하고 필요에 따라 가공후 데이터 웨어하우스에 저장

 

데이터 마트: 데이터 웨어하우스에 시스템 부하를 줄이기 위해, 데이터 분석 등의 목적으로 필요한 데이터만 추출 후 구축

- BI 도구와 조합해 데이터를 시각화하는 데에도 사용

 

데이터 레이크

- 빅데이터 시대가 되면 ETL 프로세스 자체가 복잡해짐 (모든 데이터가 데이터 웨어하우스를 가정해 만들어지지는 않음)

- 우선 데이터가 있고, 나중에 테이블을 설계하는 것이 빅데이터

- 데이터 레이크: 미가공의 원시 데이터를 그대로 저장

데이터 레이크와 데이터 마트: 필요한 데이터는 데이터 마트에 정리

 

데이터 분석 기반을 단계적으로 발전시키기

가능한 작은 시스템에서 시작하여 나중에 단계적으로 확장해 나가는 것이 좋다

애드 혹 분석 및 대시보드 도구

애드 혹 분석: 수작업으로 데이터 추출 후 분석 - 데이터 마트를 만들지 않은 채 데이터 레이크와 데이터 웨어하우스에 직접 연결

- 사용자는 작업하기 쉬운 환경을 선호하기 때문에 대화형 분석 도구를 사용

- 대시보드 도구: 일부 대시보드 도구는 데이터 마트가 없어도 동작, 설정한 스케줄에 따라 데이터 레이크와 데이터 웨어하우스에 접속해 쿼리 실행하고 그래프 생성

데이터 마트와 워크플로 관리

데이터 분석이 복잡해지고 시각화에 BI 도구가 활용됨에 따라, 데이터 마트가 필수가 된다

- 데이터 마트 구축은 배치 처리로 자동화되는 경우가 많기 때문에 실행 관리를 위해 워크플로 관리 도구를 사용한다

- 데이터 처리를 자동화해서 장기적으로 운영해 나가기 위해서는 안정된 워크플로 관리가 필수적이다

 

- 데이터 파이프라인의 큰 흐름은 변하지 않는다

    1. 저장할 수 있는 데이터 용량에 제한이 없어야 함

    2. 데이터를 효율적으로 추출할 수단이 있어야 함

데이터를 수집하는 목적

데이터 검색

- 시스템 장애 원인 파악, 고객 문의 대응을 위한 로그 확인 등

- 시스템 로그, 고객 행동 로그 등 발생하는 모든 데이터를 ㅜ취득해 놓는다

- 신속한 대응을 위해  실시간 데이터 처리 및 검색 엔진 등이 필요할 수도

데이터의 가공

- 업무 시스템의 일부로 데이터 처리 결과를 이용하고 싶은 경우

- 목적이 명확하기 때문에, 필요한 데이터를 계획적으로 모아 데이터 파이프라인을 설계한다

- 꼼꼼한 테스트 반복적으로 실행한다

- 데이터 분석이라기보다는 시스템 개발 영역에 해당

데이터 시각화

- 앞으로의 상황을 예측해 의사 결정에 도움

 

- 데이터 분석 시스템은 원칙적으로 정보계 시스템

확증적 데이터 분석과 탐색적 데이터 분석

1-3. [속성 학습] 스크립트 언어에 의한 특별 분석과 데이터 프레임

- 스몰 데이터의 기술 잘 사용하기: 스몰 데이터에는 스몰 데이터 기술을 사용하는 것이 효율적이므로 무리하게 빅데이터 기술을 사용할 필요가 없다

1-4. BI 도구와 모니터링

스프레드시트에 의한 모니터링

데이터에 근거한 의사 결정

월간 보고서

스프레드 시트 장점: 수작업으로 숫자 입력하는 정도는 유연성 있음 -> 섣불리 시스템화 하면 나중에 손보는게 어려워짐

단점 1. 보고서에 입력하는 숫자를 어디선가 계산해야 함 - 이를 위해 준비된 것이 데이터 웨어하우스, 배치 처리, 워크플로 관리

단점 2. 상세한 내역을 조사하기 어려움 - 별도 BI 도구가 필요

 

 

변화를 파악하고 세부 사항 이해하기 - BI 도구의 활용

- BI 도구는 고속의 집계 엔진을 내장하고 있어 수백만 레코드 정도의 스몰 데이터라면 순식간에 그래프를 그려줌

모니터링의 기본 전략 및 BI 도구

- BI 도구는 자신이 직접 데이터를 살펴보기 위해서 필요

 

수작업과 자동화해야할 것의 경계 판별하기

- BI 도구를 활용하려면 베이스가 되는 데이터가 준비되어야 한다 (데이터 설계의 필요성)

 

수작업으로 할 수 있는 것은 수작업으로 해두기

- BI 도구를 위한 새로운 테이블을 설계부터 시작하기보다는 한 달에 한 번씩 수동으로 하는 것이 더 쉬울 것

 

 

자동화하려는 경우에는 데이터 마트를 만든다

가장 범용성이 높은 방법: 데이터 마트를 준비하고, 그것을 BI 도구로부터 열기

 

 

python을 처음 공부한 이래, 가상환경을 세팅하는 방법으로 conda밖에 없는 줄 알았다.

하지만 그동안 conda로 가상환경을 세팅하면서 자잘한 버그들로 불편했는데 (특히 MacOS M1과의 호환성이 정말 별로였다.)

다음 두 가지 큰 이유로 이번 기회에 다른 방식으로 넘어가게 되었다.

1. langchain 관련 dependency 문제:

- 우선 conda에 langchain 생태계가 없어서 pip로 일일히 다운받아야 했는데, dependency를 챙기는게 꽤나 번거로웠다.

- conda로 가상환경을 세팅하는 장점을 전혀 누릴 수가 없었다.

 

2. poetry를 통한 개발환경 세팅시 원인 모를 에러 거듭 발생

- 이번에 data platform팀 환경 위에 python 개발할 일이 있었는데, 로컬에서 pyspark을 실행하기 위한 가이드대로 해도 계속 에러가 났다.

- python version과 whl 파일 간의 충돌이 계속 발생했는데 아무리 구글링해도 해결되지 않았다.

- 찾아보니 conda 자체가 data science 분야에만 특화되어있기도 하고, 개발 환경에는 적합하지 않은 것 같아 로컬에 설치된 conda를 전부 제거하고 pyenv로 갈아타게되었다.

- conda를 쓰면 안되는 이유가 설명된 블로그: https://devbull.xyz/python-create-environment/ 

 

넘어가면서 거의 몇 시간을 삽질했기 때문에, 까먹지 않고자 남겨두고자 한다.

 

결론

- brew -> pyenv -> pipx -> poetry 순서로 삭제했다 재설치

- conda는 아예 삭제

 

1. python 가상환경은 왜 필요한가?

- python도 일종의 실행가능한 프로그램이다.

- 여러 library들이 이 프로그램에서 사용될 수 있도록 개발되는데, library들끼리 서로 가져다쓰기 때문에 dependency라는게 생긴다.

- 예를 들어 library B가 python 3.8에서 사용할 수 있도록 개발되고 library A의 ver 1을 사용한다고 하자.

- 만약 library A의 ver 2가 배포됐을 때, 사용자는 무턱되고 A, B의 최신 버전을 사용할 수가 없다.

- 아직 B는 A의 ver 1을 사용하고 있기 때문에 B를 설치하면서 A의 ver 1을 함께 설치해줘야 한다.

- 만약 다른 python 프로젝트에서 library C를 사용하고 이 C는 library A의 ver 2를 사용한다면?

- 이런 골치아픈 dependency 문제를 해결하기 위해 각각의 프로젝트마다 가상환경을 세팅한다.

- 그리고 이 가상환경마다 dependency 충돌이 안 일어나도록 일정의 config를 설정해둔다. 

    - poetry가 이런 솔루션 중 하나인데, 복잡한 사용법을 익혀야 한다.

    - 단순하게는 requirements.txt 파일을 만들어서 해당 프로젝트에 필요한 library들과 version을 관리한다.

 

2. pyenv

- 가상환경을 세팅하는 여러 툴이 있다.

- venv, virtualenv, pyenv, conda

- 각 장단점은 검색하거나 ChatGPT에 물어보면 잘 알 수 있으니 생략하고,

- 결론적으로 pyenv로 가상환경을 세팅하기로 했다.

- pyenv는 여러 명령어를 제공한다. (참고: https://shawn-dev.oopy.io/fe911cba-0b25-474c-9c3c-d18fd945c8b0)

- 가장 편하게 느껴진 점은 이것

    - python을 여러 버전으로 설치할 수 있다. (3.9, 3.10, 3.11)

    - 가상환경을 만들 때 설치한 python으로 세팅할 수 있고, 가상환경을 활성화 하는 것도 쉽다 (pyenv activate {가상환경 이름})

    - (핵심) python이 설치된 경로를 복잡하게 챙길 필요가 없다.

 

3. 원인 모를 문제들

- .whl 파일이 os가 지원하는 것과 다른 library가 요구하는 게 다르다는 에러가 거듭 났었다.

- 결국 해결 못해서 brew를 아예 삭제하고 다시 설치하니 해결되었다.

- 이 과정에서 conda로 설치한 python 경로와 pyenv로 설치한 python 경로가 매우 복잡하게 되어있는 것을 보고 한쪽으로 정리해야겠다고 결심했다.

- conda는 아예 삭제해버리고, pyenv도 삭제했다가 다시 설치했다.

+ Recent posts