파티셔닝

파티셔닝 (Partitioning)

파티셔닝은 데이터를 쓸 때 비슷한 행을 함께 묶어서 쿼리를 더 빠르게 만드는 방법이에요. 이 문서에서는 파티셔닝의 기본 개념을 하이브와 비교하면서, 아이스버그의 숨겨진 파티셔닝(hidden partitioning)이 왜 더 나은지 설명해드릴게요. 핵심은 사용자가 파티션 값을 직접 만들고 관리할 필요 없이 아이스버그가 자동으로 처리한다는 점이에요.

출처: 문서

본문

파티셔닝이란 무엇인가요? (What is partitioning?)

파티셔닝은 데이터를 쓸 때 비슷한 행을 함께 묶어서 쿼리를 더 빠르게 만드는 방법이에요.

예를 들어 logs 테이블의 로그 항목을 찾는 쿼리는 보통 시간 범위를 포함해요. 아래는 오전 10시부터 12시 사이 로그를 찾는 쿼리예요.

SELECT level, message FROM logs
WHERE event_time BETWEEN '2018-12-01 10:00:00' AND '2018-12-01 12:00:00';

logs 테이블을 event_time의 날짜 기준으로 파티셔닝하도록 설정하면, 로그 이벤트를 같은 이벤트 날짜를 가진 파일들로 묶어요. 아이스버그는 그 날짜를 추적하고, 유용한 데이터가 없는 다른 날짜의 파일은 건너뛰는 데 이 정보를 사용해요.

아이스버그는 타임스탬프를 연(year), 월(month), 일(day), 시(hour) 단위로 파티셔닝할 수 있어요. 또한 이 logs 예시의 level처럼 범주형(categorical) 컬럼을 사용해서 행을 함께 저장하고 쿼리를 빠르게 할 수도 있어요.

아이스버그는 무엇을 다르게 하나요? (What does Iceberg do differently?)

하이브 같은 다른 테이블 포맷도 파티셔닝을 지원하지만, 아이스버그는 숨겨진 파티셔닝(hidden partitioning)을 지원해요.

  • 아이스버그는 테이블의 행에 대한 파티션 값을 만드는 지루하고 실수하기 쉬운 작업을 처리해요.
  • 아이스버그는 불필요한 파티션 읽기를 자동으로 피해요. 사용자는 테이블이 어떻게 파티셔닝됐는지 알 필요도 없고, 쿼리에 추가 필터를 넣을 필요도 없어요.
  • 아이스버그 파티션 레이아웃은 필요에 따라 진화할 수 있어요.

하이브에서의 파티셔닝 (Partitioning in Hive)

차이점을 보여주기 위해 하이브가 logs 테이블을 어떻게 다루는지 생각해볼게요.

하이브에서 파티션은 명시적이고 컬럼으로 나타나요. 그래서 logs 테이블에는 event_date라는 컬럼이 있어요. 데이터를 쓸 때 insert는 event_date 컬럼의 데이터를 제공해야 해요.

INSERT INTO logs PARTITION (event_date)
  SELECT level, message, event_time, format_time(event_time, 'YYYY-MM-dd')
  FROM unstructured_log_source;

마찬가지로 logs 테이블을 검색하는 쿼리에는 event_time 필터 외에도 event_date 필터가 있어야 해요.

SELECT level, count(1) as count FROM logs
WHERE event_time BETWEEN '2018-12-01 10:00:00' AND '2018-12-01 12:00:00'
  AND event_date = '2018-12-01';

event_date 필터가 빠지면, 하이브는 event_time 컬럼이 event_date 컬럼과 관련이 있다는 걸 모르기 때문에 테이블의 모든 파일을 스캔해야 해요.

하이브 파티셔닝의 문제점 (Problems with Hive partitioning)

하이브는 파티션 값을 직접 받아야 해요. logs 예시에서 하이브는 event_time과 event_date 사이의 관계를 알지 못해요.

이로 인해 여러 문제가 생겨요.

  • 하이브는 파티션 값을 검증할 수 없어요 — 올바른 값을 만드는 것은 작성자의 몫이에요. 20181201 대신 2018-12-01처럼 잘못된 형식을 사용하면 쿼리 실패가 아니라 조용히 잘못된 결과를 만들어요. processing_time 같은 잘못된 소스 컬럼이나 시간대를 사용해도 실패가 아니라 잘못된 결과를 만들어요.
  • 쿼리를 올바르게 작성하는 것은 사용자의 몫이에요. 잘못된 형식은 조용히 잘못된 결과를 만들고, 테이블의 물리적 레이아웃을 이해하지 못한 사용자는 불필요하게 느린 쿼리를 받게 돼요 — 하이브는 필터를 자동으로 변환할 수 없어요.
  • 동작하는 쿼리가 테이블의 파티셔닝 스킴에 묶여 있어서, 파티셔닝 설정을 바꾸면 쿼리가 깨질 수 있어요.

아이스버그의 숨겨진 파티셔닝 (Iceberg's hidden partitioning)

아이스버그는 컬럼 값을 가져와 선택적으로 변환해서 파티션 값을 만들어요. 아이스버그가 event_time을 event_date로 변환하는 일을 담당하고, 그 관계를 계속 추적해요.

테이블 파티셔닝은 이런 관계들을 사용해 구성돼요. logs 테이블은 day(event_time)와 level로 파티셔닝돼요.

아이스버그는 사용자가 유지 관리하는 파티션 컬럼을 요구하지 않기 때문에 파티셔닝을 숨길 수 있어요. 파티션 값은 매번 올바르게 만들어지고, 가능할 때마다 항상 쿼리 속도를 높이는 데 사용돼요. 생산자와 소비자는 event_date를 아예 보지 못해요.

가장 중요한 것은, 쿼리가 더 이상 테이블의 물리적 레이아웃에 의존하지 않는다는 점이에요. 물리적 레이아웃과 논리적 레이아웃이 분리되면서, 아이스버그 테이블은 데이터 볼륨이 변함에 따라 파티션 스킴을 시간이 지나며 진화시킬 수 있어요. 잘못 구성된 테이블도 값비싼 마이그레이션 없이 고칠 수 있어요.

지원되는 모든 숨겨진 파티션 변환에 대한 자세한 내용은 파티션 변환(Partition Transforms) 섹션을 확인해주세요.

테이블의 파티션 스펙을 업데이트하는 방법에 대한 자세한 내용은 파티션 진화(partition evolution) 섹션을 확인해주세요.

더 알아보기 (Learn more)