Topik ini menjelaskan cara membuat, membaca dari, dan menulis ke tabel eksternal berformat Parquet di OSS.
Lingkup Penggunaan
Tabel eksternal OSS tidak mendukung properti cluster.
Ukuran satu file tidak boleh melebihi 2 GB. Anda harus membagi file yang lebih besar dari 2 GB.
MaxCompute dan OSS harus berada di wilayah yang sama.
Tipe Data yang Didukung
Untuk informasi selengkapnya mengenai tipe data MaxCompute, lihat Data Type Version 1.0 dan Data Type Version 2.0.
Mode JNI:
set odps.ext.parquet.native=false. Mode ini menggunakan implementasi open-source berbasis Java asli untuk mengurai file data Parquet dan mendukung operasi baca serta tulis.Mode Native:
set odps.ext.parquet.native=true. Mode ini menggunakan implementasi native berbasis C++ untuk mengurai file data Parquet dan hanya mendukung operasi baca.Mode
Java Mode (Baca/Tulis)
Native Mode (Hanya Baca)
TINYINT
SMALLINT
INT
BIGINT
BINARY
FLOAT
DOUBLE
DECIMAL(precision,scale)
VARCHAR(n)
CHAR(n)
STRING
DATE
DATETIME
TIMESTAMP
TIMESTAMP_NTZ
BOOLEAN
ARRAY
MAP
STRUCT
JSON
Format Kompresi yang Didukung
Saat membaca atau menulis file OSS dengan properti kompresi, tambahkan konfigurasi properti
with serdepropertiespada pernyataan pembuatan tabel. Untuk informasi selengkapnya, lihat parameter properti with serdeproperties.Format file Parquet yang didukung mencakup kompresi ZSTD, SNAPPY, dan GZIP.
Dukungan Evolusi Skema
Tabel eksternal Parquet memetakan nilai kolom berdasarkan nama, dengan mencocokkan skema tabel terhadap kolom dalam file.
Catatan Kompatibilitas Data dalam tabel berikut menjelaskan apakah tabel eksternal yang skemanya telah dimodifikasi dapat membaca data yang sesuai dengan skema baru tersebut, serta apakah tabel tersebut tetap dapat membaca data historis yang tidak sesuai dengan skema baru.
Jenis Operasi | Didukung | Deskripsi | Catatan Kompatibilitas Data |
Tambah kolom |
|
| |
Hapus kolom | Tabel eksternal Parquet memetakan nilai kolom berdasarkan nama. | Kompatibel | |
Ubah urutan kolom | Tabel eksternal Parquet memetakan nilai kolom berdasarkan nama. | Kompatibel | |
Ubah tipe data kolom | Operasi ini tidak didukung. Parquet menerapkan validasi skema yang ketat. Mengubah tipe yang kompatibel dapat merusak kompatibilitas. | Tidak berlaku | |
Ubah nama kolom | Operasi ini tidak didukung. Parquet menerapkan validasi skema yang ketat. Mengubah tipe yang kompatibel dapat merusak kompatibilitas. | Tidak berlaku | |
Perbarui komentar kolom | Komentar harus berupa string yang valid dengan panjang maksimal 1024 byte. Jika tidak, terjadi error. | Kompatibel | |
Ubah nullability kolom | Operasi ini tidak didukung. Kolom bersifat nullable secara default. | Tidak berlaku |
Buat Tabel Eksternal
Sintaks
Saat skema file Parquet berbeda dari skema tabel eksternal:
Ketidaksesuaian jumlah kolom: Jika file Parquet memiliki kolom lebih sedikit daripada DDL tabel eksternal, kolom yang hilang mengembalikan NULL. Jika file Parquet memiliki kolom lebih banyak, kolom tambahan diabaikan.
Ketidaksesuaian tipe kolom: Jika tipe kolom file Parquet berbeda dari tipe kolom yang sesuai dalam DDL tabel eksternal, proses baca gagal. Misalnya, mencoba membaca data INT (atau STRING) menggunakan STRING (atau INT) menghasilkan error
ODPS-0123131:User defined function exception - Traceback:xxx.
Struktur 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 Detail
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/aliyunodpsdefaultrole',
'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 | Kasus Penggunaan | Deskripsi | property_value | Nilai Default |
mcfed.parquet.compression | Tambahkan properti ini saat menulis data Parquet ke OSS dalam format terkompresi. | Pengaturan kompresi Parquet. Data Parquet tidak dikompresi secara default. |
| Tidak ada |
mcfed.parquet.compression.codec.zstd.level | Tambahkan properti ini saat | Level yang lebih tinggi meningkatkan rasio kompresi tetapi mengurangi performa. Untuk I/O Parquet skala besar, gunakan level rendah (3–5). Contoh: | Nilai valid: 1–22. | 3 |
parquet.file.cache.size | Tambahkan properti ini untuk meningkatkan performa baca OSS. | Ukuran cache untuk file data OSS, dalam KB. | 1024 | Tidak ada |
parquet.io.buffer.size | Tambahkan properti ini untuk meningkatkan performa baca OSS. | Ukuran buffer untuk file data OSS yang lebih besar dari 1024 KB, dalam KB. | 4096 | Tidak ada |
Parameter tblproperties
property_name | Kasus Penggunaan | Deskripsi | property_value | Nilai Default |
io.compression.codecs | Tambahkan properti ini saat file data OSS menggunakan format Raw-Snappy. | Resolver data open-source bawaan mendukung format SNAPPY. Saat parameter ini diatur ke True, MaxCompute dapat membaca data terkompresi. Jika tidak, MaxCompute tidak dapat membaca data tersebut. | com.aliyun.odps.io.compress.SnappyRawCodec. | Tidak ada |
odps.external.data.output.prefix (Kompatibel mundur dengan odps.external.data.prefix) | Tambahkan properti ini untuk mengatur awalan kustom untuk file output. |
| Kombinasi valid, seperti mc_. | Tidak ada |
odps.external.data.enable.extension | Tambahkan properti ini untuk menampilkan ekstensi file dalam nama file output. | True menampilkan ekstensi. False menyembunyikannya. |
| False |
odps.external.data.output.suffix | Tambahkan properti ini untuk mengatur akhiran kustom untuk file output. | Hanya boleh berisi huruf, angka, dan garis bawah (a–z, A–Z, 0–9, _). | Kombinasi valid, seperti _hangzhou. | Tidak ada |
odps.external.data.output.explicit.extension | Tambahkan properti ini untuk mengatur ekstensi file kustom. |
| Kombinasi valid, seperti jsonl. | Tidak ada |
mcfed.parquet.compression | Tambahkan properti ini saat menulis data Parquet ke OSS dalam format terkompresi. | Pengaturan kompresi Parquet. Data Parquet tidak dikompresi secara default. |
| Tidak ada |
mcfed.parquet.block.size | Mengontrol ukuran blok Parquet, memengaruhi efisiensi penyimpanan dan performa baca. | Pengaturan tuning Parquet. Ukuran blok dalam byte. | Bilangan bulat non-negatif | 134217728 (128 MB) |
mcfed.parquet.block.row.count.limit | Membatasi jumlah record per grup baris saat menulis ke tabel eksternal Parquet untuk menghindari error kehabisan memori (OOM). | Pengaturan tuning Parquet. Jumlah maksimum record per grup baris. Kurangi nilai ini jika terjadi OOM. Tips penggunaan:
| Bilangan bulat non-negatif | 2147483647 (Integer.MAX_VALUE) |
mcfed.parquet.page.size.row.check.min | Mengontrol frekuensi pemeriksaan memori selama penulisan ke tabel eksternal Parquet untuk mencegah OOM. | Pengaturan tuning Parquet. Jumlah minimum record antara pemeriksaan memori. Kurangi nilai ini jika terjadi OOM. | Bilangan bulat non-negatif | 100 |
mcfed.parquet.page.size.row.check.max | Mengontrol frekuensi pemeriksaan memori selama penulisan ke tabel eksternal Parquet untuk mencegah OOM. | Properti Tuning Parquet. Menentukan jumlah minimum record antara pemeriksaan memori. Jika terjadi error kehabisan memori, kurangi parameter ini. Karena diperlukan perhitungan penggunaan memori secara berkala, menyesuaikan parameter ini dapat menimbulkan overhead tambahan. Tips penggunaan:
| Bilangan bulat non-negatif | 1000 |
mcfed.parquet.compression.codec.zstd.level | Tambahkan properti ini untuk mengatur level kompresi ZSTD saat menulis data Parquet ke OSS dalam format ZSTD. | Pengaturan kompresi Parquet. Level kompresi ZSTD. Nilai valid: 1–22. | Bilangan bulat non-negatif | 3 |
Menulis data
Untuk informasi selengkapnya tentang sintaks penulisan MaxCompute, lihat Sintaks penulisan.
Kueri dan Analisis
Untuk informasi selengkapnya tentang sintaks SELECT, lihat Sintaks kueri.
Untuk informasi selengkapnya tentang optimasi rencana kueri, lihat Optimasi kueri.
Untuk melakukan kueri langsung terhadap file LOCATION, lihat Fitur: Schemaless Query.
Optimasi Kueri: Tabel eksternal Parquet mendukung Predicate Push Down (PPD) untuk mengoptimalkan kueri. Untuk hasil performa, lihat Predicate Push Down (Parquet PPD).
Aktifkan PPD dengan menambahkan parameter berikut sebelum SQL Anda:
-- Gunakan PPD hanya dalam mode Native (odps.ext.parquet.native = true). -- Aktifkan reader native Parquet. SET odps.ext.parquet.native = true; -- Aktifkan Parquet PPD. SET odps.sql.parquet.use.predicate.pushdown = true;
Predicate Push Down (Parquet PPD)
Tabel eksternal Parquet tidak mendukung Predicate Push Down (Parquet PPD) secara native. Saat Anda menjalankan kueri dengan kondisi filter WHERE, MaxCompute secara default memindai semua data, sehingga menyebabkan I/O, konsumsi resource, dan latensi kueri yang tidak perlu. Oleh karena itu, MaxCompute telah memperkenalkan parameter Parquet PPD. Dengan mengaktifkan Parquet PPD, Anda dapat memanfaatkan fitur metadata file Parquet itu sendiri selama fase pemindaian data untuk menerapkan pemfilteran tingkat RowGroup Parquet, sehingga meningkatkan performa kueri serta mengurangi konsumsi resource dan biaya.
Cara Menggunakan
Aktifkan Predicate Push Down (Parquet PPD)
Sebelum menjalankan kueri SQL, gunakan perintah
SETuntuk mengatur dua parameter tingkat sesi berikut guna mengaktifkan Parquet PDD.-- Aktifkan reader native Parquet. set odps.ext.parquet.native = true; -- Aktifkan Parquet PPD. set odps.sql.parquet.use.predicate.pushdown = true;Contoh
Berdasarkan set data uji TPCDS 1 TB, contoh ini menggunakan tabel eksternal
tpcds_1t_store_salesberformat Parquet untuk menjalankan kueri pemfilteran dengan PPD diaktifkan. Volume total data adalah2879987999.-- 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/aliyunodpsdefaultrole', 'mcfed.parquet.compression'='zstd' ) STORED AS parquet LOCATION 'oss://oss-cn-hangzhou-internal.aliyuncs.com/oss_bucket_path/'; -- Muat 1 TB data uji TPCDS. 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 data yang dipindai, sehingga menurunkan latensi kueri dan penggunaan resource.
Mode | Total Baris | Baris Dipindai | Byte Dipindai | Waktu Mapper | Total Penggunaan Resource | Catatan |
Tabel Eksternal Parquet (PPD Dinonaktifkan) | 2879987999 | 2879987999 (100%) | 19386793984 (100%) | 18 dtk | cpu 19,25 Core * Min, memory 24,07 GB * Min 100% | |
Tabel Eksternal Parquet (PPD Diaktifkan) | 2879987999 | 762366649 (26,47%) | 3339386880 (17,22%) | 12 dtk | cpu 11,47 Core * Min, memory 14,33 GB * Min ~59,58% | Mengurangi data yang dipindai secara signifikan menurunkan latensi dan penggunaan resource |
Tabel Internal (PPD Diaktifkan) | 2879987999 | 32830000 (1,14%) | 1633880386 (8,43%) | 9 dtk | cpu 5,62 Core * Min, memory 7,02 GB * Min ~29,19% | Data tabel internal diurutkan, sehingga PPD bekerja lebih baik lagi |
Detail Pengujian
Tabel Eksternal Parquet (PPD Dinonaktifkan)
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;


Tabel Eksternal Parquet (PPD Diaktifkan)
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;

Banyak mapper kosong dan melewati pembacaan data:

Log aktual pemangkasan RowGroup:

Tabel Internal (PPD Diaktifkan)
Data tabel internal diurutkan, sehingga pemangkasan lebih efektif.
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;


Contoh Skenario
Contoh ini membuat tabel eksternal Parquet terkompresi ZSTD dan melakukan operasi baca dan tulis.
Prasyarat
Anda telah membuat proyek MaxCompute.
Anda telah menyiapkan bucket OSS dan direktori OSS. Untuk informasi selengkapnya, lihat Buat bucket dan Kelola folder.
Karena MaxCompute hanya tersedia di wilayah tertentu, masalah konektivitas cross-region dapat terjadi. Kami menyarankan menggunakan bucket OSS di wilayah yang sama dengan proyek MaxCompute Anda.
Otorisasi
Anda memiliki izin untuk mengakses OSS. Akun Alibaba Cloud (akun utama), pengguna Resource Access Management (RAM), atau peran RAM dapat mengakses tabel eksternal OSS. Untuk detail otorisasi, lihat Otorisasi mode STS untuk OSS.
Anda memiliki izin CreateTable di proyek MaxCompute. Untuk detail izin operasi tabel, lihat Izin MaxCompute.
Siapkan file data berformat ZSTD.
Di bucket
oss-mc-testdari data sampel, buat direktoriparquet_zstd_jni/dt=20230418. Tempatkan data partisi di direktoridt=20230418.Buat tabel eksternal Parquet terkompresi 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/aliyunodpsdefaultrole', 'mcfed.parquet.compression'='zstd' ) STORED AS parquet LOCATION 'oss://oss-cn-hangzhou-internal.aliyuncs.com/oss-mc-test/parquet_zstd_jni/';Jika tabel eksternal OSS Anda dipartisi, jalankan perintah ini untuk menambahkan partisi. Untuk opsi lainnya, lihat Tambahkan Partisi ke Tabel Eksternal OSS.
-- Tambahkan data partisi. MSCK REPAIR TABLE mc_oss_parquet_data_type_zstd ADD PARTITIONS;Baca data dari tabel eksternal Parquet.
SELECT * FROM mc_oss_parquet_data_type_zstd WHERE dt='20230418' LIMIT 10;Hasil contoh:
+------------+------------+------------+------------+------------------+-------------------+----------------+------------+------------+ | 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 | +------------+------------+------------+------------+------------------+-------------------+----------------+------------+------------+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 dimasukkan. SELECT * FROM mc_oss_parquet_data_type_zstd WHERE dt = '20230418' AND recordid=16;Hasil:
+------------+------------+------------+------------+------------------+-------------------+----------------+------------+------------+ | vehicleid | recordid | patientid | calls | locationlatitute | locationlongtitue | recordtime | direction | dt | +------------+------------+------------+------------+------------------+-------------------+----------------+------------+------------+ | 1 | 16 | 76 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:10 | SW | 20230418 | +------------+------------+------------+------------+------------------+-------------------+----------------+------------+------------+
FAQ
Tipe Kolom File Parquet Tidak Sesuai dengan Tipe 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
File Parquet menggunakan LongWritable, tetapi DDL tabel eksternal mendefinisikan kolom sebagai INT.
Solusi
Ubah tipe kolom dalam DDL tabel eksternal dari INT menjadi BIGINT.
Error Kehabisan Memori Saat Menulis ke Tabel Eksternaljava.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 OutOfMemoryError saat menulis data dalam jumlah besar ke tabel eksternal Parquet.
Solusi
Saat membuat tabel eksternal, pertama-tama kurangi
mcfed.parquet.block.row.count.limit. Jika OOM masih terjadi atau file output terlalu besar, kurangimcfed.parquet.page.size.row.check.maxagar pemeriksaan memori lebih sering dilakukan. Untuk detailnya, lihat Parameter Unik.Tambahkan pengaturan berikut sebelum menulis ke tabel eksternal Parquet:
-- Atur memori heap JVM maksimum untuk 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 per Map Worker. SET odps.stage.mapper.mem=12288; -- Sesuaikan ukuran data input per Map Worker (ukuran pemisahan file) untuk mengontrol jumlah Worker per tahap Map. SET odps.stage.mapper.split.size=64;