Parquet
Parquet
하둡에서 주로 사용하는 파일 포맷 중 하나. 빅데이터 플랫폼에서 활용하기 용이.
파케이(Parquet)는 중첩된 데이터를 효율적으로 저장할 수 있는 컬럼 기준 저장 포맷
컬럼 기준 은 파일 크기와 쿼리 성능 측면에 모두 효율성이 높음
- 동일한 컬럼 값을 나란히 모아서 저장하여 인코딩 효율이 높다.
- 일반적으로 행 기반 포맷에 비해 파일 사이즈가 작아서 쿼리 성능이 놓다.
- 컬럼 기반 방식으로 중첩 구조(Neted data structure)의 데이터를 저장할 수 있다.
- 적은 오버헤드로 단층 컬럼 기준 포맷에 중첩된 구조를 저장하는 새로운 기술
- 파케이는 중첩된 필드를 다른 필드와 상관 없이 독립적으로 읽을 수 있게 되었으며 따라서 상당한 성능 향상을 얻을 수 있었음
- 파케이 포맷을 지원하는 수많은 도구가 있다. 이러한 유연성은 인메모리 표현까지 확장
- 자바 구현체는 단일 표현에 얽매이지 않기 때문에 파케이 파일에서 데이터를 읽고 쓰는데 에이브로, 쓰리프트, 프로토콜 버퍼의 인메모리 데이터 모델을 사용할 수 있음
데이터 타입
기본 자료형
boolean, int32/64/96, float, double, binary, fixed_len_byte_Array
기본 문자열 자료형이 없다는 점 주의. 대신 기본 자료형에 대한 해석 방식을 정의한 논리 자료형을 제공. 따라서 직렬화 표현(기본 자료형)과 애플리케이션에 특화된 시맨틱(논리 자료형)은 차이가 있음. 문자열은 UTF-8 어노테이션을 가진 binary 기본 자료형으로 표현
논리 자료형
UTF8, ENUM, DECIMAL, DATE, LIST(순서 있는 값의 집합), MAP(순서 없는 키-값 쌍의 집합) LIST, MAP은 두 단계 그룹 구조의 그룹으로 만든다. 중첩 인코딩
스키마의 모든 기본 자료형 필드의 값을 별도의 컬럼에 저장하고, 그 구조는 명세 수준과 반복 수준의 두 정수로 인코딩한다. 단층 레코드는 null을 사용하고 중첩이나 반복 수준이 올라가면 null이 아닌 값을 사용해서 비트 필드를 인코딩한다고 생각하면 됨 이러한 인코딩 방식을 이용하면 중첩 컬럼을 포하만 어떤 컬럼도 다른 컬럼과 상관없이 읽을 수 있다. 키만 읽을 수도 있음
파일 포맷
- 헤더 - Block 1 - Block 2 - Block N - 꼬리말
- 헤더 : 파케이 파일임을 알려주는 4바이트 magic number인 PAR1만 포함
- 모든 메타데이터는 꼬리말에. 포맷 버전, 스키마, 추가 키-값 쌍, 블록 위치 등 –> 따라서 뒤에서부터 읽음
- 블록은 행 그룹을 저장. 행 그룹은 행에 대한 컬럼 데이터를 포함한 컬럼 청크로 되어 있음. 각 컬럼 청크의 데이터는 페이지에 기록
- 인코딩 : 델타 인코딩(값의 차이를 저장), 연속 길이 인코딩(동일한 값이 연속으로 나오면 그 값과 빈도를 저장), 사전 인코딩(값의 사전을 만들어 인코딩한 후 사전의 인덱스를 나타내는 정수로 그 값을 저장)
- 비트 패킹(bit packing. 작은 몇 개의 값을 한 바이트에 저장하여 공간을 절약)도 지원
- 파케이는 파일을 기록할 때 컬럼의 자료형을 기준으로 적합한 인코딩을 자동으로 선택. 주로 사전 인코딩. 사전이 너무 크면 일반 인코딩으로 대체. 이런 임계는 사전 페이지의 크기와 관련
- snappy, gzip, LZO 압축 지원
- Block 내 Column Chenk N개, M개 Row Group, Column Metadata로 이루어져 있다.

4-byte magic number "PAR1"
<Column 1 Chunk 1 + Column Metadata>
<Column 2 Chunk 1 + Column Metadata>
...
<Column N Chunk 1 + Column Metadata> // 행 그룹 1 (N 개의 Column Chunk)
<Column 1 Chunk 2 + Column Metadata>
<Column 2 Chunk 2 + Column Metadata>
...
<Column N Chunk 2 + Column Metadata> // 행 그룸 2 (N 개의 Column Chunk)
...
<Column 1 Chunk M + Column Metadata>
<Column 2 Chunk M + Column Metadata>
...
<Column N Chunk M + Column Metadata> // 행그룹 M (N 개의 Column Chunk)
File Metadata
4-byte length in bytes of file metadata
테이블 형태

꼬리말에 모든 metadata 정보가 들어있으며, offset of first data page를 가지고 있음

설정
파케이 파일의 속성은 파일 기록 시점에 정해짐
ParquetOutputFormat 속성
- parquet.block.size : 블록의 바이트 크기(행 그룹, int, default: 128MB)
- parquet.page.size : 페이지의 바이트 크기 (int, default: 1MB)
- parquet.dictionary.page.size : 일반 인코딩으로 돌아가기 전의 사전의 최대 허용 바이트 크기 (int, default: 1MB)
- parquet.enable.dictionary : 사전 인코딩 사용여부 (bool, default: True)
- parquet.compression : 사용할 압축 종류 (string)
블록 크기 : 스캔 효율성과 메모리 사용률 사이의 트레이드오프 관계 고려
- 블록 크기를 크게: 더 많은 행을 가지므로 순차 I/O성능을 높일 수 있어 효율적인 스캔. 하지만 개별 블록을 읽고 쓸 때 모든 데이터가 메모리에 저장되어야 하기 때문에 너무 큰 블록을 사용하는 것은 한계가 있음
- HDFS 블록 크기보다 크면 안됨 (HDFS 블록 기본은 128MB)
페이지 : 파케이 파일의 최소 저장 단위. 원하는 행을 읽기 위해서는 그 행을 포함한 페이지의 압축을 해제하고 디코딩 해야 함
- 단일 행 검색은 페이지가 작을수록 효율적. 원하는 값 찾기 전에 읽어야하는 값이 더 적어짐
- 페이지가 작으면 필요한 페이지의 수가 늘어나 추가적인 메타데이터로 인해 저장 용량과 처리 시간이 증가하는 단점이 있음
Mimumum/Maximum Filtering
- Parquet 2.0 이후부터, row group 별 min/max statistics 값을 가진다. 이를 통해 필요 없는 row group들을 제거할 수 있다.
- 만약 SELECT * FROM TABLE WHERE A < 10 의 Query가 요청되었을 때, 각 Row group이 가지는 min, max 값이랑 overlap이 되는 row group만 반환하게 된다.
Parquet 파일 포맷 보는 법
Parquet 파일을 보기 위해서는 parquet-tools 가 필요하다.
# 1. hdfs에 저장 되어 있는 parquet 파일 꺼내기
hdfs dfs -get `파일경로` `받을경로`
# 2. parquet 파일 보기
parquet-tools dump `파일` | more