이 저장소에는 Parquet 메타데이터를 읽고 쓰기 위한 Apache Parquet 및 Apache Thrift 정의에 대한 사양이 포함되어 있습니다.
Apache Parquet는 효율적인 데이터 저장 및 검색을 위해 설계된 오픈 소스 열 기반 데이터 파일 형식입니다. 복잡한 데이터를 대량으로 처리하기 위한 고성능 압축 및 인코딩 체계를 제공하며 많은 프로그래밍 언어 및 분석 도구에서 지원됩니다.
우리는 Hadoop 생태계의 모든 프로젝트에서 사용할 수 있는 압축되고 효율적인 열 형식 데이터 표현의 이점을 만들기 위해 Parquet을 만들었습니다.
Parquet은 처음부터 복잡한 중첩 데이터 구조를 염두에 두고 구축되었으며 Dremel 논문에 설명된 레코드 파쇄 및 조립 알고리즘을 사용합니다. 우리는 이 접근 방식이 중첩된 이름 공간을 단순하게 평탄화하는 것보다 우수하다고 믿습니다.
Parquet는 매우 효율적인 압축 및 인코딩 체계를 지원하도록 구축되었습니다. 여러 프로젝트에서 올바른 압축 및 인코딩 체계를 데이터에 적용하면 성능에 미치는 영향이 입증되었습니다. Parquet을 사용하면 열 단위 수준에서 압축 체계를 지정할 수 있으며, 개발 및 구현 시 더 많은 인코딩을 추가할 수 있도록 미래에도 대비됩니다.
쪽모이 세공은 누구나 사용할 수 있도록 만들어졌습니다. Hadoop 생태계는 데이터 처리 프레임워크가 풍부하므로 우리는 선호하는 플레이에 관심이 없습니다. 우리는 효율적이고 잘 구현된 컬럼형 스토리지 기판이 종속성을 설정하기 어렵고 비용이 많이 들지 않으면서 모든 프레임워크에 유용해야 한다고 믿습니다.
parquet-format
프로젝트에는 Parquet 파일을 올바르게 읽는 데 필요한 메타데이터의 형식 사양과 Thrift 정의가 포함되어 있습니다.
parquet-java
프로젝트에는 중첩된 열 지향 데이터 스트림을 읽고 쓰는 핵심 구성 요소를 구현하고, 이 코어를 parquet 형식에 매핑하고, Hadoop 입력/출력 형식, Pig 로더 및 기타 기능을 제공하는 여러 하위 모듈이 포함되어 있습니다. Parquet과 상호 작용하기 위한 Java 기반 유틸리티입니다.
parquet-compatibility
프로젝트에는 서로 다른 언어의 구현이 서로의 파일을 읽고 쓸 수 있는지 확인하는 데 사용할 수 있는 호환성 테스트가 포함되어 있습니다.
Java 리소스는 mvn package
사용하여 빌드할 수 있습니다. 현재 안정 버전은 항상 Maven Central에서 사용할 수 있습니다.
C++ 중고품 리소스는 make를 통해 생성될 수 있습니다.
Thrift는 다른 Thrift 지원 언어로 코드 생성될 수도 있습니다.
블록(HDFS 블록): HDFS의 블록을 의미하며 이 파일 형식을 설명하는 의미는 변함이 없습니다. 파일 형식은 HDFS 위에서 잘 작동하도록 설계되었습니다.
파일: 파일에 대한 메타데이터를 포함해야 하는 HDFS 파일입니다. 실제로 데이터를 포함할 필요는 없습니다.
행 그룹: 데이터를 행으로 논리적으로 수평 분할합니다. 행 그룹에 대해 보장되는 물리적 구조는 없습니다. 행 그룹은 데이터 세트의 각 열에 대한 열 청크로 구성됩니다.
열 청크: 특정 열에 대한 데이터 청크입니다. 이는 특정 행 그룹에 위치하며 파일에서 연속적으로 유지됩니다.
페이지: 열 청크가 페이지로 나뉩니다. 페이지는 개념적으로 분할할 수 없는 단위입니다(압축 및 인코딩 측면에서). 열 청크에 인터리브된 여러 페이지 유형이 있을 수 있습니다.
계층적으로 파일은 하나 이상의 행 그룹으로 구성됩니다. 행 그룹에는 열당 정확히 하나의 열 청크가 포함됩니다. 열 청크에는 하나 이상의 페이지가 포함됩니다.
형식을 이해하려면 이 파일과 Thrift 정의를 함께 읽어야 합니다.
4-byte magic number "PAR1"
<Column 1 Chunk 1>
<Column 2 Chunk 1>
...
<Column N Chunk 1>
<Column 1 Chunk 2>
<Column 2 Chunk 2>
...
<Column N Chunk 2>
...
<Column 1 Chunk M>
<Column 2 Chunk M>
...
<Column N Chunk M>
File Metadata
4-byte length in bytes of file metadata (little endian)
4-byte magic number "PAR1"
위의 예에서는 이 테이블에 N개의 열이 M개의 행 그룹으로 분할되어 있습니다. 파일 메타데이터에는 모든 열 청크 시작 위치의 위치가 포함됩니다. 메타데이터에 포함된 내용에 대한 자세한 내용은 Thrift 정의에서 확인할 수 있습니다.
파일 메타데이터는 단일 패스 쓰기를 허용하기 위해 데이터 뒤에 기록됩니다.
독자는 관심 있는 모든 열 청크를 찾기 위해 먼저 파일 메타데이터를 읽어야 합니다. 그런 다음 열 청크를 순차적으로 읽어야 합니다.
메타데이터에는 파일 메타데이터와 페이지 헤더 메타데이터라는 두 가지 유형이 있습니다. 모든 중고품 구조는 TCompactProtocol을 사용하여 직렬화됩니다.
파일 형식에서 지원되는 유형은 유형이 디스크 저장소에 미치는 영향에 중점을 두고 가능한 한 최소화되도록 고안되었습니다. 예를 들어 16비트 정수는 효율적인 인코딩을 통해 32비트 정수로 처리되므로 저장 형식에서 명시적으로 지원되지 않습니다. 이렇게 하면 형식에 대한 판독기와 기록기를 구현하는 복잡성이 줄어듭니다. 유형은 다음과 같습니다.
논리 유형은 기본 유형을 해석하는 방법을 지정하여 parquet를 사용하여 저장할 수 있는 유형을 확장하는 데 사용됩니다. 이는 기본 유형 세트를 최소한으로 유지하고 Parquet의 효율적인 인코딩을 재사용합니다. 예를 들어 문자열은 STRING 주석이 포함된 기본 유형 BYTE_ARRAY로 저장됩니다. 이러한 주석은 데이터를 추가로 디코딩하고 해석하는 방법을 정의합니다. 주석은 파일 메타데이터에 LogicalType
필드로 저장되며 LogicalTypes.md에 문서화되어 있습니다.
Parquet는 여러 수준(예: 열 청크, 열 인덱스 및 데이터 페이지)에서 최소/최대 통계를 저장합니다. 유형의 값 비교는 다음 규칙을 따릅니다.
각 논리 유형에는 지정된 비교 순서가 있습니다. 열에 알 수 없는 논리 유형으로 주석이 달린 경우 데이터 정리에 통계가 사용되지 않을 수 있습니다. 논리 유형의 정렬 순서는 LogicalTypes.md 페이지에 설명되어 있습니다.
기본 유형의 경우 다음 규칙이 적용됩니다.
BOOLEAN - 거짓, 참
INT32, INT64 - 부호 있는 비교.
FLOAT, DOUBLE - NaN 및 부호 있는 0의 특수 처리를 통한 부호 있는 비교입니다. 자세한 내용은 ColumnOrder
공용체의 Thrift 정의에 문서화되어 있습니다. 여기에 요약되어 있지만 Thrift 정의는 권위 있는 것으로 간주됩니다.
+0.0
기록해야 합니다.-0.0
기록해야 합니다.파일을 읽을 때 이전 버전과의 호환성을 위해:
BYTE_ARRAY 및 FIXED_LEN_BYTE_ARRAY - 사전식 부호 없는 바이트별 비교입니다.
중첩된 열을 인코딩하기 위해 Parquet에서는 정의 및 반복 수준이 포함된 Dremel 인코딩을 사용합니다. 정의 수준은 열 경로에 정의된 선택적 필드 수를 지정합니다. 반복 수준은 값이 반복되는 경로의 반복 필드를 지정합니다. 최대 정의 및 반복 수준은 스키마에서 계산할 수 있습니다(즉, 중첩 정도). 이는 레벨을 저장하는 데 필요한 최대 비트 수를 정의합니다(레벨은 열의 모든 값에 대해 정의됩니다).
레벨에 대한 두 가지 인코딩이 BIT_PACKED 및 RLE를 지원합니다. 이제 BIT_PACKED를 대체하므로 RLE만 사용됩니다.
Nullity는 정의 수준(실행 길이로 인코딩됨)에서 인코딩됩니다. NULL 값은 데이터에 인코딩되지 않습니다. 예를 들어 중첩되지 않은 스키마에서 1000개의 NULL이 있는 열은 정의 수준에 대해 실행 길이 인코딩(0, 1000회)으로 인코딩되며 다른 것은 없습니다.
데이터 페이지의 경우 3가지 정보가 페이지 헤더 다음에 연속적으로 인코딩됩니다. 데이터 페이지에는 패딩이 허용되지 않습니다. 순서대로:
헤더에 지정된 uncompressed_page_size
값은 3개 조각을 모두 합친 값입니다.
데이터 페이지의 인코딩된 값은 항상 필요합니다. 정의 및 반복 수준은 스키마 정의에 따라 선택 사항입니다. 열이 중첩되지 않은 경우(즉, 열 경로의 길이가 1인 경우) 반복 수준을 인코딩하지 않습니다(항상 값이 1입니다). 필요한 데이터의 경우 정의 수준을 건너뜁니다(인코딩된 경우 항상 최대 정의 수준의 값을 갖습니다).
예를 들어 열이 중첩되지 않고 필수인 경우 페이지의 데이터는 인코딩된 값만 됩니다.
지원되는 인코딩은 Encodings.md에 설명되어 있습니다.
지원되는 압축 코덱은 Compression.md에 설명되어 있습니다.
열 청크는 연속적으로 기록된 페이지로 구성됩니다. 페이지는 공통 헤더를 공유하며 독자는 관심 없는 페이지를 건너뛸 수 있습니다. 페이지의 데이터는 헤더를 따르며 압축 및/또는 인코딩될 수 있습니다. 압축 및 인코딩은 페이지 메타데이터에 지정됩니다.
열 청크는 부분적으로 또는 완전히 사전 인코딩될 수 있습니다. 이는 실제 값 대신 사전 색인이 데이터 페이지에 저장된다는 의미입니다. 실제 값은 사전 페이지에 저장됩니다. Encodings.md에서 자세한 내용을 확인하세요. 사전 페이지는 열 청크의 첫 번째 위치에 배치되어야 합니다. 최대 하나의 사전 페이지가 열 청크에 배치될 수 있습니다.
또한 파일에는 독자가 페이지를 보다 효율적으로 건너뛸 수 있도록 선택적 열 인덱스가 포함될 수 있습니다. 이러한 형식을 형식에 추가하는 이유와 자세한 내용은 PageIndex.md를 참조하세요.
모든 종류의 페이지를 개별적으로 체크섬할 수 있습니다. 이를 통해 HDFS 파일 수준에서 체크섬을 비활성화하여 단일 행 조회를 더 효과적으로 지원할 수 있습니다. 체크섬은 페이지의 직렬화된 바이너리 표현(페이지 헤더 자체는 포함하지 않음)에서 표준 CRC32 알고리즘(예: GZip에 사용되는 것과 같은)을 사용하여 계산됩니다.
파일 메타데이터가 손상되면 파일이 손실됩니다. 열 메타데이터가 손상된 경우 해당 열 청크는 손실됩니다(그러나 다른 행 그룹에 있는 이 열의 열 청크는 괜찮습니다). 페이지 헤더가 손상되면 해당 청크의 나머지 페이지가 손실됩니다. 페이지 내의 데이터가 손상되면 해당 페이지가 손실됩니다. 행 그룹이 작을수록 파일 손상에 대한 복원력이 더 높아집니다.
잠재적인 확장: 더 작은 행 그룹의 경우 가장 큰 문제는 파일 메타데이터를 끝에 배치하는 것입니다. 파일 메타데이터를 쓰는 동안 오류가 발생하면 작성된 모든 데이터를 읽을 수 없게 됩니다. 이 문제는 N번째 행 그룹마다 파일 메타데이터를 작성하여 해결할 수 있습니다. 각 파일 메타데이터는 누적되며 지금까지 작성된 모든 행 그룹을 포함합니다. 이를 동기화 마커를 사용하여 rc 또는 avro 파일에 사용되는 전략과 결합하면 리더가 부분적으로 작성된 파일을 복구할 수 있습니다.
형식은 데이터에서 메타데이터를 분리하도록 명시적으로 설계되었습니다. 이를 통해 열을 여러 파일로 분할할 수 있을 뿐만 아니라 단일 메타데이터 파일이 여러 쪽모이 세공 파일을 참조하도록 할 수 있습니다.
호환되는 확장의 형식에는 여러 위치가 있습니다.
Parquet Thrift IDL은 확장을 위해 모든 Thrift 구조체의 필드 ID 32767
예약합니다. 이 필드의 (Thrift) 유형은 항상 binary
입니다.
apache/parquet-testing에는 테스트용 Parquet 파일 세트가 포함되어 있습니다.
문제에 대해 의견을 제시하거나 질문이나 아이디어가 있으면 parquet-dev 메일링 리스트에 문의하세요. 이 핵심 형식 정의에 대한 변경 사항은 메일링 리스트에서 제안되고 심도 있게 논의됩니다. 모든 Java 측 구현 및 API가 포함된 Parquet-Java 하위 프로젝트에 기여하는 데 관심이 있을 수도 있습니다. Parquet-Java 프로젝트의 "기여 방법" 섹션을 참조하세요.
우리는 Twitter OSS(https://github.com/twitter/code-of-conduct/blob/master/code-of-conduct.md)에 설명된 대로 우리 자신과 Parquet 개발자 커뮤니티가 행동 강령을 준수합니다.
저작권 2013 Twitter, Cloudera 및 기타 기여자.
Apache 라이센스 버전 2.0에 따라 라이센스가 부여됩니다: http://www.apache.org/licenses/LICENSE-2.0