ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Apache Iceberg] 아이스버그 테이블 최적화 - 파티셔닝
    개발지식 아카이브/Data - Iceberg 2025. 1. 15. 07:30

    Apache 아이스버그 테이블 최적화 - 파티셔닝 편

     
     
     
     


     
     

    파티셔닝

    전통적 파티셔닝

     
    특정 필드가 데이터 액세스 방법에 핵심적인 역할을 한다는 것을 알고 있다면 정렬을 넘어 파티셔닝을 시도할 수 있다.
    예를 들어 아래 그림은 데이터를, party라는 필드 값을 기준으로 파티셔닝을 한 것이다.
     
    party = blue 인 것들끼리, party = red 인 것들끼리, party = green... 각각 물리적으로 위치를 분리하여 모은 것이다.
    이렇게 파티셔닝하면, party 값에 따라 파일스캔범위를 극적으로 줄일 수 있다.
     

     
     
    기존의 파티셔닝에는 사실, 다음과 같은 불편한 점들도 있었다.
     

    • 쿼리 사용자는 테이블의 파티션 필드에 대한 사전 지식이 있어야 한다.
    • 버킷으로 분할하려면 레코드가 속한 버킷을 명시하는 추가 열을 만들어야 한다 (비록 이 칼럼이 사용자에게 유의미한 정보를 제공하지 못할지라도...)

     
     
     
    자, 예시로 이런 상황을 가정해보자...
    데이터 엔지니어 "난잘해"씨는 아이스버그로그 테이블을 만들고, YEAR, MONTH와 같은 파티션 필드들을 만들었다.
     
    그리고 여기에 또 파티셔닝에 익숙하지 않지만 뛰어난 데이터 분석가인 "잘몰라"씨가 있었다.
    "잘몰라"씨는 이 테이블의 파티셔닝 구조에 대해 잘 알지 못했고, 파티션을 사용하지 않는 다음과 같은 쿼리를 작성하였다.
    "SELECT * FROM 아이스버그로그 WHERE created_at BETWEEN '2022-07-11 09:00:00' AND '2022-07-13 08:59:59';"
     
    .
    .
    물론 이 테이블을 설계한 "난잘해"씨라면 
    "SELECT * FROM 아이스버그로그 WHERE created_at BETWEEN '2022-07-11 09:00:00' AND '2022-07-13 08:59:59' AND year = '2022' AND month = '07';"
    이라고 작성하여, 파티션 프루닝이 일어나도록 의도하였을 것이다.
     
    .
    .
    우리는 기존 파티셔닝에 익숙하기 때문에, 조건 키워드에 파티션 필드를 꼭 넣어야 한다는 것에 내적 동의(?)를 하고 있다.
    하지만 조금 다른 관점으로 생각해 보면.... 어쩌면.... 쿼리의 직관적 가독성은, "잘몰라"씨가 작성한 것이 좀... 더 낫다고도... 볼 수 있지 않을까?...
     
     
     


     
     
     
     

    히든 파티셔닝


    아이스버그 개발자들은 "잘몰라"씨가 작성한 쿼리에 대해서도 쿼리의 성능을 보장하고 싶었다.
     
    그래서, 파티션 프루닝이 일어나는 로직 자체를 바꾸었다.

    • 전통 파티션 테이블: 파일이 물리적으로 배치된 방식에 의존하여 추적함
    • 아이스버그 테이블: 스냅샷 및 매니페스트 수준에서 파티션 값 범위를 추적함

     
    그리고, 내부에 쿼리 플랜에 쓸 수 있는 기본 템플릿들을 내장하였다.
    예를 들어 "잘몰라"씨가 작성한 쿼리도, created_at 필드가 ISO 타임스탬프 포맷을 따르기만 한다면, ICEBERG에 내장된 함수에 의해 자동 템플레이팅 되어, 쿼리 플랜 안에서 파티션 프루닝이 일어나게 될 수 있다.
     
     

     CREATE TABLE 아이스버그로그 (...) PARTITIONED BY months(created_at) USING iceberg;

     
     
    이는 다음과 같은 장점들을 아이스버그에 제공한다.

    • year, month, date와 같은 추가 칼럼을 생성할 필요가 없어져 데이터 파일에 저장하는 양이 줄어듬
    • 쿼리에서 복잡성이 제거되며, 더 쉽게 파티셔닝의 이점을 얻을 수 있음

     
     
     


     
     
     
     

    파티션 템플릿

     
    아이스버그에서 제공하는 템플릿 포맷은 다음과 같다.
     

    • year
      • year 파티션 생성

     

    • month
      • year / month 파티션 생성

     

    • day
      • year / month / day 파티션 생성

     

    • hour 
      • year / month / day / hour 파티션 생성
      • ex) CREATE TABLE 아이스버그로그 (...) PARTITIONED BY hours(created_at) USING iceberg;
        • 쿼리에 created_at 필드가 사용되면, 아이스버그의 히든 파티셔닝이 작동한다

     

    • truncate
      • 앞의 값을 잘라서 파티션으로 사용
      • ex) CREATE TABLE 아이스버그로그 (...) PARTITIONED BY truncate(name, 1) USING iceberg;
        • name="A", name="B', ...
        • 쿼리에 name 필드가 사용되면, 아이스버그의 히든 파티셔닝이 작동한다

     

    • bucket
      • 버킷의 목적: 높은 카디널리티(고유 값이 많음)가 있는 필드를 기준으로 파티셔닝 할 때에 사용 (해시함수로 분산)
      • ex) CREATE TABLE 아이스버그로그(...) PARTITIONED BY bucket(24, email_address) USING iceberg;
        • 쿼리에 email_address가 포함된 경우, 아이스버그의 히든 파티셔닝이 작동한다

     
     
     


     
     
     


    파티션 Evolution


    기존 파티셔닝에는 이러한 문제도 있었다.
    파티셔닝이, 디렉토리의 물리적 구조에 의존했기 때문에, 구조 변경시 전체 테이블을 다시 작성해야 하는 상황들이 생기기도 하였다. 
    하지만 Iceberg는 파티셔닝 정보를 메타데이터에서 얻기 때문에, 물리적 디렉토리 구조를 변경하지 않고도 새로운 파티셔닝을 추가할 수 있다.
    이러한 설계로 어떠한 장점을 얻을 수 있는 것일까?
     
    .
    .
     
    "난잘해"씨는 2023년, 아이스버그를 사용하여 다음과 같은 일별 파티셔닝 로그 테이블을 만들었다.
    CREATE TABLE LEGACY_LOG (...) PARTITIONED BY days(created_at) USING iceberg;
     
    그러나 그 이후, 로그 테이블에 들어오는 데이터의 양이 급격히 증가하기 시작했다. 시간이 많이 흐르자 SELECT 쿼리가 점점 느려졌다.
    그래서 "난잘해"씨는, 2025년 1월, ALTER 쿼리를 사용해, 파티셔닝을 시간별로 더욱 세분화 조정하였다.
    ALTER TABLE LEGACY_LOG ADD PARTITION FIELD hours(created_at);
     
     
    ALTER 쿼리가 적용된 이후부터는, 새 파티셔닝 정보에 의해 데이터가 생성되기 시작하였고, 2025년 데이터에 대한 쿼리 성능이 급격히 좋아졌다.
     
     
    일주일 후, "난잘해"씨는 분석팀으로부터 2024년 데이터 검색 성능도 개선시켜 달라는 요청을 받았다.
     
    "난잘해"씨는 2024년 데이터에 대해 sparkSQL rewriteDataFiles를 실행시켰다. Spark는 2024년 로그 데이터를 읽으며 새로운 파티셔닝 규칙(hours(created_at))에 따라 메타데이터를 재작성하기 시작했다. 기존 데이터 파일들은 병합이 필요 없을 정도로 크기가 적절하였기에, 대부분은 물리적으로 이동되지 않았고 일부 데이터 파일만 새로 작성되었다. 그리고 새로운 메타데이터 파일들이 생성되어, Hour 단위로 재정렬된 파일 로케이션 정보가 스냅샷에 기록되었다.
     
    이 태스크가 완료되자, 분석팀의 쿼리 사용자들은 24년도 데이터 역시 검색 성능이 개선되었다고 말하며 몹시 기뻐했다.
    .
    .
     
     
    만약 "난잘해"씨가 전통적인 Hive를 사용하여 로그 테이블을 만들었었다면...?
    "난잘해"씨는 새로운 스키마에 대해 테이블을 새로 생성하고, 데이터를 다시 로드하는 복잡한 작업을 했어야 했을 것이다.
    왜냐하면 전통적인 구조에서는 파티셔닝 스키마를 테이블 생성 시 정의하며, 테이블이 생성된 이후에는 기존 파티셔닝 스키마를 변경할 수 없기 때문이다.
     
     
     
     


    Reference

    이 포스팅은 Apache Iceberg The Definitive Guide 4장의 내용에 기반하여 작성하였습니다.
     

     
     


    관련 포스팅 보기

     
    2025.01.13 - [개발지식 아카이브/Data - Iceberg] - [Apache Iceberg] 아이스버그 테이블 최적화 - 컴팩션과 정렬

    [Apache Iceberg] 아이스버그 테이블 최적화 - 컴팩션과 정렬

    Apache 아이스버그 테이블 최적화 - 컴팩션 편     성능 최적화의 핵심 = 읽는 파일 줄이기Apache 아이스버그 테이블의 데이터 성능 최적화의 핵심은 바로 스캔하는 파일의 개수를 줄이는 것이다

    gem1n1.tistory.com

     

    댓글

Copyright in 2020 (And Beyond)