Realtime Compute for Apache Flink mendukung pembacaan dari dan penulisan ke Object Storage Service (OSS) menggunakan filesystem connector. OSS menyediakan daya tahan data sebesar 99,9999999999% (dua belas angka 9) dan ketersediaan 99,995%, menjadikannya penyimpanan yang andal untuk pipeline Flink berskala besar.
| Kategori | Detail |
|---|---|
| Jenis tabel yang didukung | Tabel sumber dan tabel sink |
| Mode eksekusi | Batch dan stream |
| Format data | ORC, Parquet, Avro, CSV, JSON, dan raw |
| Metrik pemantauan spesifik | Tidak ada |
| Jenis API | DataStream API dan SQL |
| Memperbarui atau menghapus data di tabel sink | Hanya insert. Update dan delete tidak didukung. |
Batasan
Umum:
-
Hanya Ververica Runtime (VVR) 11 dan versi setelahnya yang mendukung pembacaan file terkompresi (GZIP, BZIP2, XZ, DEFLATE) dari OSS. VVR 8 tidak dapat memproses file terkompresi dengan benar.
-
Versi VVR sebelum 8.0.6 hanya mendukung bucket OSS dalam akun yang sama. Untuk mengakses bucket lintas akun, gunakan VVR 8.0.6 atau versi setelahnya dan konfigurasikan otentikasi bucket. Untuk detailnya, lihat Konfigurasikan otentikasi bucket.
-
Pembacaan inkremental partisi baru tidak didukung.
-
Akses OSS lintas wilayah tidak didukung. Bucket OSS harus berada di wilayah yang sama dengan ruang kerja Flink. OSS connector dibangun di atas antarmuka Filesystem, yang hanya mendukung satu titik akhir global. Mengakses bucket OSS di wilayah berbeda menyebabkan error ketidakcocokan titik akhir.
Hanya untuk tabel sink:
Format baris — Avro, CSV, JSON, dan raw — tidak didukung saat menulis ke OSS. Lihat FLINK-30635 untuk detailnya.
Sintaks
CREATE TABLE OssTable (
column_name1 INT,
column_name2 STRING,
...
datetime STRING,
`hour` STRING
) PARTITIONED BY (datetime, `hour`) WITH (
'connector' = 'filesystem', -- wajib: harus 'filesystem'
'path' = 'oss://<bucket>/path', -- wajib: URI dari path OSS
'format' = '...', -- wajib: orc, parquet, avro, csv, json, atau raw
'partition.default-name' = '...', -- opsional: nama partisi saat bidang partisi NULL atau kosong
'source.monitor-interval' = '...', -- opsional (hanya sumber): interval untuk memindai file baru
'auto-compaction' = '...' -- opsional (hanya sink): aktifkan kompaksi otomatis setelah setiap checkpoint
);
Kolom metadata
Tabel sumber mendukung kolom metadata yang menampilkan informasi tingkat file tentang setiap baris. Definisikan kolom metadata dalam DDL Anda dengan menambahkan METADATA setelah tipe data:
CREATE TABLE MyUserTableWithFilepath (
column_name1 INT,
column_name2 STRING,
`file.path` STRING NOT NULL METADATA
) WITH (
'connector' = 'filesystem',
'path' = 'oss://<bucket>/path',
'format' = 'json'
)
Kolom metadata berikut tersedia:
| Kunci | Tipe data | Deskripsi |
|---|---|---|
file.path |
STRING NOT NULL | Path lengkap file yang berisi baris tersebut. |
file.name |
STRING NOT NULL | Nama file (elemen terakhir dari path). |
file.size |
BIGINT NOT NULL | Ukuran file, dalam byte. |
file.modification-time |
TIMESTAMP_LTZ(3) NOT NULL | Waktu modifikasi terakhir file tersebut. |
Parameter WITH
Parameter umum
| Parameter | Wajib | Bawaan | Deskripsi |
|---|---|---|---|
connector |
Ya | — | Harus filesystem. |
path |
Ya | — | Path OSS dalam format URI, seperti oss://my_bucket/my_path. Untuk VVR 8.0.6 dan versi setelahnya, otentikasi bucket diperlukan setelah mengatur parameter ini. Lihat Konfigurasikan otentikasi bucket. |
format |
Ya | — | Format file: csv, json, avro, parquet, orc, atau raw. |
Parameter tabel sumber
| Parameter | Wajib | Bawaan | Deskripsi |
|---|---|---|---|
source.monitor-interval |
Tidak | — | Interval untuk memindai file baru. Harus lebih besar dari 0. Jika tidak diatur, path dipindai sekali dan sumber bersifat bounded. Setiap file diidentifikasi berdasarkan path-nya dan diproses tepat satu kali. Path file yang telah diproses disimpan dalam state dan dipertahankan melalui checkpoint dan savepoint. Interval yang lebih pendek mempercepat penemuan file tetapi meningkatkan frekuensi pemindaian. |
Parameter tabel sink
| Parameter | Wajib | Bawaan | Deskripsi |
|---|---|---|---|
partition.default-name |
Tidak | _DEFAULT_PARTITION__ |
Nama partisi yang digunakan saat bidang partisi bernilai NULL atau string kosong. |
sink.rolling-policy.file-size |
Tidak | 128 MB | Ukuran maksimum file bagian sebelum dilakukan rolling. Setiap subtask sink membuat setidaknya satu file bagian per partisi. Lihat Perilaku kebijakan rolling untuk mengetahui interaksinya dengan format file. |
sink.rolling-policy.rollover-interval |
Tidak | 30min | Durasi maksimum file bagian dapat tetap terbuka sebelum dilakukan rolling. Frekuensi pemeriksaan dikontrol oleh sink.rolling-policy.check-interval. |
sink.rolling-policy.check-interval |
Tidak | 1min | Seberapa sering memeriksa apakah file bagian harus dilakukan rolling berdasarkan sink.rolling-policy.rollover-interval. |
auto-compaction |
Tidak | false | Apakah akan mengaktifkan kompaksi otomatis. Data pertama kali ditulis ke file temporary. Setelah setiap checkpoint, file temporary dari checkpoint tersebut digabung menjadi file yang lebih besar. File temporary tidak terlihat sebelum penggabungan. Saat diaktifkan: hanya file dalam satu checkpoint yang digabung (setidaknya satu file per checkpoint); latensi visibilitas data sama dengan interval checkpoint + durasi kompaksi; proses kompaksi yang lama dapat menyebabkan backpressure dan menunda checkpoint. |
compaction.file-size |
Tidak | 128 MB | Ukuran target file untuk output hasil kompaksi. Nilai bawaan sama dengan sink.rolling-policy.file-size. |
sink.partition-commit.trigger |
Tidak | process-time |
Kapan partisi dikomit. Lihat Pemicu komit partisi. |
sink.partition-commit.delay |
Tidak | 0s |
Penundaan minimum sebelum mengkomit partisi. Atur ke 1 d untuk partisi harian, 1 h untuk partisi per jam. |
sink.partition-commit.watermark-time-zone |
Tidak | UTC |
Zona waktu untuk menguraikan watermark LONG menjadi TIMESTAMP guna perbandingan komit partisi. Hanya berlaku saat sink.partition-commit.trigger bernilai partition-time. Gunakan zona waktu sesi saat watermark didefinisikan pada kolom TIMESTAMP_LTZ (misalnya, Asia/Shanghai). Menerima nama zona waktu lengkap (seperti America/Los_Angeles) atau offset kustom (seperti GMT-08:00). Jika tidak dikonfigurasi dengan benar, komit partisi mungkin tertunda beberapa jam. |
partition.time-extractor.kind |
Tidak | default |
Cara mengekstrak waktu dari bidang partisi. default: konfigurasikan pola atau formatter timestamp. custom: tentukan kelas extractor. |
partition.time-extractor.class |
Tidak | — | Kelas yang mengimplementasikan antarmuka PartitionTimeExtractor. Wajib saat partition.time-extractor.kind bernilai custom. |
partition.time-extractor.timestamp-pattern |
Tidak | — | Pola untuk membangun timestamp dari bidang partisi. Secara bawaan, bidang pertama diekstrak menggunakan yyyy-MM-dd hh:mm:ss. Contoh: $dt (satu bidang), $year-$month-$day $hour:00:00 (beberapa bidang), $dt $hour:00:00 (dua bidang). |
partition.time-extractor.timestamp-formatter |
Tidak | yyyy-MM-dd HH:mm:ss |
Formatter untuk mengonversi string timestamp (sebagaimana dinyatakan oleh partition.time-extractor.timestamp-pattern) menjadi timestamp. Misalnya, jika partition.time-extractor.timestamp-pattern adalah $year$month$day, atur nilai ini ke yyyyMMdd. Kompatibel dengan DateTimeFormatter Java. |
sink.partition-commit.policy.kind |
Tidak | — | Cara memberi tahu konsumen downstream bahwa partisi siap. success-file: menulis file _SUCCESS ke direktori partisi. custom: menggunakan kelas yang mengimplementasikan PartitionCommitPolicy. Beberapa kebijakan dapat digabungkan. |
sink.partition-commit.policy.class |
Tidak | — | Kelas yang mengimplementasikan PartitionCommitPolicy. Wajib saat sink.partition-commit.policy.kind bernilai custom. |
sink.partition-commit.success-file.name |
Tidak | _SUCCESS |
Nama file success yang ditulis oleh kebijakan komit success-file. |
sink.parallelism |
Tidak | — | Paralelisme untuk operator penulisan file. Nilai bawaan mengikuti paralelisme operator upstream. Harus lebih besar dari 0. Saat auto-compaction diaktifkan, operator kompaksi juga menggunakan paralelisme ini. |
Perilaku kebijakan rolling
Perilaku rolling berbeda berdasarkan format file:
Untuk format kolom (Parquet, ORC, Avro), file bagian selalu dilakukan rolling saat checkpoint, meskipun kriteria kebijakan rolling belum terpenuhi. Ukuran file dan interval rollover berlaku sebagai pemicu tambahan antar checkpoint.
Untuk format baris (CSV, JSON, raw), file bagian hanya dilakukan rolling saat kriteria kebijakan rolling (sink.rolling-policy.file-sizeatausink.rolling-policy.rollover-interval) terpenuhi. Jika Anda membutuhkan visibilitas file dengan latensi rendah, sesuaikansink.rolling-policy.rollover-intervalbersamaan dengan interval checkpoint Anda.
Format baris tidak didukung untuk tabel sink OSS karena FLINK-30635. Perilaku di atas berlaku jika dukungan format baris ditambahkan di versi mendatang.
Pemicu komit partisi
Dua jenis pemicu tersedia untuk sink.partition-commit.trigger:
-
`process-time` (bawaan): Mengkomit partisi saat waktu sistem saat ini melebihi waktu pembuatan partisi ditambah
sink.partition-commit.delay. Tidak memerlukan watermark atau extractor waktu partisi. Lebih umum tetapi kurang presisi — penundaan atau kegagalan data dapat menyebabkan komit prematur. -
`partition-time`: Mengkomit partisi saat watermark melebihi waktu pembuatan partisi ditambah
sink.partition-commit.delay. Memerlukan pembangkitan watermark dan partisi berbasis waktu (per jam, harian, dan sebagainya).
Konfigurasikan otentikasi bucket
Hanya VVR 8.0.6 dan versi setelahnya yang mendukung otentikasi bucket.
Setelah mengatur parameter path, konfigurasikan otentikasi bucket agar Flink dapat membaca dari dan menulis ke path OSS yang ditentukan. Tambahkan konfigurasi berikut ke bagian Additional Configurations pada tab Parameters di halaman Deployment Details di Konsol pengembangan Realtime Compute:
fs.oss.bucket.<bucketName>.accessKeyId: <your-access-key-id>
fs.oss.bucket.<bucketName>.accessKeySecret: <your-access-key-secret>
Ganti <bucketName> dengan nama bucket yang digunakan dalam parameter path.
| Item konfigurasi | Deskripsi |
|---|---|
fs.oss.bucket.<bucketName>.accessKeyId |
ID AccessKey untuk bucket tersebut. Gunakan AccessKey yang sudah ada atau buat yang baru. Lihat Buat AccessKey. |
fs.oss.bucket.<bucketName>.accessKeySecret |
Rahasia AccessKey untuk bucket tersebut. |
Rahasia AccessKey hanya ditampilkan sekali saat dibuat. Simpan dengan aman.
Menulis ke OSS-HDFS
Tambahkan konfigurasi berikut ke bagian Additional Configurations pada tab Parameters di halaman Deployment Details di Konsol pengembangan Realtime Compute:
fs.oss.jindo.buckets: <bucket-names>
fs.oss.jindo.accessKeyId: <your-access-key-id>
fs.oss.jindo.accessKeySecret: <your-access-key-secret>
| Item konfigurasi | Deskripsi |
|---|---|
fs.oss.jindo.buckets |
Nama bucket OSS-HDFS, dipisahkan dengan titik koma. Saat Flink menulis ke path OSS, jika bucket yang sesuai tercantum di sini, data ditulis ke layanan OSS-HDFS. |
fs.oss.jindo.accessKeyId |
ID AccessKey. Lihat Buat AccessKey. |
fs.oss.jindo.accessKeySecret |
Rahasia AccessKey. |
Rahasia AccessKey hanya ditampilkan sekali saat dibuat. Simpan dengan aman.
Konfigurasikan titik akhir OSS-HDFS menggunakan salah satu metode berikut:
Konfigurasi parameter
Tambahkan titik akhir ke Additional Configurations:
fs.oss.jindo.endpoint: <oss-hdfs-endpoint>
Konfigurasi path
Sematkan titik akhir langsung dalam path OSS:
oss://<bucket-name>.<oss-hdfs-endpoint>/<directory>
Saat menggunakan metode ini, fs.oss.jindo.buckets harus mencakup <bucket-name>.<oss-hdfs-endpoint>.
Misalnya, jika nama bucket adalah jindo-test dan titik akhirnya adalah cn-beijing.oss-dls.aliyuncs.com:
# Path OSS
oss://jindo-test.cn-beijing.oss-dls.aliyuncs.com/<directory>
# Additional Configurations
fs.oss.jindo.buckets: jindo-test,jindo-test.cn-beijing.oss-dls.aliyuncs.com
Menulis ke Sistem File Terdistribusi Hadoop (HDFS) eksternal
Untuk path yang menggunakan skema hdfs://, tambahkan konfigurasi berikut untuk menentukan atau mengganti username akses:
containerized.taskmanager.env.HADOOP_USER_NAME: hdfs
containerized.master.env.HADOOP_USER_NAME: hdfs
Contoh
Baca dari OSS (tabel sumber)
CREATE TEMPORARY TABLE fs_table_source (
`id` INT,
`name` VARCHAR
) WITH (
'connector' = 'filesystem',
'path' = 'oss://<bucket>/path',
'format' = 'parquet'
);
CREATE TEMPORARY TABLE blackhole_sink (
`id` INT,
`name` VARCHAR
) WITH (
'connector' = 'blackhole'
);
INSERT INTO blackhole_sink SELECT * FROM fs_table_source;
Menulis ke OSS (tabel sink)
Menulis ke tabel partisi
Contoh ini melakukan streaming data dari sumber datagen, mempartisi berdasarkan tanggal dan jam, serta mengkomit partisi menggunakan pemicu partition-time:
CREATE TABLE datagen_source (
user_id STRING,
order_amount DOUBLE,
ts BIGINT, -- Timestamp dalam milidetik
ts_ltz AS TO_TIMESTAMP_LTZ(ts, 3),
WATERMARK FOR ts_ltz AS ts_ltz - INTERVAL '5' SECOND -- Watermark pada kolom TIMESTAMP_LTZ
) WITH (
'connector' = 'datagen'
);
CREATE TEMPORARY TABLE fs_table_sink (
user_id STRING,
order_amount DOUBLE,
dt STRING,
`hour` STRING
) PARTITIONED BY (dt, `hour`) WITH (
'connector' = 'filesystem',
'path' = 'oss://<bucket>/path',
'format' = 'parquet',
'partition.time-extractor.timestamp-pattern' = '$dt $hour:00:00',
'sink.partition-commit.delay' = '1 h',
'sink.partition-commit.trigger' = 'partition-time',
'sink.partition-commit.watermark-time-zone' = 'Asia/Shanghai',
'sink.partition-commit.policy.kind' = 'success-file'
);
INSERT INTO fs_table_sink
SELECT
user_id,
order_amount,
DATE_FORMAT(ts_ltz, 'yyyy-MM-dd'),
DATE_FORMAT(ts_ltz, 'HH')
FROM datagen_source;
Menulis ke tabel non-partisi
CREATE TABLE datagen_source (
user_id STRING,
order_amount DOUBLE
) WITH (
'connector' = 'datagen'
);
CREATE TEMPORARY TABLE fs_table_sink (
user_id STRING,
order_amount DOUBLE
) WITH (
'connector' = 'filesystem',
'path' = 'oss://<bucket>/path',
'format' = 'parquet'
);
INSERT INTO fs_table_sink SELECT * FROM datagen_source;
DataStream API
Untuk menggunakan DataStream API, siapkan terlebih dahulu connector DataStream. Lihat Gunakan connector DataStream.
Contoh berikut menggunakan StreamingFileSink dengan OnCheckpointRollingPolicy untuk menulis ke OSS. File bagian dilakukan rolling pada setiap checkpoint.
String outputPath = "oss://<bucket>/path";
final StreamingFileSink<Row> sink =
StreamingFileSink.forRowFormat(
new Path(outputPath),
(Encoder<Row>) (element, stream) -> {
out.println(element.toString());
})
.withRollingPolicy(OnCheckpointRollingPolicy.build())
.build();
outputStream.addSink(sink);
Untuk menulis ke OSS-HDFS, konfigurasikan juga parameter OSS-HDFS di Additional Configurations. Lihat Menulis ke OSS-HDFS.