Parquet Java의 압축 알고리즘
Apache Parquet는 분석 워크로드를 대상으로 하는 열 기반 스토리지 형식이지만 모든 유형의 구조화된 데이터를 저장하는 데 사용할 수 있어 다양한 사용 사례를 처리합니다.
가장 주목할만한 기능 중 하나는 처리 프로세스의 두 단계에서 서로 다른 압축 기술을 사용하여 데이터를 효율적으로 압축하는 기능입니다. 이를 통해 스토리지 비용이 절감되고 읽기 성능이 향상됩니다.
이 기사에서는 Java에서 Parquet의 파일 압축을 설명하고 사용 예를 제공하며 성능을 분석합니다.
압축 기술
기존 행 기반 스토리지 형식과 달리 Parquet는 열 기반 접근 방식을 사용하므로 동일한 유형의 데이터에 대한 지역성과 가치 중복성을 기반으로 보다 구체적이고 효율적인 압축 기술을 사용할 수 있습니다.
Parquet는 정보를 바이너리 형식으로 기록하고 각각 다른 기술을 사용하는 두 가지 수준에서 압축을 적용합니다.
- 열 값을 쓸 때 초기 값의 특성에 따라 인코딩 유형(사전 인코딩, 실행 길이 인코딩, 비트 패킹, 증분 인코딩 등)을 적응적으로 선택합니다.
- 특정 바이트 수(기본값은 1MB)에 도달할 때마다 페이지가 형성되고 프로그래머가 구성할 수 있는 알고리즘(비압축, GZip, Snappy, LZ4, ZSTD 등)을 사용하여 바이너리 블록이 압축됩니다.
압축 알고리즘은 파일 수준에서 구성되지만 각 열의 인코딩은 내부 경험적 방법을 사용하여 자동으로 선택됩니다(적어도 parquet-java 구현에서는).
다양한 압축 기술의 성능은 데이터에 크게 좌우되므로 가장 빠른 처리 시간과 가장 낮은 스토리지 소비를 보장하는 만능 솔루션은 없습니다. 직접 테스트를 수행해야 합니다.
코드
구성은 간단하며 작성 시 명시적인 설정만 필요합니다. 파일을 읽을 때 Parquet는 어떤 압축 알고리즘이 사용되는지 검색하고 해당 압축 해제 알고리즘을 적용합니다.
알고리즘 또는 코덱 구성
프로토콜 버퍼와 Avro를 사용하는 Carpet 및 Parquet에서 압축 알고리즘을 구성하려면 빌더의 withCompressionCodec 메소드를 호출하면 됩니다.
카펫
CarpetWriter<T> writer = new CarpetWriter.Builder<>(outputFile, clazz) .withCompressionCodec(CompressionCodecName.ZSTD) .build();
아브로
ParquetWriter<Organization> writer = AvroParquetWriter.<Organization>builder(outputFile) .withSchema(new Organization().getSchema()) .withCompressionCodec(CompressionCodecName.ZSTD) .build();
프로토콜 버퍼
ParquetWriter<Organization> writer = ProtoParquetWriter.<Organization>builder(outputFile) .withMessage(Organization.class) .withCompressionCodec(CompressionCodecName.ZSTD) .build();
값은 CompressionCodecName 열거에서 사용 가능한 값 중 하나여야 합니다: UNCOMPRESSED, SNAPPY, GZIP, LZO, BROTLI, LZ4, ZSTD 및 LZ4_RAW(LZ4는 더 이상 사용되지 않으며 LZ4_RAW를 사용해야 함).
압축 수준
일부 압축 알고리즘은 압축 수준을 미세 조정하는 방법을 제공합니다. 이 수준은 일반적으로 반복 패턴을 찾는 데 필요한 노력과 관련이 있습니다. 압축 수준이 높을수록 압축 프로세스에 더 많은 시간과 메모리가 필요합니다.
기본값이 제공되지만 각 코덱마다 다른 키를 사용하더라도 Parquet의 일반 구성 메커니즘을 사용하여 수정할 수 있습니다.
또한 선택하는 값은 표준이 아니며 각 코덱에 따라 다르므로 각 레벨이 제공하는 내용을 이해하려면 각 알고리즘에 대한 설명서를 참조해야 합니다.
ZSTD
참조 레벨 구성을 위해 ZSTD 코덱은 상수 ZstandardCodec.PARQUET_COMPRESS_ZSTD_LEVEL
를 선언합니다.
가능한 값은 1~22이며, 기본값은 3입니다.
CarpetWriter<T> writer = new CarpetWriter.Builder<>(outputFile, clazz) .withCompressionCodec(CompressionCodecName.ZSTD) .build();
LZO
참조 레벨 구성을 위해 LZO 코덱은 LzoCodec.LZO_COMPRESSION_LEVEL_KEY
상수를 선언합니다.
가능한 값은 1~9, 99, 999이며, 기본값은 '999'입니다.
ParquetWriter<Organization> writer = AvroParquetWriter.<Organization>builder(outputFile) .withSchema(new Organization().getSchema()) .withCompressionCodec(CompressionCodecName.ZSTD) .build();
GZIP
상수를 선언하지 않으며 "zlib.compress.level" 문자열을 직접 사용해야 하며, 가능한 값은 0~9까지, 기본값은 "6"입니다.
ParquetWriter<Organization> writer = ProtoParquetWriter.<Organization>builder(outputFile) .withMessage(Organization.class) .withCompressionCodec(CompressionCodecName.ZSTD) .build();
성능 테스트
다양한 압축 알고리즘의 성능을 분석하기 위해 다양한 유형의 데이터가 포함된 두 개의 공개 데이터세트를 사용하겠습니다.
- 뉴욕시 택시 여행: 여러 열에 다수의 숫자와 소수의 문자열 값이 포함되어 있습니다. 23개의 열이 있고 1,960만 개의 레코드가 포함되어 있습니다.
- 이탈리아 정부의 응집력 프로젝트: 많은 열에는 부동 소수점 값은 물론 수많은 다양한 텍스트 문자열이 포함되어 있습니다. 91개의 열과 200만 개의 행이 포함되어 있습니다.
Parquet Java에서 활성화된 일부 압축 알고리즘(UNCOMPRESSED, SNAPPY, GZIP, LZO, ZSTD, LZ4_RAW)을 평가하겠습니다.
예상대로 parquet-java에서 제공하는 기본 구성과 각 알고리즘의 기본 압축 수준으로 Carpet을 사용할 예정입니다.
GitHub에서 소스 코드를 찾을 수 있으며, 테스트는 AMD Ryzen 7 4800HS CPU 및 JDK 17이 설치된 노트북에서 수행되었습니다.
파일 크기
각 압축의 성능을 이해하기 위해 해당 CSV 파일을 참조로 사용합니다.
格式 | gov.it | 纽约出租车 |
---|---|---|
CSV | 1761 MB | 2983 MB |
未压缩 | 564 MB | 760 MB |
SNAPPY | 220 MB | 542 MB |
GZIP | **146 MB** | 448 MB |
ZSTD | 148 MB | **430 MB** |
LZ4_RAW | 209 MB | 547 MB |
LZO | 215 MB | 518 MB |
두 가지 테스트 중 GZip과 Zstandard를 사용한 압축이 가장 효율적이었습니다.
Parquet 인코딩 기술만 사용하면 파일 크기를 원래 CSV 크기의 25%-32%까지 줄일 수 있습니다. 추가 압축을 적용하면 CSV 크기의 9%~15%로 줄어듭니다.
쓰기
정보를 압축하면 얼마나 많은 오버헤드가 발생하나요?
동일한 정보를 세 번 쓰고 평균 초를 계산하면 다음과 같은 결과를 얻습니다.
算法 | gov.it | 纽约出租车 |
---|---|---|
未压缩 | 25.0 | 57.9 |
SNAPPY | 25.2 | 56.4 |
GZIP | 39.3 | 91.1 |
ZSTD | 27.3 | 64.1 |
LZ4_RAW | **24.9** | 56.5 |
LZO | 26.0 | **56.1** |
SNAPPY, LZ4 및 LZO는 압축하지 않은 상태와 비슷한 시간을 달성하는 반면 ZSTD는 약간의 오버헤드를 추가합니다. GZIP은 쓰기 시간이 50% 느려지는 등 최악의 성능을 보였습니다.
읽기
파일을 읽는 것은 쓰는 것보다 계산이 덜 필요하기 때문에 더 빠릅니다.
파일의 모든 열을 읽는 데 걸리는 시간(초)은 다음과 같습니다.
算法 | gov.it | 纽约出租车 |
---|---|---|
未压缩 | 11.4 | 37.4 |
SNAPPY | **12.5** | **39.9** |
GZIP | 13.6 | 40.9 |
ZSTD | 13.1 | 41.5 |
LZ4_RAW | 12.8 | 41.6 |
LZO | 13.1 | 41.1 |
읽는 시간은 비압축 정보에 가깝고 압축 해제 오버헤드는 10~20%입니다.
결론
읽기 및 쓰기 시간 측면에서 다른 알고리즘보다 훨씬 나은 알고리즘은 없으며 모두 비슷한 범위에 있습니다. 대부분의 경우 정보를 압축하면 공간 절약(및 전송) 시간 손실을 보상할 수 있습니다.
이 두 가지 사용 사례에서 하나 또는 다른 알고리즘을 선택하는 결정 요인은 아마도 달성된 압축 비율일 것입니다. ZSTD와 Gzip이 두드러집니다(그러나 쓰기 시간은 열등함).
각 알고리즘에는 장점이 있으므로 가장 좋은 옵션은 데이터로 이를 테스트하고 어떤 요소가 더 중요한지 고려하는 것입니다.
- 자주 사용하지 않는 데이터를 대용량으로 저장하여 스토리지 사용량을 최소화합니다.
- 파일 생성 시간을 최소화하세요.
- 파일을 여러 번 읽으므로 읽기 시간을 최소화하세요.
인생의 모든 것과 마찬가지로 절충안이 있으며 이를 가장 잘 보상하는 것이 무엇인지 확인해야 합니다. Carpet에서는 아무것도 구성하지 않으면 기본적으로 압축을 위해 Snappy를 사용합니다.
구현 세부정보
값은 CompressionCodecName 열거에서 사용 가능한 값 중 하나여야 합니다. 각 열거형 값과 연관된 것은 알고리즘을 구현하는 클래스의 이름입니다:
CarpetWriter<T> writer = new CarpetWriter.Builder<>(outputFile, clazz) .withCompressionCodec(CompressionCodecName.ZSTD) .build();
Parquet는 리플렉션을 사용하여 CompressionCodec 인터페이스를 구현해야 하는 지정된 클래스를 인스턴스화합니다. 소스 코드를 보면 Parquet이 아닌 Hadoop 프로젝트에 있음을 알 수 있습니다. 이는 Java 구현에서 Parquet가 Hadoop과 얼마나 잘 결합되어 있는지 보여줍니다.
이러한 코덱 중 하나를 사용하려면 해당 구현이 포함된 JAR을 종속성으로 추가했는지 확인해야 합니다.
parquet-java를 추가할 때 모든 구현이 전이적 종속성에 존재하지 않거나 Hadoop 종속성을 너무 적극적으로 제외할 수 있습니다.
org.apache.parquet:parquet-hadoop 종속성에 SnappyCodec, ZstandardCodec 및 Lz4RawCodec의 구현을 포함합니다. 이는 이 세 가지 알고리즘의 실제 구현과 함께 snappy-java, zstd-jni 및 aircompressor 종속성을 전이적으로 가져옵니다. .
hadoop-common:hadoop-common 종속성에는 GzipCodec 구현이 포함되어 있습니다.
BrotliCodec 및 LzoCodec 구현은 어디에 있나요? Parquet 또는 Hadoop 종속성에 속하지 않습니다. 따라서 추가 종속성을 추가하지 않고 사용하면 애플리케이션에서 해당 형식으로 압축된 파일을 사용할 수 없습니다.
- LZO를 지원하려면 pom 또는 gradle 파일에 org.anarres.lzo:lzo-hadoop 종속성을 추가해야 합니다.
- Brotli의 상황은 더 복잡합니다. 종속성은 Maven Central에 없으며 JitPack 저장소도 추가해야 합니다.
위 내용은 Parquet Java의 압축 알고리즘의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

일부 애플리케이션이 제대로 작동하지 않는 회사의 보안 소프트웨어에 대한 문제 해결 및 솔루션. 많은 회사들이 내부 네트워크 보안을 보장하기 위해 보안 소프트웨어를 배포 할 것입니다. ...

많은 응용 프로그램 시나리오에서 정렬을 구현하기 위해 이름으로 이름을 변환하는 솔루션, 사용자는 그룹으로, 특히 하나로 분류해야 할 수도 있습니다.

시스템 도킹의 필드 매핑 처리 시스템 도킹을 수행 할 때 어려운 문제가 발생합니다. 시스템의 인터페이스 필드를 효과적으로 매핑하는 방법 ...

IntellijideAultimate 버전을 사용하여 봄을 시작하십시오 ...

데이터베이스 작업에 MyBatis-Plus 또는 기타 ORM 프레임 워크를 사용하는 경우 엔티티 클래스의 속성 이름을 기반으로 쿼리 조건을 구성해야합니다. 매번 수동으로 ...

Java 객체 및 배열의 변환 : 캐스트 유형 변환의 위험과 올바른 방법에 대한 심층적 인 논의 많은 Java 초보자가 객체를 배열로 변환 할 것입니다 ...

전자 상거래 플랫폼에서 SKU 및 SPU 테이블의 디자인에 대한 자세한 설명이 기사는 전자 상거래 플랫폼에서 SKU 및 SPU의 데이터베이스 설계 문제, 특히 사용자 정의 판매를 처리하는 방법에 대해 논의 할 것입니다 ...

Redis 캐싱 솔루션은 제품 순위 목록의 요구 사항을 어떻게 인식합니까? 개발 과정에서 우리는 종종 a ... 표시와 같은 순위의 요구 사항을 처리해야합니다.
