All Products
Search
Document Center

MaxCompute:Tabel eksternal Parquet

Last Updated:Sep 19, 2026

Topik ini menjelaskan cara membuat, membaca dari, dan menulis ke tabel eksternal Parquet di Object Storage Service (OSS).

Lingkup

Deskripsi izin

  • Saat mengakses tabel eksternal OSS, data diakses melalui role yang ditentukan dalam parameter odps.properties.rolearn, terlepas dari apakah Anda menggunakan Akun Alibaba Cloud, Pengguna RAM, atau Peran RAM. Oleh karena itu, Anda harus membuat Peran RAM dan memberikan izin untuk mengakses bucket OSS target, lalu mengonfigurasi ARN role tersebut dalam parameter odps.properties.rolearn. Untuk informasi selengkapnya, lihat Parameter.

  • Anda dapat mengotorisasi akses dalam akun yang sama atau akses lintas akun sesuai kebutuhan bisnis Anda. Kami merekomendasikan penggunaan kebijakan otorisasi kustom untuk kontrol akses detail halus. Untuk informasi selengkapnya, lihat Otorisasi untuk sumber data eksternal.

Buat tabel eksternal

Sintaks

Saat skema file Parquet berbeda dengan skema tabel eksternal:

  • Ketidaksesuaian jumlah kolom: Jika file Parquet memiliki lebih sedikit kolom daripada yang didefinisikan dalam DDL tabel eksternal, kolom yang hilang mengembalikan NULL. Jika file memiliki lebih banyak kolom, kolom tambahan diabaikan.

  • Ketidaksesuaian tipe kolom: Jika tipe kolom dalam file Parquet tidak sesuai dengan tipe yang sesuai dalam DDL, operasi baca gagal. Misalnya, error seperti ODPS-0123131:User defined function exception - Traceback:xxx dilaporkan jika Anda mencoba membaca kolom INT sebagai bidang STRING.

Sintaks sederhana

CREATE EXTERNAL TABLE [IF NOT EXISTS] <mc_oss_extable_name>
(
  <col_name> <data_type>,
  ...
)
[COMMENT <table_comment>]
[PARTITIONED BY (<col_name> <data_type>, ...)]
STORED AS parquet 
LOCATION '<oss_location>' 
[tblproperties ('<tbproperty_name>'='<tbproperty_value>',...)];

Sintaks lengkap

CREATE EXTERNAL TABLE [IF NOT EXISTS] <mc_oss_extable_name>
(
  <col_name> <data_type>,
  ...
)
[COMMENT <table_comment>]
[PARTITIONED BY (<col_name> <data_type>, ...)]
ROW FORMAT SERDE 'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe'
WITH serdeproperties(
    'odps.properties.rolearn'='acs:ram::<uid>:role/<role_name>',
    'mcfed.parquet.compression'='ZSTD/SNAPPY/GZIP'
)
STORED AS parquet 
LOCATION '<oss_location>' 
;

Parameter umum

Untuk informasi selengkapnya tentang parameter umum, lihat Parameter sintaks dasar.

Parameter unik

Parameter with serdeproperties

property_name

Kapan digunakan

Deskripsi

property_value

Default

mcfed.parquet.compression

Tambahkan properti ini untuk menulis data Parquet ke OSS dalam format terkompresi.

Properti kompresi Parquet. Data Parquet tidak dikompresi secara default.

  • ZSTD

  • SNAPPY

  • GZIP

None

mcfed.parquet.compression.codec.zstd.level

Tambahkan properti ini saat 'mcfed.parquet.compression'='zstd'. Jika properti ini tidak ditentukan, tingkat kompresi default 3 digunakan.

Tingkat yang lebih tinggi meningkatkan rasio kompresi. Namun, pengujian menunjukkan bahwa tingkat tinggi memberikan keuntungan minimal dalam pengurangan ukuran data sementara secara signifikan meningkatkan waktu dan konsumsi resource. Untuk skenario data besar, tingkat ZSTD rendah (3 hingga 5) memberikan keseimbangan terbaik antara performa dan kompresi. Contoh: 'mcfed.parquet.compression.codec.zstd.level'= '5'.

Nilainya dapat berkisar dari 1 hingga 22.

3

parquet.file.cache.size

Tambahkan properti ini untuk meningkatkan performa membaca file data OSS saat memproses data Parquet.

Menentukan jumlah data yang dapat di-cache saat membaca file data OSS. Satuan: KB.

1024

None

parquet.io.buffer.size

Tambahkan properti ini untuk meningkatkan performa membaca file data OSS saat memproses data Parquet.

Menentukan jumlah data yang dapat di-cache saat ukuran file data OSS melebihi 1024 KB. Satuan: KB.

4096

None

Parameter tblproperties

property_name

Kapan digunakan

Deskripsi

property_value

Default

io.compression.codecs

Tambahkan properti ini jika file data OSS Anda dalam format Raw-Snappy.

Mengaktifkan parser open source bawaan untuk format SNAPPY.

Jika Anda mengatur parameter ini ke True, MaxCompute dapat membaca data terkompresi. Jika tidak, operasi baca gagal.

com.aliyun.odps.io.compress.SnappyRawCodec.

None

odps.external.data.output.prefix

(Kompatibel dengan odps.external.data.prefix)

Tambahkan properti ini untuk menentukan awalan kustom untuk file output.

  • Hanya boleh berisi huruf, angka, dan garis bawah (a-z, A-Z, 0-9, _).

  • Panjangnya harus 1 hingga 10 karakter.

Kombinasi karakter yang valid, seperti 'mc_'.

None

odps.external.data.enable.extension

Tambahkan properti ini untuk menampilkan ekstensi file output.

Atur ke True untuk menampilkan ekstensi file. Jika tidak, ekstensi disembunyikan.

  • True

  • False

False

odps.external.data.output.suffix

Tambahkan properti ini untuk menentukan akhiran kustom untuk file output.

Hanya boleh berisi huruf, angka, dan garis bawah (a-z, A-Z, 0-9, _).

Kombinasi karakter yang valid, seperti '_hangzhou'.

None

odps.external.data.output.explicit.extension

Tambahkan properti ini untuk menentukan ekstensi kustom untuk file output.

  • Hanya boleh berisi huruf, angka, dan garis bawah (a-z, A-Z, 0-9, _).

  • Panjangnya harus 1 hingga 10 karakter.

  • Parameter ini memiliki prioritas lebih tinggi daripada odps.external.data.enable.extension.

Kombinasi karakter yang valid, seperti "jsonl".

None

odps.ext.column.mapping

Tambahkan properti ini saat nama bidang dalam file data OSS mengandung karakter khusus. 

Properti ini mendefinisikan pemetaan nama kolom kustom. Misalnya, jika bidang file OSS adalah id BIGINT, $_test DOUBLE, dan =name STRING, atur nilai parameter menjadi t_test:$_test,t_name:=_name saat membuat tabel eksternal. Anda hanya perlu menentukan pemetaan untuk bidang yang mengandung karakter khusus.

Tidak ada nilai tetap

None

odps.ext.column.mapping.delimiters

(Gunakan hanya ketika karakter dalam nama kolom bertentangan dengan delimiter default dalam pemetaan nama kolom. Umumnya tidak direkomendasikan.)

Tambahkan properti ini saat nama kolom mengandung karakter khusus : atau ,

Properti ini menyesuaikan delimiter intra-grup dan antar-grup untuk pasangan kunci-nilai. Nilainya harus berisi tepat dua karakter: karakter pertama berfungsi sebagai delimiter kunci-nilai, dan karakter kedua berfungsi sebagai delimiter antara pasangan kunci-nilai yang berbeda.

Tidak ada nilai tetap. Contoh: =|.

Nilai default: ':,'

  • Secara default, ':' digunakan sebagai delimiter antara kunci dan nilai.

  • Koma ',' digunakan sebagai delimiter antara pasangan kunci-nilai yang berbeda. 

  • Spasi awal dan akhir dalam kunci dan nilai dipangkas selama penguraian.

mcfed.parquet.compression

Tambahkan properti ini untuk menulis data Parquet ke OSS dalam format terkompresi.

Tidak diperlukan parameter tambahan untuk membaca file terkompresi.

Properti kompresi Parquet. Data Parquet tidak dikompresi secara default.

  • SNAPPY

  • GZIP

  • ZSTD

None

mcfed.parquet.block.size

Mengontrol ukuran blok file Parquet, yang memengaruhi efisiensi penyimpanan dan performa baca.

Properti tuning Parquet. Menentukan ukuran blok Parquet dalam byte.

Bilangan bulat non-negatif

134217728 (128 MB)

mcfed.parquet.block.row.count.limit

Saat menulis data ke tabel eksternal Parquet, membatasi jumlah record dalam setiap grup baris untuk mencegah error kehabisan memori (OOM).

Properti tuning Parquet. Mengontrol jumlah maksimum record per grup baris. Jika terjadi error OOM, kurangi nilai parameter ini.

Saran:

  1. Jika memori JVM hanya 1 GB dan ukuran record rata-rata 1 MB, atur parameter ini sekitar 100. Ukuran grup baris default adalah 128 MB.

  2. Jangan atur parameter ini ke nilai yang sangat kecil.

Bilangan bulat non-negatif

2147483647

(Integer.MAX_VALUE)

mcfed.parquet.page.size.row.check.min

Saat menulis data ke tabel eksternal Parquet, mengontrol frekuensi pemeriksaan memori untuk mencegah error OOM.

Properti tuning Parquet. Membatasi jumlah minimum record antara pemeriksaan memori. Jika terjadi error OOM, kurangi nilai parameter ini.

Bilangan bulat non-negatif

100

mcfed.parquet.page.size.row.check.max

Saat menulis data ke tabel eksternal Parquet, mengontrol frekuensi pemeriksaan memori untuk mencegah error OOM.

Properti tuning Parquet. Membatasi jumlah minimum record antara pemeriksaan memori. Jika terjadi error OOM, kurangi nilai parameter ini.

Karena pemeriksaan memori yang sering menambah overhead, menyesuaikan parameter ini dapat memengaruhi performa.

Saran parameter:

  1. Secara default, pemeriksaan memori dilakukan setiap 10.000 record. Jika ukuran record kecil, Anda dapat mengatur parameter ini ke nilai yang lebih kecil, seperti 1000, untuk melakukan pemeriksaan memori lebih sering dan mencegah error OOM.

  2. Pertama-tama, coba kurangi nilai mcfed.parquet.block.row.count.limit. Jika error OOM masih terjadi atau file output terlalu besar, kurangi nilai mcfed.parquet.page.size.row.check.max untuk memeriksa memori lebih sering.

Bilangan bulat non-negatif

1000

mcfed.parquet.compression.codec.zstd.level

Tambahkan properti ini untuk menentukan tingkat kompresi algoritma ZSTD saat menulis data Parquet ke OSS dengan kompresi ZSTD.

Properti kompresi Parquet. Menentukan tingkat kompresi algoritma ZSTD. Nilainya dapat berkisar dari 1 hingga 22.

Bilangan bulat non-negatif

3

Daftar putih dan blacklist

Tabel eksternal OSS MaxCompute mendukung penyaringan daftar putih dan blacklist. Dengan mengatur parameter daftar putih dan blacklist dalam tblproperties, Anda dapat menyaring file mana yang akan dibaca dari direktori. Untuk detailnya, lihat Daftar putih dan blacklist.

Menulis data

Untuk detail tentang sintaks penulisan di MaxCompute, lihat Sintaks penulisan.

Kueri dan analisis

  • Lihat Sintaks kueri untuk detail tentang sintaks SELECT.

  • Lihat Optimasi kueri untuk detail tentang mengoptimalkan rencana kueri.

  • Untuk informasi selengkapnya tentang membaca file LOCATION secara langsung, lihat Kueri tanpa skema.

  • Optimasi kueri: Tabel eksternal Parquet mendukung optimasi kueri dengan mengaktifkan Predicate Push Down (PPD). Untuk hasil performa, lihat Dukungan Predicate Push Down (Parquet PPD).

    Tambahkan parameter berikut sebelum pernyataan SQL Anda untuk mengaktifkan PPD:

    -- Parameter PPD harus digunakan dalam mode Native, artinya switch Native harus diatur ke true.
    -- Aktifkan pembaca native Parquet.
    SET odps.ext.parquet.native = true; 
    -- Aktifkan Parquet PPD.
    SET odps.sql.parquet.use.predicate.pushdown = true; 

Dukungan Predicate Push Down (Parquet PPD)

Secara default, tabel eksternal Parquet tidak mendukung Predicate Push Down (PPD). Saat Anda menjalankan kueri dengan kondisi filter WHERE, MaxCompute memindai semua data. Hal ini menyebabkan I/O yang tidak perlu, konsumsi resource, dan latensi kueri. Untuk mengatasi masalah ini, Anda dapat mengaktifkan PPD menggunakan parameter. Fitur ini menggunakan metadata dalam file Parquet untuk menyaring data pada tingkat grup baris selama fase pemindaian, yang meningkatkan performa kueri serta mengurangi konsumsi resource dan biaya.

Penggunaan

  • Aktifkan Predicate Push Down (PPD)

    Sebelum menjalankan kueri SQL, gunakan perintah set untuk mengatur dua parameter tingkat sesi berikut guna mengaktifkan Parquet PPD.

    -- Aktifkan pembaca native Parquet. 
    set odps.ext.parquet.native = true; 
    -- Aktifkan Parquet PPD.
    set odps.sql.parquet.use.predicate.pushdown = true; 
  • Contoh

    Contoh ini menggunakan set data uji TPC-DS 1 TB dan tabel eksternal Parquet tpcds_1t_store_sales. Dalam contoh ini, PPD diaktifkan dan kueri filter dijalankan. Volume data total adalah 2.879.987.999 baris.

    -- Buat tabel eksternal tpcds_1t_store_sales.
    CREATE EXTERNAL TABLE IF NOT EXISTS tpcds_1t_store_sales (
        ss_sold_date_sk         BIGINT,
        ss_sold_time_sk         BIGINT,
        ss_item_sk              BIGINT,
        ss_customer_sk          BIGINT,
        ss_cdemo_sk             BIGINT,
        ss_hdemo_sk             BIGINT,
        ss_addr_sk              BIGINT,
        ss_store_sk             BIGINT,
        ss_promo_sk             BIGINT,
        ss_ticket_number        BIGINT,
        ss_quantity             BIGINT,
        ss_wholesale_cost       DECIMAL(7,2),
        ss_list_price           DECIMAL(7,2),
        ss_sales_price          DECIMAL(7,2),
        ss_ext_discount_amt     DECIMAL(7,2),
        ss_ext_sales_price      DECIMAL(7,2),
        ss_ext_wholesale_cost   DECIMAL(7,2),
        ss_ext_list_price       DECIMAL(7,2),
        ss_ext_tax              DECIMAL(7,2),
        ss_coupon_amt           DECIMAL(7,2),
        ss_net_paid             DECIMAL(7,2),
        ss_net_paid_inc_tax     DECIMAL(7,2),
        ss_net_profit           DECIMAL(7,2)
    )
    ROW FORMAT SERDE 'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe'
    WITH serdeproperties(
      'odps.properties.rolearn'='acs:ram::<uid>:role/<role_name>',
      'mcfed.parquet.compression'='zstd'
    )
    STORED AS parquet
    LOCATION 'oss://oss-cn-hangzhou-internal.aliyuncs.com/oss_bucket_path/';
    -- Gunakan set data uji TPC-DS 1 TB.
    INSERT OVERWRITE TABLE tpcds_1t_store_sales
    SELECT 
        ss_sold_date_sk,
        ss_sold_time_sk,
        ss_item_sk,
        ss_customer_sk,
        ss_cdemo_sk,
        ss_hdemo_sk,
        ss_addr_sk,
        ss_store_sk,
        ss_promo_sk,
        ss_ticket_number,
        ss_quantity,
        ss_wholesale_cost,
        ss_list_price,
        ss_sales_price,
        ss_ext_discount_amt,
        ss_ext_sales_price,
        ss_ext_wholesale_cost,
        ss_ext_list_price,
        ss_ext_tax,
        ss_coupon_amt,
        ss_net_paid,
        ss_net_paid_inc_tax,
        ss_net_profit
    FROM 
        bigdata_public_dataset.tpcds_1t.store_sales;
    -- Jalankan kueri.
    SELECT SUM(ss_sold_date_sk) FROM tpcds_1t_store_sales
      WHERE ss_sold_date_sk >= 2451871 AND ss_sold_date_sk <= 2451880;

Perbandingan performa

Mengaktifkan PPD mengurangi jumlah data yang dipindai, sehingga menurunkan latensi kueri dan konsumsi resource.

Mode

Total baris dalam tabel

Baris yang dipindai

Byte yang dipindai

Waktu mapper

Total konsumsi resource

Deskripsi

Tabel eksternal Parquet tanpa PPD

2.879.987.999

2.879.987.999 (100%)

19386793984 (100%)

18s

CPU 19,25 Core-menit, Memori 24,07 GB-menit

100%

Tabel eksternal Parquet dengan PPD

2.879.987.999

762.366.649 (26,47%)

3.339.386.880 (17,22%)

12s

cpu 11,47 Core × Min, memory 14,33 GB × Min

~59,58%

Pemindaian data yang berkurang secara signifikan menurunkan latensi dan konsumsi resource.

Tabel internal dengan PPD

2.879.987.999

32.830.000 (1,14%)

1.633.880.386 (8,43%)

9s

cpu 5,62 Core × Min, memory 7,02 GB × Min

~29,19%

PPD lebih efektif pada tabel internal karena datanya diurutkan.

Detail pengujian

  1. Tabel eksternal Parquet tanpa PPD

    SET odps.ext.parquet.native = true;
    SET odps.sql.parquet.use.predicate.pushdown = false;
    SELECT SUM(ss_sold_date_sk) FROM tpcds_1t_store_sales
      WHERE ss_store_sk = 2 AND ss_sold_date_sk >= 2451871 AND ss_sold_date_sk <= 2451880;

    image

    Hasil menunjukkan bahwa untuk tugas M1 dalam Fuxi Jobs, IO Records Input adalah 2,9 G, IO Bytes Input adalah 18,06 GB, dan Latency adalah 00:00:18,000.

    Tab Summary hasil eksekusi menunjukkan bahwa konsumsi resource adalah cpu 19,25 Core × Min dan memori 24,07 GB × Min. Waktu proses job adalah 23,000 detik, dan mode proses adalah fuxi job 2.0. Tugas M1 memiliki 1.404 instans, waktu proses 18,000 detik, 2.879.987.999 record input, dan 355 record output. Tugas R2_1 memiliki 1 instans, waktu proses 4,000 detik, dan 1 record output.

  2. Tabel eksternal Parquet dengan PPD

    SET odps.ext.parquet.native = true;
    SET odps.sql.parquet.use.predicate.pushdown = true;
    SELECT SUM(ss_sold_date_sk) FROM tpcds_1t_store_sales
      WHERE ss_store_sk = 2 AND ss_sold_date_sk >= 2451871 AND ss_sold_date_sk <= 2451880;

    image

    Setelah menjalankan kueri ini, ringkasan job menunjukkan bahwa konsumsi resource adalah cpu 11,47 Core × Min, memory 14,33 GB × Min, dengan total waktu proses 15 detik. Tahap M1 memiliki 1.404 instans, waktu proses 12 detik, dan 762.366.649 record input (sekitar 3.339.386.880 byte). Tahap R2_1 memiliki 1 instans dan waktu proses 3 detik.

    Banyak mapper kosong dan tidak perlu membaca data:

    image.webp

    Log pemangkasan grup baris aktual:

    [2024-05-10 22:29:22.692182]    [INFO]   [239551]    [/home/admin/odps_build/workspace/IRDS_CMK_7u/jenkins-IRDS_CMK_7u-70
    16/common/table/file_formats/parquet/parquet_row_group_pruner.cpp:100]    The expression to prune row groups:(((ss_store_s
    k == 2:int64) and (ss_sold_date_sk >= 2451871:int64)) and (ss_sold_date_sk <= 2451880:int64))
    [2024-05-10 22:29:22.705508]    [INFO]   [239551]    [/home/admin/odps_build/workspace/IRDS_CMK_7u/jenkins-IRDS_CMK_7u-70
    16/common/table/file_formats/parquet/parquet_reader_factory.cpp:136]    Parquet row group pruning is enabled, millisecon
    ds elapsed:13    Total row group count:1 Pruned row group count:1    The first several row group indexes:
    [2024-05-10 22:29:22.705532]    [INFO]   [239551]    [/home/admin/odps_build/workspace/IRDS_CMK_7u/jenkins-IRDS_CMK_7u-70
    16/common/table/file_formats/parquet/parquet_reader_factory.cpp:60]  total feasible parquet row group count:0]
  3. Tabel internal dengan PPD

    Efek pemangkasan lebih signifikan karena data dalam tabel internal diurutkan.

    SELECT SUM(ss_sold_date_sk) FROM bigdata_public_dataset.tpcds_1t.store_sales
      WHERE ss_store_sk = 2 AND ss_sold_date_sk >= 2451871 AND ss_sold_date_sk <= 2451880;

    Setelah menjalankan kueri ini, DAG job menunjukkan bahwa jumlah total baris dalam sumber data adalah 2.879.987.999, tetapi jumlah baris yang benar-benar dipindai hanya 32.830.000. Tahap M1 (703 instans) membaca 32.830.000 baris dan menghasilkan 323 baris. Tahap R2_1 menerima 323 baris dan menghasilkan 1 baris. Hal ini menunjukkan bahwa efek pemangkasan sangat signifikan saat PPD diaktifkan untuk tabel internal dengan data terurut.

    Pemantauan Fuxi Jobs menunjukkan bahwa job SQL_0_1_0_job_0 selesai. Job ini mencakup dua Tugas Fuxi, M1 dan R2_1, keduanya dengan status Terminated. M1 memiliki 703 instans, input 32,8 juta record (1,52 GB), output 323 record, dan latensi 00:00:09,375. R2_1 memiliki 1 instans, input 323 record, output 1 record, dan latensi 00:00:03,873. Detail instans M1 menunjukkan 4 instans Data-Skew. Instans seperti M1#101_0, M1#103_0, dan M1#105_0 memiliki 0 untuk Input dan Output. Hal ini menunjukkan bahwa instans tersebut adalah instans dry-run dan kueri ini memiliki masalah kesenjangan data.

    resource cost: cpu 5,62 Core * Min, memory 7,02 GB * Min
    inputs:
        lakehouse47_2.default.tpcds_1t_store_sales2: 32830000 (1633880386 bytes)
    outputs:
    Job run time: 14,000
    Job run mode: fuxi job 2.0
    Job run engine: execution engine
    M1:
        instance count: 703
        run time: 9,000
        instance time:
            min: 0,000, max: 2,000, avg: 0,000
        input records:
            TableScan1: 32830000  (min: 0, max: 210000, avg: 46699)
        output records:
            StreamLineWrite1: 323  (min: 0, max: 1, avg: 0)
        metrics_output_count:
            Calc1: 58025  (min: 0, max: 461, avg: 82)
            HashAgg1: 323  (min: 0, max: 1, avg: 0)
            StreamLineWrite1: 323  (min: 0, max: 1, avg: 0)
            TableScan1: 32830000  (min: 0, max: 210000, avg: 46699)
        metrics_inner_time_ms:
            Calc1: 4  (min: 0, max: 2, avg: 0)  MaxInstance: 21
            GlobalInit: 57752  (min: 60, max: 386, avg: 82)  MaxInstance: 17
            HashAgg1: 0  (min: 0, max: 0, avg: 0)   MaxInstance: 2
            StreamLineWrite1: 20469  (min: 5, max: 899, avg: 29)   MaxInstance: 400
            TableScan1: 131977  (min: 51, max: 1417, avg: 187)  MaxInstance: 301
    R2_1:
        instance count: 1
        run time: 4,000
        instance time:
            min: 0,000, max: 0,000, avg: 0,000
        input records:
            StreamLineRead1: 323  (min: 323, max: 323, avg: 323)
        output records:
            AdhocSink1: 1  (min: 1, max: 1, avg: 1)
        metrics_output_count:
            AdhocSink1: 1  (min: 1, max: 1, avg: 1)

Perbandingan performa Parquet dan ZSTD

Bagian berikut membandingkan performa format kompresi yang berbeda untuk tabel eksternal Parquet.

Catatan: Hasil pengujian hanya sebagai referensi. Performa dapat bervariasi berdasarkan skenario bisnis. Kami merekomendasikan Anda melakukan pengujian dan evaluasi lebih lanjut untuk kasus penggunaan spesifik Anda.

Performa kueri

Set data: TPC-DS 1 TB
Resource: 900+ CU
Metode pengujian: ETL

Metrik

Parquet tidak terkompresi

Parquet-Snappy

Parquet-ZSTD

job runtime (s)

4372

4215

3649

CPU cost

14211,89

10131,36

6004,26

Memory cost

26852,91

19323,27

11778,06

Storage (GB)

425,94

335,33

230,87

  • Latensi: ZSTD 13,4% lebih cepat daripada Snappy dan 16,5% lebih cepat daripada tidak terkompresi.

  • CPU: ZSTD menggunakan 40,7% lebih sedikit CPU daripada Snappy dan 57,75% lebih sedikit daripada tidak terkompresi.

  • Memori: ZSTD menggunakan 39,04% lebih sedikit memori daripada Snappy dan 56,13% lebih sedikit daripada tidak terkompresi.

  • Storage: ZSTD menggunakan 31,15% lebih sedikit ruang penyimpanan daripada Snappy dan 45,8% lebih sedikit daripada tidak terkompresi.

imageimageimage

Efisiensi penyimpanan

Set data: TPC-DS 1 TB
Resource: 900+ CU
Metode pengujian: ETL
  • tidak terkompresi: Meskipun format ini tidak dikompresi, menghasilkan volume data yang lebih besar dan overhead I/O yang lebih tinggi, yang menyebabkan performa keseluruhan buruk.

  • snappy: Kecepatan kompresi tidak lebih cepat daripada ZSTD tingkat rendah, tetapi rasio kompresinya lebih tinggi. Hal ini menghasilkan performa keseluruhan lebih buruk daripada ZSTD tingkat rendah.

  • zstd: Ukuran data output konvergen dengan cepat. Tingkat yang lebih tinggi memberikan kompresi tambahan minimal (hanya 13,87% lebih banyak) tetapi menyebabkan peningkatan cepat dalam waktu dan konsumsi resource, yang secara drastis mengurangi efektivitas biaya. Untuk skenario ini, ZSTD tingkat rendah (level 3 hingga 5) memberikan hasil terbaik. Level 3 adalah default.

  • Pada set data TPC-DS 1 TB, ZSTD menggunakan 31,1% lebih sedikit ruang penyimpanan daripada Snappy dan 45,8% lebih sedikit daripada tidak terkompresi.

Format kompresi

Ukuran data output (GB / Rasio kompresi)

Waktu proses job (s)

Waktu TableSink (s, % dari waktu proses job)

CPU (Core × Min)

Memori (GB × Min)

tidak terkompresi

486,67 (100%)

256,406

~ 134,61 (52,5%)

2353,19

3361,71

snappy

238,33 (48,97%)

239,087

~ 73,88 (30,9%)

2110,31

3014,73

zstd (level 1, min)

164,71 (33,84%)

233,170

~ 65,75 (28,2%)

2110,23

3014,61

zstd (level 2)

165,3 (33,97%)

231,226

~ 64,51 (27,9%)

2100,79

3001,13

zstd (level 3, default)

158,9 (32,65%)

236,985

~ 67,07 (28,3%)

2115,10

3021,57

zstd (level 4)

159,52 (32,77%)

232,477

~ 67,65 (29,1%)

2100,13

3000,19

zstd (level 5)

157,89 (32,44%)

232,248

~ 71,07 (30,6%)

2103,96

3005,66

zstd (level 6)


160,47 (32,97%)

236,669

~ 78,10 (33,0%)

2137,63

3053,75

zstd (level 9)

152,00 (31,23%)

254,073

~ 100,36 (39,5%)

2287,61

3268,01

zstd (level 14)

144,63 (29,72%)

455,019

~ 341,26 (75,5%)

4076,00

5822,86

zstd (level 19)


150,87 (31,00%)

727,841

~ 614,30 (84,4%)

6933,10

9904,43

zstd (level 22, max)

150,81 (30,99%)

5381,359

~ 5.257,59 (97,7%)

42848,13

61211,62

image

Contoh skenario

Contoh ini menunjukkan cara membuat tabel eksternal Parquet partisi dengan kompresi ZSTD, lalu membaca dari dan menulis ke tabel tersebut.

  1. Prasyarat

    1. Anda telah membuat proyek MaxCompute.

    2. Anda telah menyiapkan bucket dan direktori OSS. Untuk informasi selengkapnya, lihat Buat bucket dan Kelola direktori.

      Pastikan bucket Anda berada di wilayah yang sama dengan proyek MaxCompute Anda.
    3. Berikan izin.

      1. Anda memiliki izin untuk mengakses OSS. Anda dapat mengakses tabel eksternal OSS dengan menggunakan Akun Alibaba Cloud, Pengguna RAM, atau Peran RAM. Untuk informasi selengkapnya tentang cara memberikan izin, lihat Otorisasi mode STS untuk OSS.

      2. Anda memiliki izin CreateTable di proyek MaxCompute. Untuk informasi selengkapnya tentang izin terkait tabel, lihat Izin MaxCompute.

  2. Siapkan file data dalam format ZSTD.

    Dalam bucket oss-mc-test untuk data sampel, buat folder parquet_zstd_jni/dt=20230418 dan simpan file data di folder partisi dt=20230418.

  3. Buat tabel eksternal Parquet yang menggunakan format kompresi ZSTD.

    CREATE EXTERNAL TABLE IF NOT EXISTS mc_oss_parquet_data_type_zstd (
        vehicleId INT,
        recordId INT,
        patientId INT,
        calls INT,
        locationLatitute DOUBLE,
        locationLongtitue DOUBLE,
        recordTime STRING,
        direction STRING
    )
    PARTITIONED BY (dt STRING )
    ROW FORMAT SERDE 'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe'
    WITH serdeproperties(
      'odps.properties.rolearn'='acs:ram::<uid>:role/<role_name>',
      'mcfed.parquet.compression'='zstd'
    )
    STORED AS parquet
    LOCATION 'oss://oss-cn-hangzhou-internal.aliyuncs.com/oss-mc-test/parquet_zstd_jni/';
  4. Impor data partisi. Jika tabel eksternal OSS adalah tabel partisi, Anda juga harus mengimpor data partisi. Untuk informasi selengkapnya, lihat Tabel eksternal OSS.

    -- Impor data partisi.
    MSCK REPAIR TABLE mc_oss_parquet_data_type_zstd ADD PARTITIONS;
  5. Baca data dari tabel eksternal Parquet.

    SELECT * FROM mc_oss_parquet_data_type_zstd WHERE dt='20230418' LIMIT 10;

    Output sampel berikut dikembalikan:

    +------------+------------+------------+------------+------------------+-------------------+----------------+------------+------------+
    | vehicleid  | recordid   | patientid  | calls      | locationlatitute | locationlongtitue | recordtime     | direction  | dt         |
    +------------+------------+------------+------------+------------------+-------------------+----------------+------------+------------+
    | 1          | 12         | 76         | 1          | 46.81006         | -92.08174         | 9/14/2014 0:10 | SW         | 20230418   |
    | 1          | 1          | 51         | 1          | 46.81006         | -92.08174         | 9/14/2014 0:00 | S          | 20230418   |
    | 1          | 2          | 13         | 1          | 46.81006         | -92.08174         | 9/14/2014 0:01 | NE         | 20230418   |
    | 1          | 3          | 48         | 1          | 46.81006         | -92.08174         | 9/14/2014 0:02 | NE         | 20230418   |
    | 1          | 4          | 30         | 1          | 46.81006         | -92.08174         | 9/14/2014 0:03 | W          | 20230418   |
    | 1          | 5          | 47         | 1          | 46.81006         | -92.08174         | 9/14/2014 0:04 | S          | 20230418   |
    | 1          | 6          | 9          | 1          | 46.81006         | -92.08174         | 9/14/2014 0:05 | S          | 20230418   |
    | 1          | 7          | 53         | 1          | 46.81006         | -92.08174         | 9/14/2014 0:06 | N          | 20230418   |
    | 1          | 8          | 63         | 1          | 46.81006         | -92.08174         | 9/14/2014 0:07 | SW         | 20230418   |
    | 1          | 9          | 4          | 1          | 46.81006         | -92.08174         | 9/14/2014 0:08 | NE         | 20230418   |
    | 1          | 10         | 31         | 1          | 46.81006         | -92.08174         | 9/14/2014 0:09 | N          | 20230418   |
    +------------+------------+------------+------------+------------------+-------------------+----------------+------------+------------+
  6. Tulis data ke tabel eksternal Parquet.

    INSERT INTO mc_oss_parquet_data_type_zstd PARTITION ( dt = '20230418') 
      VALUES  (1,16,76,1,46.81006,-92.08174,'9/14/2014 0:10','SW');
    -- Kueri data yang baru ditulis
    SELECT * FROM mc_oss_parquet_data_type_zstd WHERE dt = '20230418' AND recordid=16;

    Hasilnya sebagai berikut:

    +------------+------------+------------+------------+------------------+-------------------+----------------+------------+------------+
    | vehicleid  | recordid   | patientid  | calls      | locationlatitute | locationlongtitue | recordtime     | direction  | dt         |
    +------------+------------+------------+------------+------------------+-------------------+----------------+------------+------------+
    | 1          | 16         | 76         | 1          | 46.81006         | -92.08174         | 9/14/2014 0:10 | SW         | 20230418   |
    +------------+------------+------------+------------+------------------+-------------------+----------------+------------+------------+

Tipe data yang didukung

Untuk informasi selengkapnya tentang tipe data MaxCompute, lihat Tipe data (versi 1.0) dan Tipe data (versi 2.0).

  • Mode Java Native Interface (JNI): set odps.ext.parquet.native=false. Mode ini menggunakan implementasi berbasis Java open source asli untuk mengurai file data Parquet saat Anda membaca dari tabel eksternal. Mode ini mendukung operasi baca dan tulis.

  • Mode Native: set odps.ext.parquet.native=true. Mode ini menggunakan implementasi native berbasis C++ baru untuk mengurai file data Parquet saat Anda membaca dari tabel eksternal. Mode ini hanya mendukung operasi baca.

    Mode

    Mode Java (baca/tulis)

    Mode Native (read-only)

    TINYINT

    Didukung

    Didukung

    SMALLINT

    Didukung

    Didukung

    INT

    Didukung

    Didukung

    BIGINT

    Didukung

    Didukung

    BINARY

    Didukung

    Didukung

    FLOAT

    Didukung

    Didukung

    DOUBLE

    Didukung

    Didukung

    DECIMAL(precision,scale)

    Tidak didukung

    Didukung

    VARCHAR(n)

    Didukung

    Didukung

    CHAR(n)

    Didukung

    Didukung

    STRING

    Didukung

    Didukung

    DATE

    Didukung

    Didukung

    DATETIME

    Didukung

    Didukung

    TIMESTAMP

    Didukung

    Didukung

    TIMESTAMP_NTZ

    Tidak didukung

    Tidak didukung

    BOOLEAN

    Didukung

    Didukung

    ARRAY

    Didukung

    Didukung

    MAP

    Didukung

    Didukung

    STRUCT

    Didukung

    Didukung

    JSON

    Tidak didukung

    Tidak didukung

Format kompresi yang didukung

Untuk membaca atau menulis file OSS terkompresi, Anda dapat menambahkan konfigurasi properti with serdeproperties ke pernyataan pembuatan tabel. Untuk informasi selengkapnya, lihat parameter properti with serdeproperties.

Properti kompresi

Baca

Tulis

Gzip

Didukung

Didukung

ZSTD

Didukung

Didukung

SNAPPY (SnappyRawCodec)

Didukung

Didukung

SNAPPY (SnappyCodec)

Didukung

Tidak didukung

Dukungan untuk evolusi skema

Tabel eksternal Parquet memetakan nilai kolom antara skema dan kolom file berdasarkan nama.

Kolom Masalah kompatibilitas data dalam tabel berikut menjelaskan apakah data dapat dibaca dengan benar setelah operasi evolusi skema. Hal ini berlaku baik untuk data baru yang sesuai dengan skema yang dimodifikasi maupun data historis yang menggunakan skema lama.

Jenis operasi

Didukung

Deskripsi

Masalah kompatibilitas data

Tambah kolom

Didukung

  • Kolom baru ditambahkan di akhir tabel. Anda tidak dapat menentukan posisinya.

  • Jika Anda menambahkan kolom dengan nilai default, nilai default hanya berlaku untuk data yang ditulis oleh MaxCompute.

  • Data yang sesuai dengan skema yang dimodifikasi dapat dibaca.

  • Jika tidak ada modifikasi pada kolom data yang ada yang menggunakan skema lama, tabel dibaca menggunakan skema baru.

    Misalnya, jika Anda menambahkan kolom, data historis untuk kolom tersebut dibaca sebagai NULL.

Hapus kolom

Didukung

Tabel eksternal Parquet memetakan nilai kolom berdasarkan nama.

Kompatibel

Ubah urutan kolom

Didukung

Tabel eksternal Parquet memetakan nilai kolom berdasarkan nama.

Kompatibel

Ubah tipe data kolom

Tidak didukung

Operasi ini tidak didukung. Format Parquet memiliki validasi skema yang ketat. Mengubah tipe data dapat membuat data tidak dapat dibaca.

Tidak berlaku

Ubah nama kolom

Tidak didukung

Operasi ini tidak didukung. Format Parquet memiliki validasi skema yang ketat, yang dapat menyebabkan tipe yang sebelumnya kompatibel menjadi tidak dapat dibaca setelah modifikasi.

Tidak berlaku

Ubah komentar kolom

Didukung

Komentar harus berupa string yang valid dengan panjang maksimal 1024 byte. Jika tidak, terjadi error.

Kompatibel

Ubah properti non-null kolom

Tidak didukung

Operasi ini tidak didukung. Kolom bersifat nullable secara default.

Tidak berlaku

FAQ

Ketidaksesuaian tipe kolom antara file Parquet dan DDL tabel eksternal

  • Pesan error

    ODPS-0123131:User defined function exception - Traceback:
    java.lang.ClassCastException: org.apache.hadoop.io.LongWritable cannot be cast to org.apache.hadoop.io.IntWritable 
       at org.apache.hadoop.hive.serde2.objectinspector.primitive.WritableIntObjectInspector.getPrimitiveJavaObject(WritableIntObjectInspector.java:46)
  • Deskripsi error

    Tipe bidang LongWritable dari file Parquet tidak sesuai dengan tipe INT dalam DDL tabel eksternal.

  • Solusi

    Ubah tipe INT dalam DDL tabel eksternal menjadi BIGINT.

Error saat menulis ke tabel eksternal: java.lang.OutOfMemoryError

  • Pesan error

    ODPS-0123131:User defined function exception - Traceback:
    java.lang.OutOfMemoryError: Java heap space
    	at java.io.ByteArrayOutputStream.<init>(ByteArrayOutputStream.java:77)
    	at org.apache.parquet.bytes.BytesInput$BAOS.<init>(BytesInput.java:175)
    	at org.apache.parquet.bytes.BytesInput$BAOS.<init>(BytesInput.java:173)
    	at org.apache.parquet.bytes.BytesInput.toByteArray(BytesInput.java:161)
  • Deskripsi error

    Terjadi error kehabisan memori (OOM) saat Anda menulis volume data besar ke tabel eksternal Parquet.

  • Solusi

    Saat membuat tabel eksternal, pertama-tama kurangi parameter mcfed.parquet.block.row.count.limit. Jika error OOM masih terjadi atau file output terlalu besar, kurangi parameter mcfed.parquet.page.size.row.check.max untuk memeriksa memori lebih sering. Untuk informasi selengkapnya, lihat Parameter unik.

    Sebelum menulis data ke tabel eksternal Parquet, tambahkan parameter berikut.

    -- Atur ukuran memori maksimum untuk heap JVM UDF.
    SET odps.sql.udf.jvm.memory=12288;
    -- Kontrol ukuran batch di sisi waktu proses.
    SET odps.sql.executionengine.batch.rowcount =64;
    -- Atur ukuran memori untuk setiap pekerja Map.
    SET odps.stage.mapper.mem=12288;
    -- Atur volume data input untuk setiap pekerja Map (ukuran shard file input) untuk secara tidak langsung mengontrol jumlah pekerja per tahap Map.
    SET odps.stage.mapper.split.size=64;