빅데이터를 지탱하는 기술 - 3장

Jajuna_99·2023년 2월 6일
0

3장 빅데이터의 분산 처리

분산 시스템의 대표적인 프레임워크인 Hadoop & Spark를 이용한 데이터 처리를 설명한다.

3-1 대규모 분산 처리의 프레임워크

스키마(schema) : 테이블의 칼럼 명과 데이터형, 테이블 간의 관계를 스키마로 정한다.
구조화된 데이터(structured data) : 스키마가 명확하게 정의된 데이터
비구조화된 데이터(unstructured data) : 스키마가 없는 데이터 ( 텍스트, 이비지, 동영상 등)

비구조화 데이터를 분산 스토리지 등에 저장하고 그것을 분산 시스템에서 처리하는 것이 데이터 레이크의 개념이다.

데이터를 가공하는 과정에서 스키마를 정의하고, 구조화된 데이터로 변환함으로써 다른 데이터처럼 분석이 가능하다.

  • 스키마리스 데이터(schemaless data)
    서식은 정해져 있지만, 칼럼 수나 데이터형은 명확하지 않은 데이터들
    ex) CSV, JSON, XML 등

    몇몇 NoSQL 데이터베이스는 스키마리스 데이터에 대응하고 있으며, 데이터 레이크에서는 대량으로 축적된 스키마리스 데이터를 효율적으로 처리하도록 하는 요구도 종종 있다.

  • 데이터 구조화의 파이프라인
    분산 스토리지에 수집된 데이터는 명확한 스키마를 갖지 않는 것도 많으므로 그냥 그대로는 SQL로 집계할 수 없다. 따라서, 먼저 필요한 것은 스키마를 명확하게 한 테이블 형식의 '구조화 데이터'로 변환하는 것이다.

    구조화 데이터 중 시간에 따라 증가하는 데이터를 팩트 테이블
    그에 따른 부속 데이터를 디멘전 테이블로 취급한다.

  • 열 지향 스토리지의 작성
    MPP 데이터베이스의 경우, 제품에 따라 스토리지의 형식이 고정되어 있어 사용자가 그 상세를 몰라도 괜찮다.

    Hadoop에서는 사용자가 직접 열 지향 스토리지의 형식을 선택하고, 자신이 좋아하는 쿼리 엔진에서 그것을 집계할 수 있다.

    Hadoop에서 사용할 수 있는 열 지향 스토리지에는 몇 가지 종류가 있으며, 각각 특징이 다르다.

    종류로는 'Apache ORC', 'Apache Parquet' 등이 있다.

    비구조화 데이터를 읽어 들여 열 지향 스토리지로 변환하는 과정에서는 데이터의 가공 및 압축을 위해 많은 컴퓨터 리소스를 사용하는데, 이 때 Hadoop & Spark 등 분산 처리 프레임워크를 사용한다.

Hadoop
Hadoop은 단일 소프트웨어가 아니라 분산 시스템을 구성하는 다수의 소프트웨어로 이루어진 집합체다.

2013년에 배포된 Hadoop2부터 YARN이라고 불리는 새로운 리소스 관리자 상에서 복수의 분산 애플리케이션이 동작하는 구성으로 되어, 대규모 분산시스템을 구축하기 위한 공통 플래폼의 역할을 담당하고 있다.

  • 분산 파일 시스템과 리소스 관리자

    Hadoop의 기본 구성 요소 3가지

    • 분산 파일 시스템(distributed file system) -> HDFS(Hadoop Distributed File System)
    • 분산 데이터 처리(distributed data processing) -> YARN(Yet Another Resource Negotiator)
    • 분산 데이터 처리 기반 -> MapReduce3

모든 분산 시스템이 Hadoop의 의존하진 않는다.

Hadoop을 일부, 혹은 사용하지 않는 구성도 있다.
ex) HDFS를 사용하면서, 리소스 관리자는 Mesos, 분산 데이터 처리는 Spark 등 조합해서 사용

다양한 SW 중 선택해 조합함으로써 시스템을 구성하는 것이 Hadoop을 중심으로 하는 데이터 처리의 특징이다.

  • 분산 파일 시스템과 리소스 관리자

    Hadoop에서 처리되는 데이터는 HDFS에 저장된다. (파일 서버랑 같은 역할)
    다만, 다수의 컴퓨터에 파일을 저장해 중복성 up

    CPU나 메모리 등의 계산 리소스는 리소스 메니저인 YARN에 의해 관리한다.
    YARN은 리소스들을 컨테이너(container)라 불리는 단위로 관리한다.
    Hadoop을 실행하면 YARN이 클러스터 전체의 부하를 보고 비어 있는 호스트부터 컨테이너 할당한다.

YARN(리소스 관리자)는 애플리케이션 당 우선순위 및 리소스를 할당, 리소스 낭비 없이 데이터 처리를 하도록 한다.

  • 분산 데이터 처리 및 쿼리 엔진 (MapReduce, Hive)

    MapReduce도 YARN 상에서 동작하는 분산 애플리케이션 중 하나이고, 분산 시스템에서 데이터 처리를 실행하는데 사용된다.

    MapReduce는 임의의 자바 프로그램을 실행 시킬 수 있기 때문에 비구조화 데이터를 가공하는 데 적합하다.

    SQL 등의 쿼리 언어에 의한 데이터 집계가 목적이라면 그것을 위해 설계된 쿼리 엔진을 사용한다. ex) Apache Hive

    Hive는 쿼리를 자동으로 MapReduce 프로그램으로 변환하는 SW로 개발되었다. => MapReduce의 의존성 up

    이 둘의 단점은 둘다 대량의 데이터를 배치 처리하기 위한 시스템이기 때문에 작은 프로그램을 실행하려면 오버헤드가 커서 작은 프로그램(쿼리 실행)에 적합하지 않다.

  • Hive on Tez

    Hive를 속도 한계를 극복하고자 Apache Tez가 개발됐다. 초기에는 MapReduce를 대체할 목적으로 개발된 프로젝트이고, MapReduce에 몇 가지 단점을 해소함으로써 고속화를 실현하고 있다.

    Tez에서는 스테이지의 종료를 기다리지 않고 처리가 끝난 데이터를 차례대로 후속 처리에 전달함으로써 쿼리 전체의 실행 시간을 단축한다.

    현재의 Hive는 MapReduce뿐만 아니라 Tez를 사용해도 동작하게 재작성되어 있어 이를 'Hive on Tez'라고 한다.

  • 대화형 쿼리 엔진 (Impala & Presto)

    Hive를 고속화하는 것이 아닌 처음부터 대화형의 쿼리 실행만 전문으로 하는 퀴리 엔진도 개발되고 있다. 그 중 'Apache Impala'와 'Presto'가 대표적이다.

    Hadoop에서는 이와 같이 성질이 다른 쿼리 엔진을 목적에 따라 구분한다. 대량의 비구조화 데이터를 가공하는 무거운 배치 처리에는 높은 처리량으로 리소스를 활용하는 Hive를, 완성한 구조화 데이터를 대화식으로 집계하고자 할 때는 지연이 적은 Impala, Presto를 사용한다.

    Hadoop에서는 다수의 쿼리 엔진이 개발되어 있ㅇ며, 그걸들을 총칭해 'SQL-on-Hadoop'이라고 한다.

Spark

Apache Spark 또한 MapReduce보다 더 효율적인 데이터 처리를 실현하는 프로젝트로 개발이 진행되고 있다. Hadoop의 연장선 상에 있는 Tez와는 달리 Spark는 Hadoop과는 다른 독립된 프로젝트다.

컴퓨터에서 취급하는 메모리의 양이 증가함에 따라 뭐든지 디스크에서 읽고 쓰는 것이 아닌 (Hadoop과 Tez 처럼) '가능한 한 많은 데이터를 메모리상에 올린 상태로 디스크에는 아무것도 기록하지 않는다'가 가능해졌다.

이렇게 대량의 메모리를 활용하여 고속화를 하는 것이 Spark의 특징이다.

  • MapReduce 대체하기

    Spark는 Hadoop을 대체하는 것이 아닌 MapReduce를 대체하는 존재이다. ex) HDFS나 YARN 등은 Spark에서도 사용 할 수 있다.

    Hadoop을 이용하지 않는 구조도 가능하고 분산 스토리지 Amazon S3나 분산 데이터베이스인 카산드라에서 데이터를 읽어 들이는 것도 가능하다. 또한, Spark 상에서 실행되는 데이터 처리는 스크립트 언어를 사용할 수 있다.

    Spark에서는 SQL로 쿼리를 실행하기 위한 Spark SQL과 스트림 처리를 위한 Spark Streaming이라는 기능이 포함되어 있다. => 대규모 처리 + SQL에 의한 대화형 쿼리 실행, 실시간 스트림 처리 까지 이용될 수 있다.

3-2 쿼리 엔진

데이터 마트 구축의 파이프라인

이번 절에서는 위에서 설명한 아래 사진의 파이프라인 구조를 자세히 설명한다.

우선, 분산 스토리지에 저장된 데이터를 구조화하고 열 지향 스토리지 형식으로 저장한다. 이것은 다수의 비정규화 데이터를 읽어 들여 가공하는 작업으로 Hive를 사용한다.

그리고 완성한 구조화 데이터를 결합, 집계하고 비정규호 테이블로 데이터 마트에 써서 내보낸다. 열 지향 스토리지를 이용한 쿼리의 싱행에는 Presto를 사용함으로써 실행 시간을 단축할 수 있다.

Hive에서 만든 각 테이블의 정보는 Hive 메타 스토어라고 불리는 특별한 DB에 저장된다. 이것은 Hive뿐만 아니라 다른 SQL-on-Hadoop의 쿼리 엔진에서도 공통의 테이블 정보로 참고 된다.

Hive에 의한 구조화 데이터 작성

  • 열 지향 스토리지의 변환

데이터 집계에 걸리는 시간이 오래 걸려 열 지향으로 변환해야겠다.

본 책에서는 열 지향 스토리지 형식인 ORC 형식으로 변환한다. Hive의 경우, 테이블마다 스토리지 형식을 저장할 수 있다. 다음과 같이 새로운 테이블을 만들고, 외부 테이블에서 읽은 데이터를 모두 저장한다.

ORC 형식으로의 변환에는 시간이 다소 걸리지만, 변환 후의 테이블 집계는 8 -> 1.5초 까지 단축 된다. 파일 크기도 원래 데이터의 비해 1/10이하로 줄어들었다.

  • Hive로 비정규화 테이블 작성하기

데이터가 구조화 됐으니 데이터 마트 구축 차례다. 즉, 테이블을 결합 및 집약해서 '비정규화 테이블'을 만든다.

이때 Presto 같은 대화형 쿼리 엔진을 사용할 것인지, Hive 같은 배치형 쿼리 엔진을 사용할 것인지에 따라 생각이 달라진다.

  • 서브 쿼리 안에서 레코드 수 줄이기

Hive 쿼리는 SQL과 유사하지만, DB가 아닌 데이터 처리를 위한 배치 처리 구조다. 즉, 읽어 들이는 데이터의 양을 의식하면서 쿼리를 작성하지 않으면 생각한 만큼의 성능이 나오지 않아 고민하게 된다.

책에서는 예제로 팩트 테이블을 작게 해야될 이유를 실습으로 증명해준다. (p.106) 기본적으로는 서브 쿼리 안에서 팩트 테이블을 작게 하는 것이 중요하다.

  • 데이터 편향 피하기
    데이터의 편차(data skew) 또한 분산 시스템에서의 고속화를 방해하는 요소이다.

예를 들어 하루 단위로 데이터를 분할 했을 때 데이터 양이 균등하지 않다면 SQL 실행 속도가 느려지게 된다.

중복이 없는 값을 세려면, 데이터를 한 곳에 모아야해서 분산 처리하기가 여려워지기 때문이다.

대부분의 쿼리 엔진에는 '모범 사례'와 '쿼리 최적화' 문서가 준비되어 있으니 시스템 사용 전, 중에는 읽어서 문제를 방지해보자.

대화형 쿼리 엔진 Presto의 구조

대화형 쿼리 엔진 : 쿼리 실행의 지연을 감소시키는 것을 목적으로 개발된 구조. 작은 쿼리를 여러 번 실행하는 대화형 데이터 처리에 적합하다.

Dremel : Google BigQuery의 핵심 기술로 수천 대의 컴퓨터에 분산된 열 지향 스토리지를 사용하여 집계를 가속화한다. 해당 분야에서 자주 참고되는 기술이다.

현재는 Hadoop과 함께 사용할 수 있는 유사 SW(대화형 쿼리 엔진)가 많이 개발되고 있으며, Hive를 대체하는 대화형 쿼리 엔진으로 이용되고 있다.

  • 플러그인 가능한 스토리지

Presto의 특징은 '플러그인 가능한 스토리 설계'다. 일반적인 MPP DB에서는 스토리지와 컴퓨팅 노드가 밀접하게 결합되어 있어 처음에 데이터를 로드하지 않으면 집계를 시작할 수 없다.

반면에, Presto는 전용 스토리지를 갖고 있지 않으므로 Hive와 마찬가지로 다양한 데이터 소스에서 직접 데이터를 읽어들인다.

Presto는 Hive 메타 스토어에 등록된 테이블을 가져올 수 있다.

즉, Hive에서 만든 구조화 데이터를 좀 더 집계하는 등의 목적에 적합하다. Presto의 성능을 최대로 발휘하려면 원래 스토리가 열 지향 데이터 구조로 되어 있어야 한다.

특히, ORC 형식의 로드에 최적화되어 있으며, 그것을 확장성이 높은 분산 스토리지에 배치하여 최대의 성능을 발휘한다. 데이터의 로딩 속도를 높이려면 Presto 클러스터를 분산 스토리지와 네트워크의 가까운 곳에 설치한 곳에 설치한 후에 그것들을 가능한 한 고속 네트워크에 연결해야 한다.

  • CPU 처리의 최적화

Presto는 SQL의 실행에 특화된 시스템으로, 쿼리를 분석하여 최적의 실행 계획을 생성하고, 그것을 자바의 바이트 코드로 변환한다. 바이트 코드는 Presto의 워커 노드에 배포되고, 그것은 런타임 시스템에 의해 기계 코드로 컴파일된다.

코드의 실행은 멀티 스레드화되어 단일 머신에서 수백 태스크로 병렬 실행된다. 열 지향 스토리지에서의 읽기도 병렬화되어 데이터가 도달할 떄 마다 처리가 진행된다. 따라서, Presto의 CPU 이용 효율이 높으므로 메모리와 CPU 리소스만 충분하다면 데이터의 읽기 속도가 쿼리의 실행 시간을 결정하게 된다.

  • 인 메모리 처리에 의한 고속화

Presto는 쿼리 실행 과정에서 디스크에 쓰기를 하지 않는다. 모든 데이터 처리를 메모리상에서 실시하고 메모리가 부족하면 여유가 생길때까지 기다리거나 오류로 처리한다.

여러 컴퓨터를 나열해서 메모리 리소스 증가 또한 어렵지 않게 되었다.

메모리상에서 실행할 수 있는 실행은 메모리에서 하고 대량의 데이터는 Hive에 맡기는 방식을 애용하자.

  • 분산 결합과 브로드캐스트 결합

테이블의 결합은 대량의 메모리를 소비한다. (특히 2개의 팩트 테이블을 결합하는 경우에는 매우 많은 조인 키를 메모리상에 계속 유지해야 한다.)

Presto는 기본적으로 분산 결합을 실시, 같은 키를 갖는 데이터는 동일한 노드에 모인다.

분산 결합에서는 노드 간의 데이토 전송을 위한 네트워크 통신이 발생, 쿼리의 지연을 초래한다. 한쪽 테이블이 충분히 작은 경우에는 브로드캐스트 결합을 사용하여 처리 속도를 고속화할 수 있다.

  • 열 지향 스토리지 집계

위와 같은 구조에 의해 Presto에서는 열 지향 스토리지의 집계를 매우 빠르게 실행할 수 있다.

실제로 책에서 실습 내용을 보면 ORC 형식의 테이블을 로드해보면, 수백만 레코드 정도의 데이터양인 경우 1초 미만으로 집계할 수 있음을 확인할 수 있다.

데이터 분석의 프레임워크 선택하기

  • MPP 데이터베이스

시각화를 위한 데이터 마트로 생각하면, MPP DB는 유력한 대안이다. BI 도구와 MPP DB와의 조합에는 오랜 실적이 있기에 완성한 비정규화 테이블을 고속으로 집계하는 데에 최적이다.

  • Hive

텍스트 데이터를 가공하거나 열 지향 스토리지를 만드는 등의 무거운 처리는 아무래도 처리 시간이 길어지는 경향이 있어 Hive에서 실행하는 것이 적합하다.

Tez 덕에 대화형 쿼리에서도 사용되었다. Hive는 데이터양에 좌우되지 않는 쿼리 엔진으로 계속 이용될 것으로 예상된다.

  • Presto

Presto의 쿼리는 단시간에 대량의 리소스를 소비하기 때문에 너무 무리하게 사용을 하면 다른 쿼리를 실행할 수 없다. 여러 단점이 있다만 속도가 중요하거나, 대화식으로 구조를 만들어야 하는 경우 Presto가 적합하겠다.

  • Spark

Spark는 인 메모리의 데이터 처리가 중심이며 Presto뿐만 아니라 대화형 쿼리 실행에도 적합하다. 그러나 Spark의 장점은 SQL이가리보다는 ETL 프로세스에서 SQL에 이르기까지의 일련의 흐름을 하나의 데이터 파이파라인으로 기술할 수 있다는 점이다.

Spark는 분산 시스템을 사용한 프로그래밍 환경이므로, 일단 사용법을 익혀두면 ETL 프로세스나 머신러닝 같은 모든 데이터 처리에 활용할 수 있다.

데이터 엔지니어 및 프로그래밍 기술이 높은 데이터 과학자에게 강력한 무기가 될 수 있겠다.

3-3 데이터 마트의 구축

팩트 테이블

팩트 테이블 작성에는 추가(append)와 치환(replace) 두 가지 방법이 있다.

추가는 새로 도착한 데이터만을 증분으로 추가한다.

치환은 과걱의 데이터를 포함하여 테이블 전체를 치환한다.

  • 테이블 파티셔닝

효율적인 면에서는 추가가 압도적으로 유리하다. 그러나 추가에는 다음과 같은 잠재적 문제들이 있다.

추가에 실패한 것을 알아채지 못하면 팩트 테이블의 일부에 결손이 발생한다.

추가를 잘못해서 여러 번 실행하면 팩트 테이블의 일부가 중복된다.
 
나중에 팩트 테이블을 다시 만들고 싶은 경우의 관리가 복잡해진다. 

위를 방지하기 위해 테이블 파티셔닝(table paririoning)을 사용한다.
-> 하나의 테이블을 여러 물리적인 파티션으로 나눔으로써 파티션 단위로 정리하여 데이터를 쓰거나 삭제할 수 있도록 한 것이다.

주기적으로 새 파티션을 만들고 그것을 팩트 테이블에 붙여 놓는다. 각 파티션은 매번 교체하도록 하고, 만약 이미 존재한다면 덮어쓴다. 그렇게 해서 데이터가 중복될 가능성을 배제하면서 필요하면서 필요에 따라 여러 번 데이터의 기록을 바로 잡을 수 있다.

  • 데이터 마트의 치환

데이터 마트를 만드는 경우에는 단순히 팩트 테이블을 치환하는 경우가 많을 수도 있겠다.

데이터 마트의 데이터양은 한정되어 있기 때문에, 테이블일 아주 크지 않다면 매번 치환하기 어렵지 않다. ex) 30일 동안의 데이터를 매일 꺼내 치환해 일일 보고서를 만드는 작업 등

집계 테이블

팩트 테이블을 어느 정도 모아서 집계하면 데이터의 양이 크게 줄어드는데, 이것을 집계 테이블(summary table)이라고 한다.

특히 데이터를 1일 단위로 집계하는 것을 일일 집계라고 하는데, 일일 보고서를 만드는 과정에서 자주 사용된다.

  • 일일 집계를 잘 만들면 원래의 데이터가 아무리 대량으로 있어도 데이터 마트는 그다지 커지지 않는다.

일일 집계 실습 (p.123)

스냅샷 테이블

마스터 데이터처럼 업데이트될 가능성이 있는 테이블에 대해서 두 가지 방안이 있다.

  1. 정기적으로 테이블을 통째로 저장하는 방법 => 스냅샷 테이블(snapshot table)

  2. 변경 내용만을 저장하는 방법 => 이력 테이블 (history table)

데이터 분석 방면을 생각하면 스냅샷 테이블이 취급하기 쉽다. 마스터 테이블의 레코드 수가 많다면 스냅샷 테이블은 거대해지지만, 이를 위해 빅데이터 기술이기 때문에 괜찮다.

스냅샷 테이블은 시간이 지남에 따라 점점 커지므로 이것도 일종의 팩트 테이블로 간주한다.

스냅샷 테이블은 다른 팩트 테이블과 결합함으로써 디멘젼 테이블로도 사용할 수 있다. 스냅샷의 날짜를 지정하여 과거의 마스터 테이블을 언제든지 볼 수 있다. (p.126)

이력 테이블

데이터의 양을 줄이는 데 도움이 되지만, 어느 순간의 완전한 마스터 테이블을 나중에 복원하는 것이 어려워지므로, 디멘전 테이블로는 사용하기 힘들다.

마스터 관계의 테이블은 기본적으로 매일 스냅샷 하는 것으로 생각하는 것이 좋다.

디멘전을 추가하여 비정규화 테이블 완성시키기

마지막 단계로 팩트 테이블과 디멘전 테이블을 결합하여 비정규화 테이블을 만든다.

디멘전 테이블로는 스냅샷을 사용할 뿐만 아니라 목적에 따라 각종 중간 테이블이 만들어 진다.

  • 데이터 집계의 기본형

먼저, 팩트 테이블에서 필요한 데이터를 꺼낸다. 이때 시간에 의한 검색이나 참고하는 칼럼 수를 줄임으로써 데이터의 로드 속도는 빨라진다. (p.129)

계속해서 그것을 디멘전 테이블과 결합하여 데이터 마트에 저장할 칼럼을 선택한다. 이때 가급적 카디널리티를 작게 하는 것이 중요하다. 세션 ID와 같이 다수의 값을 갖는 것을 출력에 포함하는 것은 피하고, 시각화에서 이용하고 싶은 디멘전만을 추가하도록 한다.

마지막으로 그룹화하여 측정값을 집계한다. 이제 충분히 작은 비정규화 테이블이 만들어졌다. 이 후, 그 결과를 데이터 마트 or CSV 파일로 저장하면 완료된다.

요약

데이터 마트를 구축하는 프로세스를 알아보기 위해 분산 시스템에 의한 데이터 처리의 기본적인 흐름을 알아봤다.

profile
Learning bunch, mostly computer and language

0개의 댓글