>Java >java지도 시간 >Parquet Java의 압축 알고리즘

Parquet Java의 압축 알고리즘

Mary-Kate Olsen
Mary-Kate Olsen원래의
2025-01-20 18:04:12931검색

Compression algorithms in Parquet Java

Apache Parquet는 분석 워크로드를 대상으로 하는 열 기반 스토리지 형식이지만 모든 유형의 구조화된 데이터를 저장하는 데 사용할 수 있어 다양한 사용 사례를 처리합니다.

가장 주목할만한 기능 중 하나는 처리 프로세스의 두 단계에서 서로 다른 압축 기술을 사용하여 데이터를 효율적으로 압축하는 기능입니다. 이를 통해 스토리지 비용이 절감되고 읽기 성능이 향상됩니다.

이 기사에서는 Java에서 Parquet의 파일 압축을 설명하고 사용 예를 제공하며 성능을 분석합니다.

압축 기술

기존 행 기반 스토리지 형식과 달리 Parquet는 열 기반 접근 방식을 사용하므로 동일한 유형의 데이터에 대한 지역성과 가치 중복성을 기반으로 보다 구체적이고 효율적인 압축 기술을 사용할 수 있습니다.

Parquet는 정보를 바이너리 형식으로 기록하고 각각 다른 기술을 사용하는 두 가지 수준에서 압축을 적용합니다.

  • 열 값을 쓸 때 초기 값의 특성에 따라 인코딩 유형(사전 인코딩, 실행 길이 인코딩, 비트 패킹, 증분 인코딩 등)을 적응적으로 선택합니다.
  • 특정 바이트 수(기본값은 1MB)에 도달할 때마다 페이지가 형성되고 프로그래머가 구성할 수 있는 알고리즘(비압축, GZip, Snappy, LZ4, ZSTD 등)을 사용하여 바이너리 블록이 압축됩니다.

압축 알고리즘은 파일 수준에서 구성되지만 각 열의 인코딩은 내부 경험적 방법을 사용하여 자동으로 선택됩니다(적어도 parquet-java 구현에서는).

다양한 압축 기술의 성능은 데이터에 크게 좌우되므로 가장 빠른 처리 시간과 가장 낮은 스토리지 소비를 보장하는 만능 솔루션은 없습니다. 직접 테스트를 수행해야 합니다.

코드

구성은 간단하며 작성 시 명시적인 설정만 필요합니다. 파일을 읽을 때 Parquet는 어떤 압축 알고리즘이 사용되는지 검색하고 해당 압축 해제 알고리즘을 적용합니다.

알고리즘 또는 코덱 구성

프로토콜 버퍼와 Avro를 사용하는 Carpet 및 Parquet에서 압축 알고리즘을 구성하려면 빌더의 withCompressionCodec 메소드를 호출하면 됩니다.

카펫

<code class="language-java">CarpetWriter<T> writer = new CarpetWriter.Builder<>(outputFile, clazz)
    .withCompressionCodec(CompressionCodecName.ZSTD)
    .build();</code>

아브로

<code class="language-java">ParquetWriter<Organization> writer = AvroParquetWriter.<Organization>builder(outputFile)
    .withSchema(new Organization().getSchema())
    .withCompressionCodec(CompressionCodecName.ZSTD)
    .build();</code>

프로토콜 버퍼

<code class="language-java">ParquetWriter<Organization> writer = ProtoParquetWriter.<Organization>builder(outputFile)
    .withMessage(Organization.class)
    .withCompressionCodec(CompressionCodecName.ZSTD)
    .build();</code>

값은 CompressionCodecName 열거에서 사용 가능한 값 중 하나여야 합니다: UNCOMPRESSED, SNAPPY, GZIP, LZO, BROTLI, LZ4, ZSTD 및 LZ4_RAW(LZ4는 더 이상 사용되지 않으며 LZ4_RAW를 사용해야 함).

압축 수준

일부 압축 알고리즘은 압축 수준을 미세 조정하는 방법을 제공합니다. 이 수준은 일반적으로 반복 패턴을 찾는 데 필요한 노력과 관련이 있습니다. 압축 수준이 높을수록 압축 프로세스에 더 많은 시간과 메모리가 필요합니다.

기본값이 제공되지만 각 코덱마다 다른 키를 사용하더라도 Parquet의 일반 구성 메커니즘을 사용하여 수정할 수 있습니다.

또한 선택하는 값은 표준이 아니며 각 코덱에 따라 다르므로 각 레벨이 제공하는 내용을 이해하려면 각 알고리즘에 대한 설명서를 참조해야 합니다.

ZSTD

참조 레벨 구성을 위해 ZSTD 코덱은 상수 ZstandardCodec.PARQUET_COMPRESS_ZSTD_LEVEL를 선언합니다.

가능한 값은 1~22이며, 기본값은 3입니다.

<code class="language-java">CarpetWriter<T> writer = new CarpetWriter.Builder<>(outputFile, clazz)
    .withCompressionCodec(CompressionCodecName.ZSTD)
    .build();</code>

LZO

참조 레벨 구성을 위해 LZO 코덱은 LzoCodec.LZO_COMPRESSION_LEVEL_KEY 상수를 선언합니다.

가능한 값은 1~9, 99, 999이며, 기본값은 '999'입니다.

<code class="language-java">ParquetWriter<Organization> writer = AvroParquetWriter.<Organization>builder(outputFile)
    .withSchema(new Organization().getSchema())
    .withCompressionCodec(CompressionCodecName.ZSTD)
    .build();</code>

GZIP

상수를 선언하지 않으며 "zlib.compress.level" 문자열을 직접 사용해야 하며, 가능한 값은 0~9까지, 기본값은 "6"입니다.

<code class="language-java">ParquetWriter<Organization> writer = ProtoParquetWriter.<Organization>builder(outputFile)
    .withMessage(Organization.class)
    .withCompressionCodec(CompressionCodecName.ZSTD)
    .build();</code>

성능 테스트

다양한 압축 알고리즘의 성능을 분석하기 위해 다양한 유형의 데이터가 포함된 두 개의 공개 데이터세트를 사용하겠습니다.

  • 뉴욕시 택시 여행: 여러 열에 다수의 숫자와 소수의 문자열 값이 포함되어 있습니다. 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 열거에서 사용 가능한 값 중 하나여야 합니다. 각 열거형 값과 연관된 것은 알고리즘을 구현하는 클래스의 이름입니다:

<code class="language-java">CarpetWriter<T> writer = new CarpetWriter.Builder<>(outputFile, clazz)
    .withCompressionCodec(CompressionCodecName.ZSTD)
    .build();</code>

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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.