All Products
Search
Document Center

Realtime Compute for Apache Flink:Penyimpanan aliran Fluss

Last Updated:Aug 21, 2026

Pelajari cara menggunakan konektor Stream Storage Fluss.

Informasi latar belakang

Fluss menggunakan arsitektur integrasi lake-stream yang terintegrasi secara mulus dengan format data lake seperti Apache Paimon untuk menyediakan pemrosesan data berlatensi rendah dan secara signifikan mengurangi biaya pembangunan serta pemeliharaan gudang data real-time. Fluss membantu perusahaan menghilangkan silodata, mempercepat analitik mendalam, dan berbagi data secara efisien dalam data lake mereka dengan menyediakan mekanisme terpadu untuk sinergi aliran data dan lakehouse.

Kategori

Deskripsi

Jenis yang didukung

Tabel sumber, tabel dimensi, dan tabel hasil, serta sink ingesti data.

Mode eksekusi

Mode streaming dan mode batch.

Format data

Belum didukung.

Jenis API

SQL dan YAML ingesti data.

Dukungan untuk pembaruan dan penghapusan tabel hasil

Ya.

Buat katalog kustom

Fluss berkembang lebih cepat daripada Realtime Compute for Apache Flink. Paket Catalog kustom terbaru disediakan di sini agar Anda dapat mencoba fitur Fluss Catalog yang belum dirilis bersama versi VVR. Untuk informasi selengkapnya, lihat Daftarkan Katalog Fluss.

SQL

Konektor Fluss dapat digunakan sebagai tabel sumber, tabel dimensi, atau tabel hasil dalam pekerjaan SQL. Untuk informasi selengkapnya, lihat Integrasi Mesin - Flink.

Prasyarat

  • Anda memiliki izin baca dan tulis untuk tabel Fluss target. Untuk informasi selengkapnya, lihat Berikan akses ke kluster Fluss.

  • Ruang kerja Flink dan kluster Fluss harus berada dalam VPC yang sama.

  • Anda telah membuat Katalog Fluss di Konsol Flink. Untuk detailnya, lihat Buat Katalog Fluss.

Fitur utama

Konektor Fluss menyediakan fitur-fitur utama berikut:

Fitur

Deskripsi

konsumsi lengkap dan inkremental terpadu

Mendukung konsumsi lengkap, inkremental, dan konsumsi lengkap dan inkremental terpadu.

eksplorasi data

Fluss mendukung eksplorasi data cepat dalam mode batch Flink SQL, yang berguna untuk pengembangan data, debugging, validasi data, dan troubleshooting.

langganan log CDC dan tabel virtual

Tabel kunci primer Fluss menawarkan dukungan native untuk langganan log Change Data Capture (CDC), memungkinkan pekerjaan Flink downstream mengonsumsi aliran lengkap event perubahan (INSERT, UPDATE_BEFORE, UPDATE_AFTER, dan DELETE) secara real-time.

lookup join (join tabel dimensi)

Dukungannya terhadap lookup point key-value (KV) dan lookup indeks sekunder yang efisien menjadikan Fluss ideal untuk skenario join tabel dimensi berlatensi rendah.

pembaruan parsial

Hanya memperbarui data di kolom yang dimodifikasi, bukan seluruh baris.

delta join

Solusi join baru ini mempertahankan semantik join dual-stream dengan mendorong operasi pembaruan data ke tabel Fluss. Proses ini secara signifikan mengurangi konsumsi resource Flink dan meningkatkan stabilitas serta efisiensi eksekusi pekerjaan.

mesin merge

Tabel kunci primer Fluss memungkinkan Anda mengonfigurasi mesin merge yang berbeda untuk mengontrol bagaimana catatan dengan kunci primer yang sama digabungkan.

integrasi lake-stream

Menyediakan integrasi mendalam antara penyimpanan aliran real-time (Fluss) dengan data lake berbasis Paimon tempat metadata dikelola oleh Data Lake Formation (DLF). Model "satu data, dua tampilan" ini memungkinkan satu tabel logis tunggal menawarkan akses data real-time berlatensi rendah sekaligus analisis data historis ber-throughput tinggi.

tabel partisi

Mendukung pembuatan tabel partisi, membaca dari dan menulis ke tabel tersebut, serta secara otomatis menangani pembuatan dan pembersihan partisi.

tambah kolom

Memungkinkan Anda menambahkan kolom secara dinamis tanpa mengganggu pekerjaan baca dan tulis yang sedang berjalan.

Batasan

  • Tabel log hanya mendukung operasi INSERT, tidak mendukung UPDATE atau DELETE.

  • Tabel kunci primer mendukung operasi INSERT, UPDATE, dan DELETE.

  • Lookup join hanya didukung pada tabel dimensi yang juga merupakan tabel kunci primer. Kondisi join harus mencakup semua bidang kunci primer.

  • Untuk Delta join, kedua tabel harus merupakan tabel kunci primer Fluss, dan kunci join harus mencakup kunci bucket.

Pertimbangan

  • Tabel Fluss tersedia dalam dua jenis: tabel log, yang tidak memiliki kunci primer dan mirip dengan topik Kafka, dan tabel kunci primer, yang memiliki kunci primer dan mendukung semantik upsert. Pilih jenis tabel yang paling sesuai dengan kasus penggunaan Anda.

  • Di lingkungan produksi, konfigurasikan dengan tepat parameter bucket.num untuk memastikan kinerja baca dan tulis paralel yang optimal serta distribusi data yang seimbang.

  • Untuk tabel partisi, rancang strategi partisi Anda berdasarkan volume data dan pola kueri. Pilih granularitas waktu yang sesuai (misalnya harian atau bulanan) dan gunakan parameter table.auto-partition.num-retention untuk mengontrol jumlah partisi historis yang dipertahankan, mencegah pembengkakan metadata. Jika tabel kunci primer berisi data dengan karakteristik partisi alami (seperti berdasarkan waktu atau dimensi bisnis), gunakan tabel partisi alih-alih menyimpan semua data dalam satu tabel non-partisi. Tabel partisi menyederhanakan manajemen siklus hidup data dan memungkinkan pemangkasan partisi untuk kueri streaming dan batch, yang secara signifikan mengurangi pemindaian data yang tidak perlu dan meningkatkan kinerja kueri.

  • Sebelum menggunakan Delta Join, konfigurasikan parameter runtime yang diperlukan dalam pekerjaan Flink Anda untuk mengaktifkan optimasi ini.

Fitur

Konsumsi lengkap dan inkremental

Ikhtisar

Tabel kunci primer Fluss mendukung konsumsi lengkap dan inkremental. Sistem pertama-tama membaca snapshot historis lengkap dari tabel tersebut. Setelah pembacaan snapshot selesai, sistem secara otomatis dan mulus beralih ke konsumsi aliran inkremental. Proses ini memastikan kelengkapan dan konsistensi data.

Mode konsumsi

Anda dapat mengontrol titik awal konsumsi menggunakan parameter scan.startup.mode.

Mode

Deskripsi

full

Bawaan. Pertama-tama membaca snapshot lengkap, lalu mengonsumsi data inkremental. Mode ini cocok untuk skenario yang memerlukan data historis lengkap.

earliest

Mengonsumsi data dari offset log paling awal yang tersedia tanpa membaca snapshot lengkap.

latest

Mengonsumsi data dari offset terbaru. Hanya data baru yang dihasilkan setelah pekerjaan dimulai yang dikonsumsi.

timestamp

Mengonsumsi data dari timestamp tertentu. Mode ini mengharuskan Anda juga mengatur parameter scan.startup.timestamp.

Contoh SQL
-- Konsumsi lengkap dan inkremental (mode bawaan)
SELECT * FROM `fluss_catalog`.`fluss_db`.orders;

-- Mengonsumsi dari timestamp tertentu menggunakan petunjuk
SELECT * FROM `fluss_catalog`.`fluss_db`.orders
  /*+ OPTIONS('scan.startup.mode' = 'timestamp', 'scan.startup.timestamp' = '2025-01-01 00:00:00') */;

-- Mengonsumsi dari offset terbaru
SELECT * FROM `fluss_catalog`.`fluss_db`.orders
  /*+ OPTIONS('scan.startup.mode' = 'latest') */;

Langganan log CDC dan tabel virtual

Langganan log

Tabel kunci primer Fluss secara native mendukung langganan log CDC (Change Data Capture). Hal ini memungkinkan pekerjaan Flink downstream mengonsumsi aliran changelog lengkap (event INSERT, UPDATE_BEFORE, UPDATE_AFTER, dan DELETE) secara real-time tanpa memerlukan konfigurasi binlog terpisah.

Artinya:

  • Semua perubahan pada tabel kunci primer secara otomatis menghasilkan log CDC.

  • Aplikasi downstream dapat langsung berlangganan ke tabel kunci primer untuk menerima aliran changelog lengkap guna sinkronisasi data real-time atau ETL streaming.

Contoh SQL
-- Baca tabel kunci primer secara langsung untuk mendapatkan aliran changelog CDC
SELECT * FROM `fluss_catalog`.`fluss_db`.orders;
-- Output mencakup event INSERT, UPDATE, dan DELETE lengkap.
Tabel virtual

Selain berlangganan langsung ke aliran CDC, Fluss menyediakan mekanisme tabel virtual. Anda dapat mengakses changelog dengan metadata dengan menambahkan akhiran tertentu ke nama tabel dasar, yang menghilangkan kebutuhan akan penyimpanan data tambahan. Sistem menghasilkan tabel virtual ini secara otomatis, sehingga tidak perlu dibuat secara manual.

Tabel changelog ($changelog)

Fitur ini berlaku untuk tabel kunci primer dan tabel append-only serta menyediakan aliran changelog mentah dengan metadata.

Struktur tabel (Sistem secara otomatis menambahkan kolom metadata berikut ke skema tabel asli):

Kolom metadata

Tipe

Deskripsi

_change_type

STRING

Jenis perubahan. Untuk tabel kunci primer, nilai yang mungkin adalah insert, update_before, update_after, dan delete. Untuk tabel append-only, satu-satunya nilai yang mungkin adalah insert.

_log_offset

BIGINT

Offset perubahan dalam log.

_commit_timestamp

TIMESTAMP_LTZ

Timestamp commit perubahan.

Contoh SQL:

-- Baca tabel virtual $changelog untuk tabel orders
SELECT * FROM `fluss_catalog`.`fluss_db`.orders$changelog;

-- Mengonsumsi dari offset terbaru menggunakan petunjuk
SELECT * FROM `fluss_catalog`.`fluss_db`.orders$changelog
  /*+ OPTIONS('scan.startup.mode' = 'latest') */;

-- Filter untuk event penghapusan
SELECT * FROM `fluss_catalog`.`fluss_db`.orders$changelog
WHERE _change_type = 'delete';
Tabel binlog ($binlog)

Fitur ini hanya tersedia untuk tabel kunci primer dan menyediakan data dalam format Binlog yang mencakup gambar before/after, sehingga memudahkan untuk mengambil secara akurat status data sebelum dan sesudah setiap perubahan.

Struktur tabel (Selain kolom metadata, data baris before dan after lengkap disajikan dalam tipe ROW bersarang):

Kolom

Tipe

Deskripsi

_change_type

STRING

Jenis perubahan. Nilai yang mungkin adalah insert, update, dan delete.

_log_offset

BIGINT

Offset log.

_commit_timestamp

TIMESTAMP_LTZ

Stempel waktu commit.

before

ROW

Data baris sebelum perubahan. Nilainya NULL untuk operasi insert.

after

ROW

Data baris setelah perubahan. Nilainya NULL untuk operasi delete.

Ubah pemetaan event:

Jenis perubahan

before

after

insert

NULL

Nilai baru

update

Nilai lama

Nilai baru

delete

Nilai lama

NULL

Contoh SQL:

-- Baca tabel virtual $binlog untuk tabel users
SELECT * FROM `fluss_catalog`.`fluss_db`.users$binlog;

-- Dapatkan nilai before dan after suatu bidang dari event update
SELECT
  `before`.user_name AS old_name,
  `after`.user_name  AS new_name,
  _commit_timestamp  AS change_time
FROM `fluss_catalog`.`fluss_db`.users$binlog
WHERE _change_type = 'update';
Batasan
  • Tabel $changelog dan $binlog saat ini tidak mendukung projection pushdown, partition pruning, atau predicate pushdown.

  • Tabel $binlog hanya tersedia untuk tabel kunci primer. Tidak didukung untuk tabel append-only.

  • Mode startup yang didukung untuk tabel virtual adalah earliest (bawaan), latest, dan timestamp. Mode full tidak didukung.


Pembaruan parsial

Ikhtisar

Fluss mendukung pembaruan parsial, yang memungkinkan beberapa aliran data menulis secara independen ke kolom masing-masing dalam tabel kunci primer lebar yang sama. Mesin Fluss secara otomatis menggabungkan bidang-bidang tersebut pada level catatan berdasarkan kunci primer. Pendekatan ini menghindari kebutuhan untuk memelihara state join multi-aliran yang kompleks di Flink dan mencegah masalah terkait ukuran state yang besar.

Kasus penggunaan

Kasus penggunaan khas adalah membangun tabel lebar profil pengguna real-time. Berbagai sumber data, seperti sistem rekomendasi, log impresi, log klik, dan data keranjang belanja, dapat memperbarui bidang masing-masing dalam tabel profil pengguna. Proses ini menciptakan tampilan 360 derajat lengkap tentang pengguna.

Batasan
  • Tabel target harus berupa tabel kunci primer.

  • Operasi tulis setiap aliran data harus mencakup semua bidang kunci primer.

  • Topologi komputasi tidak boleh mengandung node join multi-aliran. Fluss menangani operasi merge langsung di lapisan penyimpanan.

Contoh SQL
-- 1. Buat tabel lebar
CREATE TABLE IF NOT EXISTS `fluss_catalog`.fluss_db.user_rec_wide (
    user_id   STRING,
    item_id   STRING,
    rec_score DOUBLE,
    imp_cnt   INT,
    click_cnt INT,
    PRIMARY KEY (user_id, item_id) NOT ENFORCED
) WITH ('bucket.num' = '3');

-- 2. Gunakan beberapa aliran untuk menulis ke bidang masing-masing
-- Aliran 1: Menulis skor rekomendasi
INSERT INTO `fluss_catalog`.fluss_db.user_rec_wide (user_id, item_id, rec_score)
SELECT user_id, item_id, rec_score 
FROM `fluss_catalog`.fluss_db.recommendations;

-- Aliran 2: Menulis jumlah impresi
INSERT INTO `fluss_catalog`.fluss_db.user_rec_wide (user_id, item_id, imp_cnt)
SELECT user_id, item_id, imp_cnt 
FROM `fluss_catalog`.fluss_db.impressions;

-- Aliran 3: Menulis jumlah klik
INSERT INTO `fluss_catalog`.fluss_db.user_rec_wide (user_id, item_id, click_cnt)
SELECT user_id, item_id, click_cnt 
FROM `fluss_catalog`.fluss_db.clicks;

Tiga pernyataan INSERT di atas dapat dijalankan sebagai pekerjaan Flink terpisah. Lapisan penyimpanan Fluss secara otomatis menggabungkan bidang-bidang tersebut untuk kunci primer yang sama menjadi baris-baris lengkap.


Delta Join

Ikhtisar

Delta Join adalah paradigma join aliran-aliran generasi berikutnya yang disediakan oleh Fluss. Paradigma ini memindahkan operasi pembaruan data ke lapisan penyimpanan Fluss, memanfaatkan tabel kunci primer dan indeks sekunder untuk lookup yang efisien. Desain ini menghilangkan kebutuhan untuk memelihara state join di Flink.

Keunggulan utama:

  • Tidak ada state join: Menghilangkan penyimpanan state berlebih dan menghindari masalah garbage collection (GC) yang disebabkan oleh ukuran state besar.

  • Konsumsi resource rendah: Mengurangi konsumsi memori dan CPU Flink hingga lebih dari 86% dalam pengujian.

  • Stabilitas dan efisiensi lebih baik: Menghindari bottleneck kinerja yang disebabkan oleh pembengkakan state.

Perbandingan dengan join tradisional

Fitur

Join Flink tradisional (dengan Kafka)

Fluss Delta Join

Penyimpanan State

Memerlukan caching semua data upstream di Flink.

Tidak ada state join; mengandalkan indeks Fluss.

Konsumsi Resource

Tinggi, karena GC sering akibat state besar.

Rendah

Stabilitas

Rentan terhadap masalah akibat pembengkakan state.

Lebih stabil

Mekanisme

Pembaruan dari kedua aliran mendorong join.

Fluss memindahkan pembaruan ke lapisan penyimpanannya.

Kasus Penggunaan

Join antar-aliran tujuan umum.

Join efisien antara tabel kunci primer Fluss.

Batasan
  • Baik tabel kiri maupun kanan harus berupa tabel kunci primer Fluss (tabel partisi didukung).

  • Kunci bucket harus merupakan awalan dari kunci primer.

  • Kunci join harus mencakup kunci bucket. Untuk tabel partisi, kunci join juga harus mencakup kunci partisi.

Contoh SQL

1. Buat tabel

CREATE TABLE orders (
  user_id BIGINT,
  order_date DATE,
  order_id BIGINT,
  amount DECIMAL(10, 2),
  PRIMARY KEY (user_id, order_id, order_date) NOT ENFORCED
) WITH ('bucket.key' = 'user_id, order_id');

CREATE TABLE order_enhance (
  user_id BIGINT,
  order_id BIGINT,
  risk_level TINYINT,
  is_fraud BOOLEAN,
  update_time TIMESTAMP(3),
  PRIMARY KEY (user_id, order_id) NOT ENFORCED
) WITH ('bucket.key' = 'user_id, order_id');

2. Jalankan Delta Join

SELECT * FROM orders o
INNER JOIN order_enhance e
ON o.user_id = e.user_id AND o.order_id = e.order_id;

3. Optimalkan kinerja lookup dengan petunjuk

SELECT * FROM orders o /*+ OPTIONS('client.lookup.queue-size'='2560') */
INNER JOIN order_enhance e /*+ OPTIONS('client.lookup.queue-size'='2560') */
ON o.user_id = e.user_id AND o.order_id = e.order_id;
Konfigurasi parameter pekerjaan

Untuk menggunakan Delta Join, tambahkan konfigurasi berikut ke parameter runtime pekerjaan Flink Anda:

table.exec.delta-join.cache-enabled: 'true'
table.exec.async-lookup.buffer-capacity: '3000'
table.optimizer.delta-join.strategy: FORCE
table.exec.delta-join.left.cache-size: '100'
table.exec.delta-join.right.cache-size: '1000'

Parameter

Deskripsi

table.optimizer.delta-join.strategy

Atur ke FORCE untuk memaksakan Delta Join. Pekerjaan gagal jika kondisi tidak terpenuhi.

table.exec.async-lookup.buffer-capacity

Kapasitas buffer untuk permintaan asinkron. Kami merekomendasikan mengatur nilai ini dalam ribuan.

table.exec.delta-join.cache-enabled

Mengaktifkan caching lokal untuk mengurangi permintaan ke Fluss.

table.exec.delta-join.left.cache-size

Jumlah kunci yang dicache untuk tabel kiri. Sesuaikan nilai ini berdasarkan memori dan pola data panas.

table.exec.delta-join.right.cache-size

Jumlah kunci yang dicache untuk tabel kanan. Sesuaikan nilai ini berdasarkan memori dan pola data panas.

Setelah Anda mengaktifkan Delta Join, node Delta Join muncul dalam ikhtisar pekerjaan Flink, menunjukkan bahwa optimasi aktif.


Lookup join (join tabel dimensi)

Ikhtisar

Anda dapat menggunakan tabel kunci primer Fluss sebagai tabel dimensi Flink SQL. Lookup join memungkinkan Anda memperkaya data streaming dengan data dimensi secara real-time. Fluss mendukung lookup point KV dan pencarian indeks sekunder yang efisien, sehingga cocok untuk skenario join tabel dimensi berlatensi rendah.

Batasan
  • Hanya tabel kunci primer yang dapat digunakan sebagai tabel dimensi.

  • Kondisi join harus mencakup semua bidang kunci primer dari tabel dimensi.

Mode sinkron dan asinkron

Mode

Konfigurasi

Deskripsi

Asinkron (bawaan)

'lookup.async' = 'true'

Memberikan throughput tinggi. Direkomendasikan untuk sebagian besar kasus penggunaan.

Sinkron

'lookup.async' = 'false'

Meminta catatan secara berurutan. Cocok untuk debugging atau skenario konkurensi rendah.

Contoh SQL
-- Konfigurasikan cache lookup menggunakan petunjuk untuk melakukan join tabel dimensi
SELECT
  o.order_id,
  o.amount,
  u.user_name,
  p.product_name
FROM `fluss_catalog`.`fluss_db`.orders AS o
LEFT JOIN `fluss_catalog`.`fluss_db`.user_dim
  /*+ OPTIONS('lookup.cache' = 'PARTIAL', 'lookup.partial-cache.expire-after-write' = '60s', 'lookup.partial-cache.max-rows' = '10000') */
  FOR SYSTEM_TIME AS OF o.proctime AS u
  ON o.user_id = u.user_id
LEFT JOIN `fluss_catalog`.`fluss_db`.product_dim
  FOR SYSTEM_TIME AS OF o.proctime AS p
  ON o.product_id = p.product_id;

-- Gunakan mode lookup sinkron (cocok untuk debugging)
SELECT o.order_id, o.amount, d.user_name
FROM `fluss_catalog`.`fluss_db`.orders AS o
LEFT JOIN `fluss_catalog`.`fluss_db`.user_dim
  /*+ OPTIONS('lookup.async' = 'false') */
  FOR SYSTEM_TIME AS OF o.proctime AS d
  ON o.user_id = d.user_id;

Mesin Penggabungan

Ikhtisar

Tabel kunci primer Fluss memungkinkan Anda mengonfigurasi mesin merge untuk mengontrol bagaimana sistem menggabungkan catatan dengan kunci primer yang sama. Gunakan parameter table.merge-engine untuk memilih salah satu strategi berikut:

Mesin merge

Deskripsi

last_row (bawaan)

Menyimpan catatan yang ditulis terakhir. Data yang lebih baru menimpa data yang lebih lama. Mesin ini cocok untuk sebagian besar skenario upsert.

first_row

Menyimpan catatan yang ditulis pertama, mengabaikan data berikutnya dengan kunci primer yang sama. Mesin ini cocok untuk skenario deduplikasi, seperti deduplikasi log.

versioned

Menyimpan catatan dengan nomor versi tertinggi dari kolom versi yang ditentukan. Memerlukan parameter table.merge-engine.versioned.ver-column untuk menentukan kolom versi. Mesin ini cocok untuk skenario yang memerlukan pengendalian urutan pembaruan data berdasarkan versi.

Contoh SQL
-- Gunakan first_row untuk deduplikasi
CREATE TABLE IF NOT EXISTS `fluss_catalog`.fluss_db.event_dedup (
    event_id STRING,
    event_type STRING,
    event_time TIMESTAMP(3),
    payload STRING,
    PRIMARY KEY (event_id) NOT ENFORCED
) WITH (
  'table.merge-engine' = 'first_row'
);

-- Gunakan versioned untuk memperbarui berdasarkan kolom versi
CREATE TABLE IF NOT EXISTS `fluss_catalog`.fluss_db.user_profile (
    user_id BIGINT,
    user_name STRING,
    age INT,
    update_version BIGINT,
    PRIMARY KEY (user_id) NOT ENFORCED
) WITH (
  'table.merge-engine' = 'versioned',
  'table.merge-engine.versioned.ver-column' = 'update_version'
);

Tabel partisi

Ikhtisar

Fluss mendukung tabel partisi. Anda dapat menggunakan PARTITIONED BY untuk membagi data ke partisi fisik yang berbeda berdasarkan kunci partisi. Ini ideal untuk mengelola siklus hidup data dan meningkatkan kinerja kueri berdasarkan waktu atau dimensi bisnis. Tabel partisi mendukung partisi single-field dan partisi multi-field, serta menawarkan tiga strategi manajemen partisi ortogonal: manajemen manual, manajemen otomatis, dan pembuatan dinamis.

Aturan dasar
  • Tipe data kunci partisi harus berupa STRING.

  • Untuk tabel kunci primer, kunci partisi harus merupakan subset dari kunci primer.

  • Anda hanya dapat mengonfigurasi aturan partisi otomatis saat membuat tabel; Anda tidak dapat mengubahnya nanti.

Strategi manajemen partisi

Strategi

Deskripsi

Manajemen manual

Membuat atau menghapus partisi secara manual menggunakan ALTER TABLE. Strategi ini cocok untuk skenario dengan jumlah partisi yang terbatas dan terkendali.

Manajemen otomatis

Sistem secara otomatis membuat partisi baru dan membersihkan partisi historis yang kedaluwarsa berdasarkan aturan berbasis waktu. Strategi ini cocok untuk ingesti data berkelanjutan berbasis waktu.

Pembuatan dinamis

Saat data ditulis, klien secara otomatis membuat partisi target jika belum ada. Strategi ini cocok untuk skenario dengan nilai partisi yang tidak dapat diprediksi.

Ketiga strategi ini ortogonal dan dapat digunakan secara kombinasi. Misalnya, Anda dapat mengaktifkan manajemen otomatis untuk pembuatan dan pembersihan berbasis waktu, serta pembuatan dinamis sebagai cadangan untuk menangani partisi yang tidak dibuat sebelumnya.

Contoh SQL

1. Buat tabel partisi single-field dengan manajemen partisi otomatis

CREATE TABLE `fluss_catalog`.fluss_db.site_access (
  site_id BIGINT,
  user_name STRING,
  pv BIGINT,
  event_day STRING,
  PRIMARY KEY (site_id, event_day) NOT ENFORCED
) PARTITIONED BY (event_day) WITH (
  'table.auto-partition.enabled' = 'true',
  'table.auto-partition.time-unit' = 'DAY',
  'table.auto-partition.num-precreate' = '5',
  'table.auto-partition.num-retention' = '30',
  'table.auto-partition.time-zone' = 'Asia/Shanghai'
);

2. Buat tabel partisi multi-field

CREATE TABLE `fluss_catalog`.fluss_db.region_access (
  access_id BIGINT,
  user_name STRING,
  event_date STRING,
  region STRING,
  PRIMARY KEY (access_id, event_date, region) NOT ENFORCED
) PARTITIONED BY (event_date, region) WITH (
  'table.auto-partition.enabled' = 'true',
  'table.auto-partition.key' = 'event_date',
  'table.auto-partition.time-unit' = 'DAY',
  'table.auto-partition.num-retention' = '7'
);
Catatan: Untuk partisi multi-field, Anda harus menentukan kunci berbasis waktu untuk partisi otomatis menggunakan table.auto-partition.key. Partisi multi-field hanya mendukung kedaluwarsa dan pembersihan otomatis, bukan pembuatan pra-otomatis. Parameter num-precreate dipaksakan menjadi 0.

3. Kelola partisi secara manual

-- Lihat semua partisi
SHOW PARTITIONS `fluss_catalog`.fluss_db.site_access;

-- Tambahkan partisi secara manual
ALTER TABLE `fluss_catalog`.fluss_db.site_access
  ADD PARTITION (event_day = '20250315');

-- Hapus partisi secara manual
ALTER TABLE `fluss_catalog`.fluss_db.site_access
  DROP PARTITION (event_day = '20250101');

4. Buat partisi secara dinamis

Saat Anda menulis data, jika partisi target tidak ada, klien secara otomatis membuatnya. Fitur ini diaktifkan secara bawaan.

-- Tulis data. Jika partisi '20250701' tidak ada, partisi tersebut dibuat secara otomatis.
INSERT INTO `fluss_catalog`.fluss_db.site_access
VALUES (1, 'hello', 100, '20250701');

Parameter klien client.writer.dynamic-create-partition.enabled (bawaan: true) mengontrol pembuatan dinamis. Fitur ini tunduk pada batasan tingkat kluster max.partition.num (bawaan: 1000) dan max.bucket.num (bawaan: 128.000).

Pemangkasan partisi

Saat Anda mengkueri tabel partisi dalam mode streaming atau batch, Fluss mendukung pemangkasan partisi. Dengan memfilter berdasarkan kunci partisi dalam klausa WHERE, kueri hanya membaca partisi yang cocok, sehingga mengurangi overhead I/O yang tidak perlu.

-- Baca hanya data dari partisi untuk tanggal tertentu
SELECT * FROM `fluss_catalog`.`fluss_db`.site_access
WHERE event_day = '20250315';

-- Filter tabel partisi multi-field berdasarkan region
SELECT * FROM `fluss_catalog`.`fluss_db`.region_access
WHERE region = 'US';
Parameter partisi otomatis

Parameter

Tipe

Bawaan

Deskripsi

table.auto-partition.enabled

Boolean

false

Menentukan apakah akan mengaktifkan manajemen partisi otomatis.

table.auto-partition.key

String

None

Untuk partisi multi-field, menentukan kunci berbasis waktu untuk partisi otomatis. Parameter ini tidak diperlukan untuk partisi single-field.

table.auto-partition.time-unit

Enum

DAY

Granularitas waktu untuk partisi otomatis. Nilai yang valid adalah HOUR, DAY, MONTH, QUARTER, dan YEAR.

table.auto-partition.num-precreate

Integer

2

Jumlah partisi masa depan yang akan dibuat sebelumnya. Tidak didukung untuk partisi multi-field, di mana nilainya dipaksakan menjadi 0.

table.auto-partition.num-retention

Integer

7

Jumlah partisi historis yang dipertahankan. Partisi yang kedaluwarsa melebihi batas ini dihapus secara otomatis.

table.auto-partition.time-zone

String

Zona waktu sistem

Zona waktu yang digunakan untuk partisi otomatis.

Praktik terbaik
  • Pilih granularitas partisi yang tepat: Pilih granularitas waktu berdasarkan volume data dan pola kueri Anda. Untuk volume data besar dan rentang waktu kueri sempit, kami merekomendasikan partisi berdasarkan DAY atau HOUR. Untuk volume data lebih kecil, Anda dapat mempartisi berdasarkan MONTH atau QUARTER.

  • Tetapkan kebijakan retensi yang wajar: Gunakan num-retention untuk mengontrol jumlah partisi historis. Hal ini membantu menghindari pembengkakan metadata dan mengurangi beban manajemen kluster akibat jumlah partisi yang berlebihan.

  • Kombinasikan manajemen otomatis dan pembuatan dinamis: Gunakan manajemen otomatis untuk pembuatan dan pembersihan partisi rutin berbasis waktu, serta gunakan pembuatan dinamis sebagai cadangan untuk menangani data abnormal atau tertunda.

  • Perhatikan batasan kluster: Parameter max.partition.num (bawaan: 1000) membatasi jumlah partisi per tabel. Jumlah total bucket dalam kluster dibatasi oleh max.bucket.num (bawaan: 128.000). Jumlah total bucket dalam tabel (jumlah partisi × bucket.num) tidak boleh melebihi batas ini.


Pushdown kueri streaming

Fluss menggunakan format penyimpanan kolom Apache Arrow untuk transmisi log. Hal ini mendukung mendorong operasi filter dan proyeksi ke lapisan penyimpanan, sehingga mengurangi volume transfer data dan dapat meningkatkan kinerja kueri hingga 10x.

Fitur ini sangat efektif dalam skenario berikut:

  • Membaca hanya subset kolom dari tabel lebar (projection pushdown).

  • Memfilter sejumlah besar data berdasarkan kondisi tertentu (predicate pushdown).

Format penyimpanan log dikontrol oleh parameter table.log.format, yang bawaannya adalah ARROW.


Arsitektur stream-lake terpadu

Ikhtisar

Fluss mendukung arsitektur stream-lake terpadu yang secara otomatis menyinkronkan data real-time dari Fluss ke data lake, seperti Apache Paimon. Hal ini mencapai penyimpanan bertingkat otomatis untuk data panas dan dingin, menyeimbangkan latensi rendah kueri real-time dengan biaya penyimpanan historis yang rendah.

Fitur utama:

  • Secara otomatis menulis data streaming dari Fluss ke penyimpanan lake Paimon.

  • Secara otomatis mengklasifikasikan data panas dan dingin. Data panas dipertahankan di penyimpanan aliran Fluss, sedangkan data dingin dipindahkan ke Paimon.

  • Menyediakan antarmuka kueri Flink SQL terpadu untuk mengakses data di penyimpanan aliran dan penyimpanan lake secara bersamaan.

Parameter konfigurasi

Parameter

Tipe

Bawaan

Deskripsi

table.datalake.enabled

Boolean

false

Mengaktifkan tiering penyimpanan lake.

table.datalake.format

Enum

Bawaan kluster

Format data lake. Saat ini, hanya paimon yang didukung.

table.log.tiered.local-segments

Integer

2

Jumlah segmen log yang dipertahankan secara lokal setelah tiering penyimpanan diaktifkan.


Eksplorasi data

Ikhtisar

Fluss mendukung eksplorasi data cepat pada tabel dalam mode batch Flink SQL, termasuk kueri LIMIT, lookup point kunci primer, dan agregasi COUNT(*). Anda dapat dengan cepat melihat data dalam tabel tanpa memulai pekerjaan streaming yang berjalan terus-menerus. Hal ini berguna untuk pengembangan, debugging, validasi data, dan troubleshooting.

Kueri LIMIT

Anda dapat menjalankan kueri LIMIT pada tabel kunci primer dan tabel append-only untuk dengan cepat mengambil sampel kecil data.

-- Lihat 10 catatan pertama dari tabel kunci primer
SELECT * FROM `fluss_catalog`.`fluss_db`.orders LIMIT 10;

-- Lihat 5 catatan pertama dari tabel append-only
SELECT * FROM `fluss_catalog`.`fluss_db`.events LIMIT 5;

-- Gabungkan dengan proyeksi untuk melihat hanya kolom tertentu
SELECT order_id, amount, order_time 
FROM `fluss_catalog`.`fluss_db`.orders LIMIT 20;
Lookup point kunci primer

Untuk tabel kunci primer, Anda dapat melakukan lookup point presisi dengan menentukan kunci primer dalam klausa WHERE. Hal ini memanfaatkan mesin penyimpanan KV Fluss untuk mencapai waktu respons tingkat milidetik.

-- Lakukan lookup point untuk satu catatan berdasarkan kunci primernya
SELECT * FROM `fluss_catalog`.`fluss_db`.orders
WHERE order_id = 1001;

-- Lakukan lookup point dengan kunci primer komposit
SELECT * FROM `fluss_catalog`.`fluss_db`.user_orders
WHERE user_id = 12345 AND order_id = 6789;
Agregasi COUNT(*)

Anda dapat menjalankan kueri COUNT(*) pada tabel kunci primer untuk dengan cepat mendapatkan jumlah total catatan.

-- Hitung jumlah total baris dalam tabel kunci primer
SELECT COUNT(*) FROM `fluss_catalog`.`fluss_db`.orders;

Parameter WITH

Parameter penyimpanan

Parameter berikut dipertahankan ke metadata tabel.

Parameter

Tipe

Nilai bawaan

Wajib

Deskripsi

bucket.num

Integer

None

Tidak

Jumlah bucket untuk tabel Fluss. Parameter ini memengaruhi paralelisme baca dan tulis data. Nilai bawaannya diwarisi dari konfigurasi kluster default.bucket.number.

bucket.key

String

None

Tidak

Kolom yang digunakan untuk distribusi data berbasis hash. Kolom-kolom ini harus merupakan subset dari kunci primer. Gunakan koma untuk memisahkan beberapa kolom.

table.log.ttl

Duration

7d

Tidak

Periode retensi untuk data log.

table.replication.factor

Integer

Bawaan kluster

Tidak

Faktor replikasi untuk tabel log. Nilai ini tidak boleh lebih besar dari jumlah tablet server.

table.log.format

Enum

ARROW

Tidak

Format penyimpanan untuk log. Opsi termasuk ARROW (format kolom yang mendukung query pushdown) dan INDEXED.

table.log.arrow.compression.type

Enum

ZSTD

Tidak

Jenis kompresi untuk format ARROW. Opsi yang valid adalah NONE, LZ4_FRAME, dan ZSTD.

table.log.arrow.compression.zstd.level

Integer

3

Tidak

Tingkat kompresi ZSTD (1-22).

table.kv.format

Enum

COMPACTED

Tidak

Format penyimpanan KV. Opsi yang valid adalah COMPACTED atau INDEXED.

table.merge-engine

Enum

last_row

Tidak

Strategi merge untuk tabel kunci primer. Opsi yang valid adalah first_row, versioned, dan last_row.

table.merge-engine.versioned.ver-column

String

None

Wajib bersyarat

Diperlukan jika table.merge-engine diatur ke versioned. Menentukan nama kolom versi.

table.datalake.enabled

Boolean

false

Tidak

Mengaktifkan atau menonaktifkan tiering penyimpanan data lake.

table.datalake.format

Enum

Bawaan kluster

Tidak

Format data lake. Saat ini, hanya paimon yang didukung.

table.log.tiered.local-segments

Integer

2

Tidak

Jumlah segmen log yang dipertahankan secara lokal setelah tiering penyimpanan diaktifkan.

Parameter partisi otomatis

Parameter

Tipe

Nilai bawaan

Wajib

Deskripsi

table.auto-partition.enabled

Boolean

false

Tidak

Mengaktifkan atau menonaktifkan pembuatan partisi otomatis.

table.auto-partition.time-unit

Enum

DAY

Tidak

Granularitas waktu untuk partisi otomatis. Opsi yang valid adalah YEAR, QUARTER, MONTH, DAY, dan HOUR.

table.auto-partition.num-precreate

Integer

2

Tidak

Jumlah partisi masa depan yang akan dibuat sebelumnya selama pemeriksaan.

table.auto-partition.num-retention

Integer

7

Tidak

Jumlah partisi historis yang dipertahankan. Partisi yang lebih lama dihapus secara otomatis.

table.auto-partition.time-zone

String

Zona waktu sistem

Tidak

Zona waktu yang digunakan untuk partisi otomatis.

Parameter baca

Parameter berikut dapat dikonfigurasi melalui klausa WITH atau petunjuk SQL.

Parameter

Tipe

Nilai bawaan

Wajib

Deskripsi

scan.startup.mode

Enum

full

Tidak

Mode startup konsumsi. Opsi yang valid adalah full, earliest, latest, dan timestamp.

scan.startup.timestamp

Long/String

None

Wajib bersyarat

Timestamp startup, yang dapat berupa nilai milidetik atau string dalam format yyyy-MM-dd HH:mm:ss. Parameter ini hanya berlaku ketika scan.startup.mode diatur ke timestamp.

scan.partition.discovery.interval

Duration

1 menit

Tidak

Interval untuk secara otomatis menemukan partisi baru. Atur ke nilai negatif untuk menonaktifkan penemuan otomatis.

client.scanner.log.check-crc

Boolean

true

Tidak

Menentukan apakah akan melakukan pemeriksaan CRC32 pada pesan untuk memastikan integritas data.

client.scanner.log.max-poll-records

Integer

500

Tidak

Jumlah maksimum catatan yang dapat dikembalikan oleh satu panggilan poll().

client.scanner.log.fetch.max-bytes

MemorySize

16mb

Tidak

Jumlah maksimum byte yang diambil dari server per permintaan.

client.scanner.log.fetch.max-bytes-for-bucket

MemorySize

1mb

Tidak

Jumlah maksimum byte yang diambil per bucket dalam satu permintaan.

client.scanner.log.fetch.min-bytes

MemorySize

1b

Tidak

Ukuran data minimum yang harus dikembalikan server untuk permintaan fetch.

client.scanner.log.fetch.wait-max-time

Duration

500ms

Tidak

Waktu maksimum yang ditunggu server ketika jumlah byte minimum tidak terpenuhi.

client.scanner.io.tmpdir

String

Direktori sementara sistem

Tidak

Direktori lokal untuk menyimpan file sementara seperti snapshot dan segmen log.

client.scanner.remote-log.prefetch-num

Integer

4

Tidak

Jumlah segmen log jarak jauh yang akan dipra-ambil.

client.remote-file.download-thread-num

Integer

3

Tidak

Jumlah thread yang digunakan untuk mengunduh file jarak jauh.

Menulis parameter

Parameter berikut dapat dikonfigurasi melalui klausa WITH atau petunjuk SQL.

Parameter

Tipe

Nilai bawaan

Wajib

Deskripsi

sink.ignore-delete

Boolean

false

Tidak

Menentukan apakah akan mengabaikan pesan DELETE dan UPDATE_BEFORE dari sumber.

sink.bucket-shuffle

Boolean

true

Tidak

Menentukan apakah akan mengacak data berdasarkan ID bucket sebelum menulis, yang dapat meningkatkan kinerja tulis.

client.writer.buffer.memory-size

MemorySize

64mb

Tidak

Ukuran total memori buffer internal untuk data baris.

client.writer.batch-size

MemorySize

2mb

Tidak

Ukuran batch target untuk catatan dalam bucket yang sama.

client.writer.buffer.wait-timeout

Duration

Long.MAX

Tidak

Waktu maksimum writer memblokir saat menunggu segmen yang tersedia.

client.writer.batch-timeout

Duration

100ms

Tidak

Waktu maksimum untuk menyangga catatan sebelum mengirimnya dalam batch.

client.writer.bucket.no-key-assigner

Enum

STICKY

Tidak

Strategi penugasan bucket untuk tabel tanpa kunci primer. Opsi yang valid adalah STICKY atau ROUND_ROBIN.

client.writer.acks

String

all

Tidak

Tingkat acknowledgment untuk tulis. all (atau -1): Menunggu semua replika mengakui. 1: Hanya menunggu leader mengakui. 0: Tidak menunggu acknowledgment apa pun. Pengaturan all direkomendasikan untuk daya tahan data maksimum.

client.writer.request-max-size

MemorySize

10mb

Tidak

Ukuran maksimum permintaan tunggal dalam byte.

client.writer.retries

Integer

MAX_VALUE

Tidak

Jumlah kali percobaan ulang pengiriman yang gagal dengan error yang dapat diulang.

client.writer.enable-idempotence

Boolean

true

Tidak

Mengaktifkan tulis idempoten, yang menyediakan semantik tepat-sekali dan jaminan pengurutan pesan.

client.writer.max-inflight-requests-per-bucket

Integer

5

Tidak

Jumlah maksimum permintaan yang sedang berlangsung per bucket. Parameter ini hanya berlaku ketika tulis idempoten diaktifkan.

Parameter tabel dimensi

Parameter

Tipe

Nilai bawaan

Wajib

Deskripsi

lookup.async

Boolean

true

Tidak

Mengaktifkan lookup asinkron, yang dapat meningkatkan throughput untuk join tabel dimensi.

lookup.cache

Enum

NONE

Tidak

Kebijakan cache. Opsi yang valid adalah NONE (tanpa caching) atau PARTIAL (caching parsial).

lookup.max-retries

Integer

3

Tidak

Jumlah maksimum percobaan ulang jika lookup gagal.

lookup.partial-cache.expire-after-access

Duration

None

Tidak

Periode kedaluwarsa cache setelah akses terakhir.

lookup.partial-cache.expire-after-write

Duration

None

Tidak

Periode kedaluwarsa cache setelah tulis terakhir.

lookup.partial-cache.cache-missing-key

Boolean

true

Tidak

Menentukan apakah akan menyimpan kunci yang tidak ada dalam tabel dimensi (yaitu, menyimpan nilai null).

lookup.partial-cache.max-rows

Long

None

Tidak

Jumlah maksimum baris dalam cache.

client.lookup.queue-size

Integer

25600

Tidak

Ukuran antrian untuk operasi lookup yang tertunda.

client.lookup.max-batch-size

Integer

128

Tidak

Ukuran batch maksimum untuk menggabungkan beberapa operasi lookup.

client.lookup.max-inflight-requests

Integer

128

Tidak

Jumlah maksimum permintaan lookup yang sedang berlangsung.

client.lookup.batch-timeout

Duration

100ms

Tidak

Waktu maksimum menunggu batch lookup terisi sebelum dikirim.

Ingesti Data

Konektor Fluss berperan sebagai sink data dalam pekerjaan YAML ingesti data.

Sintaksis

source:
   type: xxx

sink:
  type: fluss
  name: Fluss Sink
  bootstrap.servers: localhost:9123
  properties.client.security.protocol: sasl
  properties.client.security.sasl.mechanism: PLAIN
  properties.client.security.sasl.username: developer
  properties.client.security.sasl.password: developer-pass
  

pipeline:
  schema.change.behavior: IGNORE

Perubahan skema

Server Fluss mendukung penambahan kolom baru tetapi tidak mendukung operasi kolom lainnya (seperti menghapus kolom, mengganti nama kolom, atau mengubah tipe kolom). Oleh karena itu, kami merekomendasikan menggunakan pengaturan bawaan Flink CDC schema.change.behavior = LENIENT:

  • Saat kolom diganti namanya, konektor mengirim dua event. Konektor tidak menghapus kolom asli. Sebaliknya, konektor mengubah tipe data kolom menjadi nullable dan menambahkan kolom baru dengan nama baru dan tipe data nullable.

  • Saat kolom dihapus, konektor mengirim event perubahan tipe kolom, mengubah tipe data kolom menjadi nullable.

  • Saat kolom ditambahkan, konektor mengirim event penambahan kolom tetapi mengubah tipe data kolom menjadi nullable.

Catatan

Fitur ini memerlukan VVR 11.6 atau versi yang lebih baru.

Parameter

Parameter

Deskripsi

Wajib

Tipe

Bawaan

Keterangan

type

Menentukan jenis sink.

Ya

String

None

Nilai tetap: fluss.

name

Menentukan nama sink.

Tidak

String

None

None.

bootstrap.servers

Menentukan alamat Server Fluss.

Ya

String

None

Format: host:port,host:port,host:port. Gunakan koma (,) untuk memisahkan beberapa alamat.

bucket.key

Menentukan kunci bucket.

Tidak

String

None

Tentukan kebijakan distribusi data untuk setiap tabel Fluss. Tabel dipisahkan oleh ';', dan kunci bucket dipisahkan oleh ','.

Format: database1.table1:key1,key2;database1.table2:key3.

Data didistribusikan ke bucket berdasarkan nilai hash kunci bucket. Kunci bucket harus merupakan subset dari kunci primer dan tidak boleh mencakup kunci partisi tabel kunci primer. Jika tabel memiliki kunci primer tetapi tidak ada kunci bucket yang ditentukan, kunci bucket bawaannya adalah kunci primer (tidak termasuk kunci partisi). Jika tabel tidak memiliki kunci primer dan tidak ada kunci bucket yang ditentukan, data didistribusikan secara acak ke bucket.

Nilai bucket.key dan bucket.num tidak dapat diubah setelah tabel dibuat.

bucket.num

Menentukan jumlah bucket untuk tabel Fluss.

Tidak

String

None

Jumlah bucket untuk setiap tabel Fluss. Angka dipisahkan oleh ';'.

Format: database1.table1:4;database1.table2:8.

Jika tabel tidak memiliki jumlah bucket yang dikonfigurasi, item konfigurasi sisi server default.bucket.number digunakan secara bawaan.

Nilai bucket.key dan bucket.num tidak dapat diubah setelah tabel dibuat.

properties.table.*

Properti tabel Fluss.

Tidak

String

None

Melewatkan parameter yang didukung oleh tabel Fluss ke pipeline. Untuk informasi selengkapnya, lihat Opsi tabel Fluss.

properties.client.*

Parameter klien Fluss.

Tidak

String

None

Melewatkan parameter yang didukung oleh klien Fluss ke pipeline. Untuk informasi selengkapnya, lihat Opsi klien Fluss.

Pemetaan tipe

Tabel berikut menunjukkan pemetaan tipe data untuk ingesti data.

Tipe bidang CDC

Tipe bidang Fluss

TINYINT

TINYINT

SMALLINT

SMALLINT

INT

INT

BIGINT

BIGINT

FLOAT

FLOAT

DOUBLE

DOUBLE

DECIMAL(p, s)

DECIMAL(p, s)

BOOLEAN

BOOLEAN

DATE

DATE

TIME

TIME

TIMESTAMP

TIMESTAMP

TIMESTAMP_LTZ

TIMESTAMP_LTZ

CHAR(n)

CHAR(n)

VARCHAR(n)

STRING

ARRAY

ARRAY

MAP

MAP

ROW

ROW

BINARY(n)

Tidak didukung

VARBINARY(n)