Apache Iceberg의 변형 타입: 셰딩이 지저분... 노트

Apache Iceberg의 변형 타입: 셰딩이 지저분한 JSON을 빠른 분석으로 바꾸는 방법

모든 데이터 엔지니어는 JSON 컬럼이 있는 테이블을 접하게 되는데, 이는 데이터 환경에서 유용하지만 고통스러운 부분입니다. 이러한 컬럼은 원시 데이터를 담고 있지만 문자열 파싱으로 인해 상당한 쿼리 성능 비용을 발생시킵니다. Apache Iceberg v3는 이를 해결하기 위해 Variant 타입을 도입하여, 거의 타입화된 컬럼 성능으로 JSON과 같은 유연성을 제공합니다. 이는 Shredding이라는 기법을 통해 달성됩니다.Variant 이전에는 두 가지 좋지 않은 옵션이 있었습니다. JSON을 문자열로 저장하는 것은 수집은 쉬웠지만, 모든 쿼리에 대해 전체 문자열을 파싱해야 했고 저장 공간이 방대했기 때문에 읽기 속도가 느렸습니다. 대안은 JSON을 타입화된 컬럼으로 평탄화하는 것이었는데, 이는 쿼리를 빠르게 만들었지만 스키마 불안정성과 빈번한 마이그레이션으로 인해 운영상의 고통을 야기했습니다. 많은 팀은 둘 다 유지하는 방법을 택했고, 새로운 정보 없이 복잡성만 더했습니다.Variant는 이러한 옵션들을 하나의 유연하고 빠른 컬럼으로 통합합니다. 이는 행마다 구조가 달라지는 값에 대한 데이터 타입으로, 객체, 배열, 그리고 날짜 및 십진수와 같은 기본 타입을 지원합니다. 결정적으로, Variant 값은 텍스트가 아닌 바이너리 인코딩으로 저장되며, 이는 Apache Parquet 표준을 활용합니다. 이 인코딩은 값을 메타데이터 섹션(필드 이름의 사전)과 값 섹션으로 분할하여 기본 타입을 효율적으로 저장하고 특정 필드로 직접 점프할 수 있도록 합니다.바이너리 인코딩은 문자열 저장보다 개선되었지만, Parquet가 Variant 값을 불투명한 블롭으로 보기 때문에 완전한 컬럼 성능을 달성하지는 못합니다. 이러한 불투명성은 컬럼 읽기, 압축 및 가지치기와 같은 중요한 최적화를 방해합니다. Shredding은 파일 형식에 내부 구조를 보이게 함으로써 이를 해결합니다.Shredding은 쓰기 시점에 엔진이 Variant 값 내에서 일관되게 나타나는 필드를 식별하고 이를 별도의 타입화된 Parquet 컬럼으로 저장하는 방식으로 작동합니다. 예를 들어, user_id 및 event_type과 같은 일반적인 필드는 자체 컬럼으로 추출되고, 덜 일반적이거나 다양한 필드는 잔여 바이너리 컬럼에 유지됩니다. 이는 일반 문서(송장, 라벨)를 별도로 보관하고 다른 항목은 원본 봉투에 보관하는 우편실 직원에 비유할 수 있습니다.기계적으로, Shredding은 각 일반 필드에 대해 typed_value와 value라는 두 개의 컬럼을 생성합니다. typed_value 컬럼은 필드가 예상되는 타입과 일치할 때 해당 필드를 보유하며, 모든 컬럼 최적화의 이점을 누립니다. value 컬럼은 예상되는 타입과 일치하지 않는 경우 필드를 바이너리 Variant 형태로 저장하는 대체 역할을 합니다. 이는 데이터 무결성을 보장하면서 일반 필드에 대한 쿼리를 극적으로 가속화합니다.