ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [빅데이터의 분산 처리] 2. 쿼리 엔진
    책/빅데이터를 지탱하는 기술 2022. 3. 29. 15:03
    반응형

    이 글은 빅데이터를 지탱하는 기술을 읽고 정리한 글입니다.


     

     

     

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


    Hive에 의한 구조화 데이터 생성과 Presto에 의한 대화식 쿼리에 대해 설명하기 위해 이 둘을 결합한 데이터 파이프라인을 만들었다고 가정한다.

    Hive의 역할

    - 아래 과정은 많은 데이터를 가공하기 때문에 배치형 쿼리 엔진인 Hive를 사용한다.

    1. 분산 스토리지에 저장된 데이터를 구조화한다.

    2. 구조화 데이터를 열 지향 스토리지 형식으로 저장한다.

     

     

    Presto의 역할

    - 열 지향 스토리지를 이용한 쿼리 실행에서는 SQL 쿼리 실행을 전문적으로 처리하는 대화형 쿼리 엔진인 Presto를 사용하여 시간을 단축한다.

    1. 구조화 데이터를 결합, 집계하고 비정규화 테이블로 데이터 마트에 써서 내보낸다. 


     

     

     

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


    외부 테이블

    - Hive의 외부에 있는 특정 파일을 참고해 마치 거기에 테이블이 존재하는 것처럼 읽어들이기 위해 지정

    - CREATE EXTERNAL TABLE을 사용하여 외부 테이블을 정의한다.

    - 대부분의 SQL-on_Hadoop의 쿼리 엔진은 MPP 데이터베이스처럼 데이터를 외부에서 텍스트 파일을 그대로 집계할 수 있다.

    * CSV 파일은 비효율적이기 때문에 열 지향 스토리지로 변환하는 것이 좋다.

     

     

    열 지향 스토리지로의 변환

    - Hive는 테이블마다 스토리지 형식으로 지정할 수 있다.

    - 데이터를 ORC 형식(열 지향 스토리지)으로 변환하면 파일 크기도 줄어들고, 속도도 매우 빨라진다.

    - Hive가 읽을 수 있는 형식이라면 쿼리를 사용하여 어떤 테이블이라도 만들 수 있다.

     

     

    비정규화 테이블 작성하기

    - 데이터 구조화를 완료하면 비정규화 테이블을 만들어야 하는데, 규모가 매우 크다면 리소스 이용 효율을 높이는 배치형 쿼리 엔진인 Hive를 사용한다. (참조)

    - 비정규화 테이블을 만드는데에는 오랜 시간이 걸리기 때문에 쿼리를 개선해야 한다. 대표적인 쿼리 개선은 '서브 쿼리 안에서 레코드 수 줄이기'와 '데이터 편향을 방지하는 방법'이 있다.

    * 이 두 방법은 빅데이터를 집계할 때 항상 의식해야 한다.


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

    초기 단계에서 팩트 테이블을 작게한다.

    SELECT ...
    FROM university u
    JOIN student s ON s.id = u.student_id
    WHERE s.birth_year >= 2000

    이런 SQL 쿼리가 있다고 하면 모든 데이터를 읽은 뒤에 JOIN에 있는 조건에 맞게 결합하고, WHERE에 의한 검색을 하게 된다.

    여기서 팩트 테이블은 university이고, 디멘젼 테이블은 student이니 모든 university 데이터를 읽은 뒤에 JOIN 조건에 맞게 student 데이터를 결합하고, WHERE 절에 의해 출력 데이터를 결정하게 된다. 이 경우 실행 속도가 매우 느리게 나온다.

     

    SELECT ...
    FROM (
    	SELECT * university
        WHERE student_birth_year >= 2000
    ) u
    JOIN students s ON s.id = u.student_id
    WHERE b.birth_year >= 2000

    그래서 이렇게 쿼리문은 좀 더 길지만, 서브 쿼리를 사용하여 학생의 출생연도가 2000년 이상인 데이터만 팩트 테이블로 가져오기 때문에 규모가 매우 큰 데이터의 경우에는 효과적으로 실행 속도를 줄일 수 있게 된다.

     

     

    데이터 편향 피하기

    SQL에서  중복을 제거하기 위해 distinct를 사용하는 경우, 데이터를 한 곳에 모아 처리를 해야해서 한 곳에 데이터가 집중되기 때문에 분산 처리가 어려워진다. 특히 테이블 결합과 ORDER BY로 정렬하는 경우에도 잘 발생한다.

    그래서 서브 쿼리를 만들어서 최초에 중복을 없애거나, 데이터가 균등하다면 GROUP BY문을 사용하여 그룹화시켜 분산 처리를 하게 만들어준다.

    * SQL 쿼리 실행 순서: FROM -> WHERE -> GROUP BY -> HAVING -> SELECT -> ORDER BY 

     

    SELECT date, COUNT(DISTINCT student_id) students
    FROM university GROUP BY date

    이런 쿼리가 있을 경우 hive의 여러 노드에 date별로 student_id를 모아 중복을 제거하고 있을 것이다. 이 경우 데이터 처리 속도가 느려지기 때문에 아래 쿼리처럼 서브 쿼리를 사용해 처음부터 중복을 제거하여 데이터를 집계하는 것이 더욱 효과적이다.

    SELECT date, COUNT(*) students
    FROM (
    	SELECT DISTINCT date, student_id FROM university
    ) t
    GROUP BY date

     

     

     

    3. 대화형 쿼리 엔진 Presto의 구조


    Presto에 대한 간단한 소개 - 링크

     

    플러그인 가능한 스토리지

    Presto는 전용 스토리지를 가지고 있지 않으므로 Hive와 마찬가지로 다양한 데이터 소스에서 직접 데이터를 읽어 들인다. 그래서 Hive 메타 스토어에 저장된 테이블을 가져오거나, NoSQL 데이터베이스에 저장된 데이터러를 집계하거나 등등의 일을 할 수 있다. 거기다가 Presto는 ORC 형식의 로드에 최적화되어 있어서 ORC 형식의 파일을 확장성이 높은 분산 스토리지에 배치하면 최대의 성능을 발휘할 수 있다.

     

     

    CPU 처리의 최적화

    Presto는 코드의 실행이 멀티 스레드화되어 단일 머신에서 수백 태스크나 병렬로 실행된다. 그래서 CPU 이용 효율이 높으므로 메모리와 CPU 리소스만 충분하다면 데이터의 읽기 속도가 쿼리의 실행 시간을 결정하게 된다. 하지만 쿼리가 실행되면 중간에 끼어들 수 없기 때문에 너무 큰 쿼리를 실행해서는 안된다.

     

    * Presto의 처리 순서

    (쿼리 분석) → (최적의 실행 계획을 생성) → (자바의 바이트 코드로 변환) → (Presto 워커 노드에 배포) → (런타임 시스템에 의해 기계 코드로 컴파일)

     

     

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

    Hive는 쿼리를 실행하면 디스크에 기록을 하지만, Presto는 쿼리를 실행해도 디스크에 기록을 하지 않는다. 그래서 디스크 기록이 필요한 대규모 배치 처리와 거대한 테이블끼리의 결합은 Hive에 맡기고, 나머지 단시간 쿼리 실행에는 Presto와 같은 대화형 쿼리 엔진을 사용하는 것이 효율적이다.

     

     

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

     

    테이블의 결합은 많은 조인 키를 메모리상에 계속 유지를 해야하는데, Presto에서는 같은 키를 갖는 데이터는 같은 노드에 모이게 하는 분산 결합을 실시한다.

     

    분산 결합에서는 노드 간 데이터 전송을 위한 네트워크 통신이 발생하기 때문에 한쪽 테이블이 작은 경우에는 해당 테이블의 데이터를 모든 노드에 복사해서 보내는 브로드캐스트 결합을 사용하여 처리 속도를 고속화한다.

     

     

    열 지향 스토리지 집계

    ORC 형식의 테이블을 사용하면 더욱 빠르게 데이터 집계가 가능하다.


     

     

     

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


    MPP 데이터베이스

    MPP 데이터베이스는 처음에 ETL 프로세스 등으로 데이터를 가져오기만 하면, 이후엔 SQL만으로 데이터 집계가 가능하다. 시각화를 위한 데이터 마트를 생각하거나 완성한 비정규화 테이블을 고속으로 집계하는 데에 MPP 데이터베이스를 사용하는 것은 최적의 방법이다.

     

    Hive

    대규모 배치 처리를 꾸준히 실행한다는 점에서 장점이 있어서 텍스트 데이터를 가공하거나, 열 지향 스토리지를 만드는 무겁고 오래 걸리는 작업은 Hive를 사용하는 것이 적합하다. 거기다가 Hive는 대화형 쿼리에서도 사용이 되었어서 데이터양에 좌우되지 않는 쿼리 엔진이라고 생각하면 된다.

     

    Presto

    Presto는 Hive와 다르게 속도에 치중한 쿼리 엔진으로 일상적인 데이터 분석을 위해 자주 사용하는 쿼리 엔진이다. 그리고 표준 SQL을 준수하고 있기 때문에 많은 데이터 스토어에 대응하고 있어서 모든 데이터를 SQL로 집계하기 위한 중심적인 존재가 될 수 있다.

    하지만 ETL 프로세스 및 데이터 구조화에 적합하지 않고, 거기다가 단시간에 대량의 리소스를 처리하기에도 적합하지 않다.

     

    Spark

    Spark는 인 메모리의 데이터 처리가 중심이기 때문에 Presto처럼 대화형 쿼리 실행에 적합하다. 그리고 ETL 프로세스에서 SQL에 이르기까지의 흐름을 하나의 데이터 파이프라인으로 기술할 수 있다는 큰 장점도 있다. (여기서는 Hive + Presto를 사용하지만, Spark는 Spark만으로 만들 수 있음)


    반응형

    댓글

Designed by Tistory.