Topik ini menjelaskan cara membuat, membaca dari, dan menulis ke tabel eksternal OSS dalam format Parquet.
Lingkup
Tabel eksternal OSS tidak mendukung properti cluster.
Ukuran satu file tidak boleh melebihi 2 GB. Jika ukuran file terlalu besar, pisahkan file tersebut.
MaxCompute dan OSS harus berada di wilayah yang sama.
Tipe data yang didukung
Untuk informasi selengkapnya mengenai tipe data MaxCompute, lihat Data Types 1.0 dan Data Types 2.0.
Mode Java:
set odps.ext.parquet.native=false. Saat membaca data dari tabel eksternal, implementasi berbasis Java open-source asli digunakan untuk mengurai file data Parquet. Mode ini mendukung operasi baca dan tulis.Mode Native:
set odps.ext.parquet.native=true. Saat membaca data dari tabel eksternal, implementasi native berbasis C++ yang baru digunakan untuk mengurai file data Parquet. Mode ini hanya mendukung operasi baca.Mode
Mode Java (baca/tulis)
Mode Native (read-only)
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 yang memiliki properti kompresi, Anda harus menambahkan konfigurasi properti
with serdepropertiesdalam pernyataan pembuatan tabel. Untuk informasi selengkapnya, lihat parameter properti `with serdeproperties`.MaxCompute mendukung pembacaan dan penulisan file Parquet yang dikompresi dengan ZSTD, SNAPPY, atau GZIP.
Buat tabel eksternal
Sintaks
Jika skema file Parquet tidak konsisten dengan skema tabel eksternal:
Jumlah kolom tidak konsisten: Jika file Parquet memiliki jumlah kolom lebih sedikit daripada definisi tabel eksternal, kolom yang hilang akan diisi dengan nilai NULL selama operasi baca. Jika file Parquet memiliki lebih banyak kolom, kolom tambahan tersebut akan diabaikan.
Tipe kolom tidak konsisten: Jika tipe kolom dalam file Parquet tidak sesuai dengan tipe kolom yang sesuai dalam definisi tabel eksternal, error akan dilaporkan saat membaca data dari file tersebut. Misalnya, error akan dilaporkan jika Anda mencoba membaca data bertipe INT sebagai STRING, atau sebaliknya. Pesan error-nya adalah
ODPS-0123131:User defined function exception - Traceback:xxx.
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/aliyunodpsdefaultrole',
'mcfed.parquet.compression'='ZSTD/SNAPPY/GZIP'
)
STORED AS parquet
LOCATION '<oss_location>'
;Parameter umum
Untuk informasi lebih lanjut mengenai parameter umum, lihat Parameter sintaks dasar.
Parameter unik
Properti untuk WITH SERDEPROPERTIES
property_name | Skenario | Deskripsi | property_value | Nilai default |
mcfed.parquet.compression | Tambahkan properti ini ketika Anda perlu menulis data Parquet ke OSS dalam format terkompresi. | Properti kompresi Parquet. Secara default, data Parquet tidak dikompresi. |
| None |
mcfed.parquet.compression.codec.zstd.level | Anda dapat menambahkan properti ini ketika | Nilai tingkat yang lebih tinggi menghasilkan rasio kompresi yang lebih tinggi. Namun, pengujian kami menunjukkan bahwa tingkat tinggi memberikan pengurangan data minimal sementara secara signifikan meningkatkan waktu dan konsumsi resource. Pertukaran ini mengurangi efektivitas biaya. Oleh karena itu, untuk skenario yang melibatkan pembacaan dan penulisan file Parquet terkompresi dalam volume besar, tingkat kompresi zstd rendah (level 3 hingga level 5) memberikan hasil terbaik. Contohnya: | Nilai valid: 1 hingga 22. | 3 |
parquet.file.cache.size | Tambahkan properti ini untuk meningkatkan performa pembacaan 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 pembacaan file data OSS saat memproses data Parquet. | Menentukan jumlah data yang dapat di-cache ketika ukuran file data OSS melebihi 1024 KB. Satuan: KB. | 4096 | None |
Properti untuk TBLPROPERTIES
property_name | Skenario | Deskripsi | property_value | Nilai default |
io.compression.codecs | Tambahkan properti ini ketika file data OSS berada dalam format Raw-Snappy. | Skenario: Mengurai data dalam format SNAPPY menggunakan parser data open-source bawaan. Atur parameter ini ke True agar MaxCompute dapat membaca data terkompresi. Jika tidak, MaxCompute tidak dapat membaca data tersebut. | 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 nama file output. |
| Kombinasi karakter valid, seperti 'mc_'. | None |
odps.external.data.enable.extension | Tambahkan properti ini untuk menampilkan ekstensi file output. | True menunjukkan bahwa ekstensi file output ditampilkan. False menunjukkan bahwa ekstensi tidak ditampilkan. |
| False |
odps.external.data.output.suffix | Tambahkan properti ini untuk menentukan akhiran kustom untuk nama file output. | Akhiran hanya boleh berisi angka, huruf, dan garis bawah (a-z, A-Z, 0-9, dan _). | Kombinasi karakter valid, seperti '_hangzhou'. | None |
odps.external.data.output.explicit.extension | Tambahkan properti ini untuk menentukan ekstensi kustom untuk file output. |
| Kombinasi karakter valid, seperti "jsonl". | None |
mcfed.parquet.compression | Tambahkan properti ini ketika Anda perlu menulis data Parquet ke OSS dalam format terkompresi. | Properti kompresi Parquet. Secara default, data Parquet tidak dikompresi. |
| 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 Anda menulis data ke tabel eksternal Parquet, properti ini membatasi jumlah catatan dalam setiap grup baris untuk mencegah error kehabisan memori (OOM). | Properti tuning Parquet. Mengontrol jumlah maksimum catatan per grup baris. Jika terjadi error OOM, kurangi nilai parameter ini. Saran penggunaan parameter:
| Bilangan bulat non-negatif | 2147483647 (Integer.MAX_VALUE) |
mcfed.parquet.page.size.row.check.min | Saat Anda menulis data ke tabel eksternal Parquet, properti ini mengontrol frekuensi pemeriksaan memori untuk mencegah error OOM. | Properti tuning Parquet. Membatasi jumlah minimum catatan antara pemeriksaan memori. Jika terjadi error OOM, kurangi nilai parameter ini. | Bilangan bulat non-negatif | 100 |
mcfed.parquet.page.size.row.check.max | Saat Anda menulis data ke tabel eksternal Parquet, properti ini mengontrol frekuensi pemeriksaan memori untuk mencegah error OOM. | Properti tuning Parquet. Parameter ini menentukan jumlah minimum catatan antara pemeriksaan memori. Jika terjadi error kehabisan memori (OOM), Anda dapat mengurangi nilai parameter ini. Menyesuaikan parameter ini dapat menimbulkan overhead tambahan karena penggunaan memori sering dihitung. Saran penggunaan parameter:
| Bilangan bulat non-negatif | 1000 |
mcfed.parquet.compression.codec.zstd.level | Tambahkan properti ini untuk menentukan tingkat kompresi algoritma kompresi ZSTD saat Anda perlu menulis data Parquet ke OSS dalam format terkompresi ZSTD. | Properti kompresi Parquet. Menentukan tingkat kompresi algoritma kompresi ZSTD. Nilai valid: 1 hingga 22. | Bilangan bulat non-negatif | 3 |
Menulis data
Untuk informasi lebih lanjut mengenai sintaks penulisan MaxCompute, lihat Sintaks penulisan.
Kueri dan analisis
Untuk informasi lebih lanjut mengenai sintaks SELECT, lihat Sintaks kueri.
Untuk informasi lebih lanjut mengenai optimasi rencana kueri, lihat Optimasi kueri.
Untuk membaca data langsung dari file yang ditentukan oleh LOCATION, lihat Fitur: Schemaless Query.
Optimasi kueri: Tabel eksternal Parquet mendukung optimasi kueri dengan mengaktifkan Predicate Push Down (PPD). Untuk informasi lebih lanjut mengenai hasil performa, lihat Dukungan untuk Predicate Push Down (Parquet PPD).
Tambahkan parameter berikut sebelum pernyataan SQL untuk mengaktifkan PPD:
-- Parameter PPD harus digunakan dalam mode Native. Saklar mode Native harus diatur ke true. -- Aktifkan reader native Parquet. SET odps.ext.parquet.native = true; -- Aktifkan Parquet PPD. SET odps.sql.parquet.use.predicate.pushdown = true;
Dukungan untuk Predicate Push Down (Parquet PPD)
Secara default, tabel eksternal Parquet tidak mendukung Parquet PPD. Saat menjalankan kueri dengan kondisi filter WHERE, MaxCompute memindai semua data. Hal ini dapat menyebabkan operasi I/O yang tidak perlu, konsumsi resource, dan latensi kueri. Untuk mengatasi masalah ini, MaxCompute menyediakan parameter untuk mengaktifkan Parquet PPD. Fitur ini menggunakan metadata dalam file Parquet untuk memfilter data pada tingkat grup baris selama fase pemindaian, sehingga meningkatkan performa kueri serta mengurangi konsumsi resource dan biaya.
Penggunaan
Aktifkan Parquet PPD
Sebelum menjalankan kueri SQL, jalankan perintah
setuntuk mengatur dua parameter tingkat sesi berikut guna mengaktifkan Parquet PPD.-- Aktifkan reader 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 TPCDS 1 TB dan tabel eksternal Parquet
tpcds_1t_store_sales. PPD diaktifkan dan kueri filter dieksekusi. Total volume data adalah2.879.987.999baris.-- 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/'; -- Gunakan set data uji TPCDS 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 mengurangi latensi kueri dan konsumsi resource.
Mode | Total baris dalam tabel | Baris yang dipindai | Byte yang dipindai | Durasi Mapper | Total konsumsi resource | Deskripsi |
Tabel eksternal Parquet + PPD dinonaktifkan | 2.879.987.999 | 2.879.987.999 (100%) | 19.386.793.984 (100%) | 18 detik | cpu 19,25 Core × Min, memori 24,07 GB × Min 100% | |
Tabel eksternal Parquet + PPD diaktifkan | 2879987999 | 762.366.649 (26,47%) | 3.339.386.880 (17,22%) | 12 detik | cpu 11,47 Core × Min, memori 14,33 GB × Min ~59,58% | Setelah volume data yang dipindai berkurang, latensi dan konsumsi resource berkurang secara signifikan. |
Tabel internal + PPD diaktifkan | 2.879.987.999 | 32.830.000 (1,14%) | 1.633.880.386 (8,43%) | 9 detik | cpu 5,62 Core × Min, memori 7,02 GB × Min ~29,19% | Data dalam tabel internal diurutkan, sehingga efek PPD lebih signifikan. |
Rincian 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 tidak membaca data:

Log pemangkasan grup baris aktual:

Tabel internal + PPD diaktifkan
Data dalam tabel internal diurutkan, sehingga efek pemangkasan lebih signifikan.
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 menunjukkan cara membuat tabel eksternal untuk file Parquet yang dikompresi menggunakan ZSTD, lalu membaca dan menulis data ke tabel tersebut.
Prasyarat
Anda telah membuat proyek MaxCompute.
Persiapkan bucket dan folder OSS. Untuk informasi lebih lanjut, lihat Buat bucket dan Kelola folder.
MaxCompute hanya tersedia di beberapa wilayah. Untuk mencegah masalah konektivitas data, gunakan bucket OSS yang berada di wilayah yang sama dengan proyek MaxCompute Anda.
Otorisasi
Anda harus memiliki izin untuk mengakses OSS. Anda dapat menggunakan Akun Alibaba Cloud, Pengguna RAM, atau Peran RAM untuk mengakses tabel eksternal OSS. Untuk informasi lebih lanjut mengenai otorisasi, lihat Otorisasi STS untuk OSS.
Anda harus memiliki izin `CreateTable` dalam proyek MaxCompute. Untuk informasi lebih lanjut mengenai izin operasi tabel, lihat Izin MaxCompute.
Persiapkan file data dalam format ZSTD.
Dalam bucket
oss-mc-testyang dijelaskan di Data contoh, buat hierarki folderparquet_zstd_jni/dt=20230418, dan simpan file data di folder partisidt=20230418.Buat tabel eksternal Parquet untuk data 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/';Temukan partisi. Jika tabel eksternal OSS adalah tabel partisi, Anda harus melakukan operasi tambahan untuk memuat data partisi. Untuk informasi lebih lanjut, lihat Sintaks untuk menambahkan data partisi ke tabel eksternal OSS.
-- Temukan 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 sebagian 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 | +------------+------------+------------+------------+------------------+-------------------+----------------+------------+------------+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 = '20230606' AND recordId=16;Hasil berikut dikembalikan:
+------------+------------+------------+------------+------------------+-------------------+----------------+------------+------------+ | 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 dalam file Parquet tidak konsisten dengan tipe dalam pernyataan DDL untuk tabel eksternal
Pesan kesalahan
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 dalam file Parquet tidak konsisten dengan tipe INT dalam pernyataan DDL untuk tabel eksternal.
Solusi
Ubah tipe INT dalam pernyataan DDL untuk tabel eksternal menjadi BIGINT.
Error java.lang.OutOfMemoryError dilaporkan saat Anda menulis data ke tabel eksternal
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
Error kehabisan memori (OOM) dilaporkan saat sejumlah besar data ditulis ke tabel eksternal Parquet.
Solusi
Untuk mengatasi masalah ini, kurangi parameter
mcfed.parquet.block.row.count.limit. Jika error OOM tetap terjadi atau file output terlalu besar, Anda juga dapat mengurangi parametermcfed.parquet.page.size.row.check.maxuntuk memeriksa memori lebih sering. Untuk informasi lebih lanjut, lihat Parameter unik.Sebelum menulis data ke tabel eksternal Parquet, tambahkan parameter berikut.
-- Atur memori heap maksimum yang dapat digunakan oleh JVM UDF. SET odps.sql.udf.jvm.memory=12288; -- Kontrol ukuran batch di sisi runtime. SET odps.sql.executionengine.batch.rowcount =64; -- Atur ukuran memori untuk setiap pekerja Map. SET odps.stage.mapper.mem=12288; -- Ubah volume data input untuk setiap pekerja Map, yaitu ukuran shard file input. Ini secara tidak langsung mengontrol jumlah pekerja di setiap tahap Map. SET odps.stage.mapper.split.size=64;