
시작하며
3장은 데이터 마트를 구축하는 파이프라인을 분산 처리의 관점으로 살펴본다. 크게 보면 1) 분산 스토리지에 저장된 데이터를 구조화, 2) 열 지향 스토리지 형식으로 저장, 3) 완성한 구조화 데이터를 결합·집계하여 데이터 마트(비정규) 생성, 4) 배치 혹은 애드 훅 등 상황에 맞는 쿼리 엔진으로 질의 의 순서로 이루어진다. 이 과정에서 핵심이 될 만한 내용 3가지를 추려보면 다음과 같다.
- 비구조화 데이터를 가공하는 과정
- 상황에 맞는 쿼리 엔진
- 데이터 마트를 구축하기까지
1. 비구조화 데이터를 가공해보자
책에서 나온 구조화 데이터 라는 용어는 보통 정형 데이터로, 비구조화 데이터는 비정형 데이터로 자주 표현한다. 영어로도 structured, unstructured로 표현하기 때문에 책에 나온 표현 그대로를 사용한다.
먼저 구조화 데이터와 비구조화 데이터는 다음과 같이 정의된다.
- 구조화 데이터(‘structured data’) : 스키마가 명확하게 정의된 데이터
- 비구조화 데이터(‘unstructured data’) : 스키마가 없는 데이터. 텍스트, 미디어 데이터
- 반구조화 데이터(‘Semi-structured data’) : 데이터의 서식은 정해져 있으나 칼럼 수, 데이터형 등이 고정되지 않은 채 저장되는 데이터. JSON, XML 등
Info
스키마리스 데이터란 미리 정의된 스키마(데이터베이스에서 데이터의 구조, 타입, 관계 등을 명시하는 것) 없이도 저장할 수 있는 데이터를 의미한다.
현실 세계의 대부분의 데이터는 처음에 이 비구조화 데이터(비정형 데이터) 모양으로 존재하는데, 이 상태 그대로는 집계 처리가 불가능하다. 따라서 앞으로 소개될 여러 소프트웨어들은 이 비구조화 데이터를 분산 스토리지 등에 저장하여 분산 시스템에서 처리·가공하는 과정이 필수적으로 선행되어야 하며, 이때 스키마를 정의하고 구조화된 데이터로 변환한다. 특히 SQL 집계를 위해 구조화 데이터로 변환하는 과정에서는 데이터의 압축률을 높이기 위해 열 지향 스토리지로 저장한다.
이 열 지향 스토리지로 저장하는 방법은 두 가지가 있는데, 하나는 제품마다 미리 스토리지 형식이 고정되어 있는 MPP 데이터베이스를 사용하는 것이고, 다른 하나는 Hadoop 사용 시 사용자가 직접 열 지향 스토리지의 형식을 선택하고 쿼리 엔진으로 집계하는 방식이다.
Hadoop은 분산 파일 시스템인 HDFS(Hadoop Distributed File System), 리소스 관리자인 YARN(Yet Another Resource Negotiator), 분산 데이터 처리를 위한 MapReduce로 구성되어 있고, 이 외에 다양한 소프트웨어로 대체 혹은 조합하여 시스템을 구성한다. YARN은 가용 가능한 자원인 CPU와 메모리를 묶어 컨테이너(container)라는 단위로 관리하며 MapReduce 역시 컨테이너 상에서 동작한다. 이 MapReduce는 비구조화 데이터를 가공하는 데 적합하다.
Info
컬럼 기반(columnar) 스토리지 포맷
- Apache Parquet
- Apache Parquet은 Hadoop 생태계에서 널리 사용되는 오픈 소스 컬럼 기반 스토리지 포맷이다. Parquet은 복잡한 중첩 데이터 구조를 효율적으로 저장하고, 데이터 압축 및 인코딩 기능을 제공하여 스토리지 비용을 절감하고 쿼리 성능을 개선한다. Hadoop과 더불어 Apache Spark, Apache Impala, Apache Drill 등 다양한 데이터 처리 프레임워크와 호환된다.
- Apache ORC (Optimized Row Columnar)
- ORC는 Apache Hive 프로젝트에 의해 개발된 컬럼 기반의 데이터 스토리지 포맷이다. ORC는 높은 압축 비율과 효율적인 읽기 성능을 제공하며, 특히 Hive에서의 대규모 데이터 웨어하우스 작업에 최적화되어 있다.
- Avro
- Avro는 행 기반(row-oriented)과 컬럼 기반 스토리지 모두를 지원하는 데이터 직렬화 시스템이다. Avro는 스키마가 데이터와 함께 저장되어, 데이터가 어떻게 해석되어야 하는지 명확하게 한다.
- Apache CarbonData
- Apache CarbonData는 Hadoop 생태계를 위한 새로운 컬럼 기반 스토리지 포맷이다. CarbonData는 뛰어난 압축 기능과 인덱싱 메커니즘을 제공하여, 고성능의 인터랙티브 쿼리와 빠른 데이터 처리를 지원한다.
2. 쿼리 엔진도 상황에 맞게 써야 한다
반면 가공이 아닌 집계가 목적이라면, 집계를 위해 설계된 쿼리 엔진을 사용할 수 있다.
-
Apache Hive (여기서는 Hive on MR)
- 쿼리를 자동으로 MapReduce 프로그램으로 변환한다. 대량의 데이터를 배치 처리하기 위한 시스템으로, 한 번 실행하면 대량의 데이터를 읽지만 작은 프로그램을 실행하기에는 오버헤드가 너무 크기 때문에 시간이 걸리는 배치 처리에는 적합하나 애드 훅 쿼리를 여러 번 실행하는 데는 부적합하다.
- Hive On Tez : MR처럼 1회의 MapReduce 스테이지의 종료를 기다리지 않고, 처리가 끝난 데이터를 차례로 후속 처리에 전달함으로써 쿼리 전체의 실행 시간을 단축시킨다.
-
Apache Impala, Presto
- Hive를 고속화하는 방안이 아니라, 처음부터 대화형 쿼리 실행을 전문으로 하는 쿼리 엔진이다. Hive on MR, Tez는 장시간의 배치를 가정해 한정된 리소스를 유효하게 활용하도록 했지만, Impala & Presto는
순간 최대 속도를 내기 위해 모든 오버헤드가 제거되어 사용 가능한 리소스를 최대한 활용한다. MPP 데이터베이스처럼 가능한 많은 데이터를 병렬 처리함으로써 고속화를 구현한다.
- Hive를 고속화하는 방안이 아니라, 처음부터 대화형 쿼리 실행을 전문으로 하는 쿼리 엔진이다. Hive on MR, Tez는 장시간의 배치를 가정해 한정된 리소스를 유효하게 활용하도록 했지만, Impala & Presto는
-
Apache Spark
- Spark는 인메모리 형태의 고속 데이터 처리 프로젝트이다. 컴퓨터에서 취급 가능한 메모리의 양이 증가함에 따라
가능한 많은 데이터를 메모리상에 올려두고 사용하며, 중간에 비정상 종료되어 날아가더라도 다시 처리하면 된다는 개념을 가지고 있다. MapReduce를 대체하는 존재이며, SQL 실행을 위한 SparkSQL과 스트림 처리를 위한 Spark Streaming 기능이 처음부터 내포되어 있다.
- Spark는 인메모리 형태의 고속 데이터 처리 프로젝트이다. 컴퓨터에서 취급 가능한 메모리의 양이 증가함에 따라
책에서는 간단한 예제를 통해 Hive에 의한 구조화 데이터 작성부터 살펴본다. 예시를 통해 Presto 등 사용하려는 쿼리 엔진에 최적화된 형식으로 스토리지 포맷을 선택하며, 서브쿼리를 통해 팩트 테이블의 양을 줄이거나 데이터 편향을 고려한 쿼리의 예시를 보여준다.
hive>
## 예시1) ORC 형식으로 테이블 생성
CREATE TABLE access_log_orc STORED AS ORC AS
SELECT cast(time AS timestamp) time,
request,
status,
cast(bytes AS bigint) bytes
FROM access_log_csv
;
## 예시2) 보다 효율적인 쿼리
SELECT data, count(*) users
FROM(
# 최초에 중복을 없앤다.
SELECT DISTINCT data, user_id FROM access_log
) t
GROUP BY date
;책에서 소개된 내용을 토대로, 배치 목적의 Hive보다 대화형 쿼리 엔진인 Presto가 가진 장점은 다음과 같다.
- 쿼리 실행의 지연을 감소시키는 것을 목적으로 개발된 것이
대화형 쿼리 엔진이다. - Presto는 플러그인 가능한 스토리지 설계로, 전용 스토리지 없이도 다양한 데이터 소스에서 데이터를 읽어들인다.
- Hive에서 만든 구조화 데이터를 다시 재집계하는 목적에 적합하다.
- 특히 ORC 형식의 로드에 최적화되어 있으며, 스토리지가 열 지향 데이터 구조로 되어 있는 경우에 성능을 최대한으로 발휘할 수 있다.
- Presto는 SQL 실행에 특화되어 있고, 쿼리를 분석하여 나온 최적의 실행 계획을 생성하여 자바 바이트 코드로 변환한다. 변환된 바이트 코드는 Presto의 워커 노드에 배포되고, 런타임 시스템에 의해 기계 코드로 컴파일된다. 코드는 멀티스레드화되어 단일 머신에서 수백 태스크씩 병렬 수행이 가능하다.
- Presto는 Hive와 달리 쿼리의 실행 과정에서 디스크에 쓰기를 하지 않는다.
Presto는 점점 그 목적에 부합하는 형태로 진화해 왔고, 현재는 기존의 것을 리브랜딩한 Trino라는 솔루션이 많이 사용되고 있다.
3. 데이터 마트를 구축해보자
결국 이 모든 것은 데이터 마트를 구축하여 쓰기 위함이다. 데이터 마트를 구축하기 위한 구성요소를 요약하면 다음과 같다.
-
팩트 테이블만들기- 추가 : 새로운 데이터를 증분으로 추가하는 방법이다.
- 치환 : 과거의 데이터를 포함하여 테이블 전체를 다시 만드는 방법이다.
- 효율을 보면 추가가 압도적으로 유리하지만, 관리상의 이유로 테이블에 결손·중복 등이 발생할 소지가 있다. 이를 위해 테이블 파티셔닝을 사용하며, 1일 1회 혹은 1시간 1회로 새 파티션을 만들고, 이를 팩트 테이블에 붙여놓는 방식을 사용한다. 각 파티션은 매번 교체되며, 만약 이미 존재한다면 덮어쓴다.
-
집계 테이블만들기- 팩트 테이블을 요약한 테이블이며, 꼭 필요한 칼럼을 정하여 각 칼럼이 취하는 값의 범위인 카디널리티(cardinality)를 조정한다. 너무 많이 줄이면 정보 손실이 있을 수 있다.
-
마스터 테이블을 관리하는 방법- 스냅샷 테이블(snapshot table) : 정기적으로 마스터 테이블 전체를 통으로 저장한다.
- 이력 테이블(history table) : 변경 내용만을 저장한다.
-
비정규화 테이블 만들기
- 팩트 테이블과 디멘전 테이블을 결합하여 비정규화 테이블을 만든다.
정리하며
이번 장의 내용을 정리하면 다음과 같다.
- 비구조화 상태의 데이터를 구조화 상태로 변환하여 집계한다. 이를 위해 익숙한 Hadoop, Spark 등을 널리 이용한다.
- Hive는 디스크상에서 대량의 데이터를 처리하는 데 적합하며, Presto(Trino), Impala 등의 엔진은 메모리상에서 고속(대화형)으로 집계하는 데 적합하다.
- 데이터 마트는 팩트 테이블과 디멘전 테이블을 효율적으로 결합·집계하여 비정규화 테이블 형태로 만든다.
참고문헌
- [출처] 니시다 케이스케(Keisuke Nishida), ⌜빅데이터를 지탱하는 기술(BIG DATA WO SASAERU GIJUTSU)⌟, 장성두 옮김, 주식회사 제이펍
- https://pandio.com/difference-between-trino-and-prestodb/
- https://medium.com/@CodeDemon/columnar-file-format-for-big-data-analytics-25dd3ba01b63
- https://www.upsolver.com/blog/the-file-format-fundamentals-of-big-data
- https://jsonobject.tistory.com/564