Realtime Compute for Apache Flink mendukung dua jenis agregasi jendela: agregasi jendela grup dan agregasi fungsi bernilai tabel (TVF) jendela. Topik ini mencakup sintaks keduanya, skenario di mana agregasi TVF jendela kembali ke mode non-TVF, serta dukungan update stream pada berbagai jenis jendela.
Pilih antara dua sintaks
| Agregasi jendela grup | Agregasi TVF jendela | |
|---|---|---|
| Operator | GroupWindowAggregation |
WindowAggregate |
| Fungsi jendela | TUMBLE, HOP, SESSION | TUMBLE, HOP, CUMULATE, SESSION |
| Status | Deprecated | Direkomendasikan |
| Optimisasi performa | Tidak | Ya |
| Dukungan `GROUPING SETS` | Tidak | Ya |
| Window Top-N setelah agregasi | Tidak | Ya |
| Dukungan update stream | Ya (VVR) | Ya (VVR, semua jenis jendela) |
Gunakan agregasi TVF jendela. Fitur ini mendukung semua jenis jendela dari agregasi jendela grup ditambah CUMULATE, menawarkan optimisasi performa dan GROUPING SETS, serta memungkinkan penerapan Window Top-N pada hasil agregasi.
Agregasi jendela grup (deprecated)
Agregasi jendela grup mendefinisikan jendela dalam klausa GROUP BY. Fitur ini sesuai dengan operator GroupWindowAggregation dan mendukung fungsi jendela TUMBLE, HOP, dan SESSION.
Untuk sintaks, contoh, dan detail fitur, lihat Agregasi jendela grup.
Perubahan perilaku VVR 11.x untuk agregasi jendela grup
Mulai VVR 11.x (Flink 1.20), sistem tidak lagi secara otomatis menulis ulang agregasi jendela grup (sintaks deprecated) menjadi rencana eksekusi agregasi TVF jendela.
Pada VVR 8.x, sistem secara otomatis menulis ulang sintaks deprecated menjadi rencana eksekusi sintaks baru, sehingga mengaktifkan optimisasi agregasi dua fase Local-Global. Mulai VVR 11.x, penulisan ulang otomatis ini tidak lagi menjadi perilaku bawaan—sintaks deprecated mempertahankan rencana eksekusi fisik aslinya.
Dampak: Pekerjaan yang menggunakan sintaks deprecated tidak lagi secara otomatis mendapatkan manfaat dari optimisasi agregasi dua fase. Performa dapat menurun pada skenario dengan volume data besar atau kesenjangan data.
Migrasikan agregasi jendela grup ke agregasi TVF jendela (sintaks baru). Untuk kondisi yang mengaktifkan optimisasi agregasi dua fase, lihat Optimisasi Local-Global untuk agregasi jendela.
Kompatibilitas dengan perilaku sebelumnya
Jika migrasi tidak dapat dilakukan segera, aktifkan parameter berikut untuk mengembalikan perilaku VVR 8.x:
| Parameter | Deskripsi | Bawaan |
|---|---|---|
table.optimizer.window-rewrite-enabled |
Mengaktifkan penulisan ulang otomatis dari sintaks deprecated ke sintaks baru, sehingga mengaktifkan optimisasi agregasi dua fase. | false (sejak VVR 11.x) |
Contoh konfigurasi (tambahkan ke parameter pekerjaan):
table.optimizer.window-rewrite-enabled: true
Parameter ini hanya berfungsi sebagai langkah kompatibilitas transisional selama upgrade. Dukungan penulisan ulang untuk sintaks deprecated kemungkinan akan dihapus pada rilis mendatang. Migrasikan ke sintaks baru sesegera mungkin.
Agregasi TVF jendela
Agregasi TVF jendela mendefinisikan jendela melalui klausa GROUP BY yang mencakup kolom window_start dan window_end yang dihasilkan oleh TVF jendela. Fitur ini sesuai dengan operator WindowAggregate dan mendukung fungsi jendela TUMBLE, HOP, CUMULATE, dan SESSION.
Berbeda dengan agregasi pada tabel kontinu, agregasi TVF jendela tidak menghasilkan hasil antara—hanya hasil akhir pada akhir setiap jendela. Data status antara dibersihkan secara otomatis.
Untuk sintaks, contoh, dan detail fitur, lihat Agregasi TVF jendela.
Sintaks SESSION TVF jendela: VVR 11.x vs VVR 8.x
Sintaks SESSION TVF jendela berbeda antar versi VVR. Upgrade ke VVR 11.1 atau yang lebih baru untuk menggunakan sintaks lengkap.
VVR 11.x (Flink 1.20)
SESSION(TABLE data [PARTITION BY(keycols, ...)], DESCRIPTOR(timecol), gap)
| Parameter | Deskripsi |
|---|---|
data |
Tabel dengan kolom atribut waktu |
keycols |
(Opsional) Kolom yang digunakan untuk mempartisi data sebelum pembuatan jendela sesi |
timecol |
Kolom atribut waktu yang dipetakan ke jendela sesi |
gap |
Interval waktu maksimum antara dua event dalam sesi yang sama |
VVR 8.x (Flink 1.17)
SESSION(TABLE data, DESCRIPTOR(timecol), gap)
| Parameter | Deskripsi |
|---|---|
data |
Tabel dengan kolom atribut waktu |
timecol |
Kolom atribut waktu yang dipetakan ke jendela sesi |
gap |
Interval waktu maksimum antara dua event dalam sesi yang sama |
VVR 8.x tidak mendukungPARTITION BY. Kolom partisi diinferensi secara implisit dari klausaGROUP BY.
Perbandingan sintaks SESSION: VVR 11.x vs VVR 8.x
| VVR 11.x | VVR 8.x | |
|---|---|---|
| Sintaks | SESSION(TABLE data [PARTITION BY(keycols, ...)], DESCRIPTOR(timecol), gap) |
SESSION(TABLE data, DESCRIPTOR(timecol), gap) |
| Spesifikasi kolom partisi | Eksplisit — melalui PARTITION BY(keycols) |
Implisit — melalui klausa GROUP BY |
| Batasan kolom partisi | Tidak ada | Harus ada di GROUP BY; tidak boleh berupa window_start, window_end, atau window_time |
| Penggunaan `SESSION()` mandiri | Didukung | Harus digunakan dengan GROUP BY |
| Penggabungan fungsi jendela dengan agregasi | Didukung | Tidak didukung — kolom agregasi harus sesuai dengan kolom partisi |
Contoh berikut setara. Keduanya menggunakan item sebagai kolom partisi.
-- Skema tabel Bid (digunakan di semua contoh di bawah)
> desc Bid;
+-------------+------------------------+------+-----+--------+---------------------------------+
| name | type | null | key | extras | watermark |
+-------------+------------------------+------+-----+--------+---------------------------------+
| bidtime | TIMESTAMP(3) *ROWTIME* | true | | | `bidtime` - INTERVAL '1' SECOND |
| price | DECIMAL(10, 2) | true | | | |
| item | STRING | true | | | |
+-------------+------------------------+------+-----+--------+---------------------------------+
-- VVR 11.x: kolom partisi dideklarasikan eksplisit dalam SESSION()
> SELECT window_start, window_end, item, SUM(price) AS total_price
FROM TABLE(
SESSION(TABLE Bid PARTITION BY item, DESCRIPTOR(bidtime), INTERVAL '5' MINUTES))
GROUP BY item, window_start, window_end;
-- VVR 8.x: kolom partisi diinferensi dari GROUP BY
> SELECT window_start, window_end, item, SUM(price) AS total_price
FROM TABLE(
SESSION(TABLE Bid, DESCRIPTOR(bidtime), INTERVAL '5' MINUTES))
GROUP BY item, window_start, window_end;
| VVR 11.x | VVR 8.x | |
|---|---|---|
| Partisi jendela SESSION | SESSION(TABLE Bid PARTITION BY item, DESCRIPTOR(bidtime), INTERVAL '5' MINUTES) |
SESSION(TABLE Bid, DESCRIPTOR(bidtime), INTERVAL '5' MINUTES) |
| Agregasi dan penggabungan jendela | Penggabungan langsung didukung (misalnya, SUM(price) dalam jendela) |
Kolom agregasi harus sesuai dengan kolom partisi jendela (misalnya, GROUP BY item) |
Kapan agregasi TVF jendela kembali ke mode non-TVF
Ketika sebuah kueri mencakup TVF jendela tetapi tidak memenuhi kondisi agar TVF dan agregasi dapat digabungkan, sistem akan kembali ke rencana eksekusi non-TVF.
Jika kueri yang tidak dapat digabungkan menggunakan waktu pemrosesan sebagai atribut waktu, kolom waktu pemrosesan dimaterialisasi dan digunakan sebagai atribut waktu untuk jendela yang dibuat. Hal ini menyebabkan watermark tabel sumber memengaruhi hasil agregasi—jendela mungkin ditutup lebih awal dari yang diharapkan, dan data terlambat mungkin dibuang, sama seperti pada jendela waktu event. Hindari pola di bawah ini untuk mencegah hal ini terjadi.
TVF jendela dan pernyataan agregasi tidak dapat digabungkan jika salah satu kondisi berikut terpenuhi:
-
Filter atau komputasi pada kolom waktu jendela.
window_start,window_end, atauwindow_timedifilter atau dimodifikasi sebelum agregasi.-- Filter pada window_start > SELECT window_start, window_end, item, SUM(price) AS total_price FROM (SELECT item, price, window_start, window_end FROM TABLE( SESSION(TABLE Bid, DESCRIPTOR(bidtime), INTERVAL '5' MINUTES)) WHERE window_start >= TIMESTAMP '2020-04-15 08:06:00.000') GROUP BY item, window_start, window_end; -- Operasi aritmetika pada window_start > SELECT window_start, window_end, item, SUM(price) AS total_price FROM (SELECT item, price, window_start + (INTERVAL '1' SECOND) AS window_start, window_end FROM TABLE( SESSION(TABLE Bid, DESCRIPTOR(bidtime), INTERVAL '5' MINUTES))) GROUP BY item, window_start, window_end; -- Konversi tipe pada window_start > SELECT window_start, window_end, item, SUM(price) AS total_price FROM (SELECT item, price, CAST(window_start AS varchar) AS window_start, window_end FROM TABLE( SESSION(TABLE Bid, DESCRIPTOR(bidtime), INTERVAL '5' MINUTES))) GROUP BY item, window_start, window_end; -
TVF jendela digunakan bersama fungsi bernilai tabel yang didefinisikan pengguna (UDTF).
> SELECT window_start, window_end, category, SUM(price) AS total_price FROM (SELECT category, price, window_start, window_end FROM TABLE( SESSION(TABLE Bid, DESCRIPTOR(bidtime), INTERVAL '5' MINUTES)), LATERAL TABLE(category_udtf(item)) AS T(category)) GROUP BY category, window_start, window_end; -
Klausa `GROUP BY` tidak mencantumkan `window_start` atau `window_end`.
> SELECT window_start, item, SUM(price) AS total_price FROM TABLE( SESSION(TABLE Bid, DESCRIPTOR(bidtime), INTERVAL '5' MINUTES)) GROUP BY item, window_start; -
Fungsi agregat yang didefinisikan pengguna Python (UDAF) digunakan.
-
`GROUPING SETS`, `CUBE`, atau `ROLLUP` mengelompokkan secara terpisah berdasarkan `window_start` atau `window_end`.
> SELECT item, SUM(price) AS total_price FROM TABLE( SESSION(TABLE Bid, DESCRIPTOR(bidtime), INTERVAL '5' MINUTES)) GROUP BY GROUPING SETS((item), (window_start), (window_end)); > SELECT item, SUM(price) AS total_price FROM TABLE( SESSION(TABLE Bid, DESCRIPTOR(bidtime), INTERVAL '5' MINUTES)) GROUP BY CUBE (item, window_start, window_end); > SELECT item, SUM(price) AS total_price FROM TABLE( SESSION(TABLE Bid, DESCRIPTOR(bidtime), INTERVAL '5' MINUTES)) GROUP BY ROLLUP (item, window_start, window_end); -
Fungsi agregat diterapkan pada `window_start`, `window_end`, atau `window_time`.
> SELECT window_start, window_end, item, SUM(price) AS total_price, MAX(window_end) AS max_end FROM TABLE( SESSION(TABLE Bid, DESCRIPTOR(bidtime), INTERVAL '5' MINUTES)) GROUP BY item, window_start, window_end;
Dukungan update stream
Tabel berikut menunjukkan dukungan update stream berdasarkan fungsi jendela dan sintaks.
| Fungsi jendela | Sintaks lama (GroupWindowAggregation) — VVR | Sintaks lama (GroupWindowAggregation) — Apache Flink | Sintaks baru (WindowAggregate) — VVR | Sintaks baru (WindowAggregate) — Apache Flink |
|---|---|---|---|---|
| TUMBLE | Ya | Ya | Ya | Tidak |
| HOP | Ya | Ya | Ya | Tidak |
| SESSION | Ya | Ya | Ya | Ya (Apache Flink 1.19 dan seterusnya) |
| CUMULATE | N/A | N/A | Ya (VVR 8.0.6 dan seterusnya) | Tidak |
Pada sintaks lama, dukungan update stream identik baik saat menggunakan VVR maupun Apache Flink. Pada sintaks baru, hanya operator WindowAggregate milik VVR yang mendukung update stream untuk semua fungsi jendela. VVR secara otomatis memilih antara operator GroupWindowAggregation dan WindowAggregate berdasarkan aliran input.
Untuk perbedaan fungsi jendela SESSION antara VVR dan Apache Flink, lihat Queries.
Optimisasi Local-Global untuk agregasi jendela
Agregasi jendela mendukung optimisasi agregasi dua fase Local-Global. Saat diaktifkan, pengoptimal membagi agregasi jendela satu fase menjadi:
-
Agregasi Lokal: melakukan pra-agregasi parsial sebelum shuffle data, sehingga mengurangi jumlah data yang ditransfer melalui jaringan.
-
Agregasi Global: melakukan agregasi akhir setelah shuffle dan menghasilkan output.
Keenam kondisi berikut harus terpenuhi agar optimisasi ini berlaku.
Kondisi 1: Strategi fase agregasi mengizinkan dua fase
table.optimizer.agg-phase-strategy diatur ke AUTO (bawaan) atau TWO_PHASE. Mengatur ke ONE_PHASE menonaktifkan optimisasi dua fase.
Kondisi 2: Jendela menggunakan waktu event
Jendela harus menggunakan waktu event (rowtime). Jendela waktu pemrosesan tidak didukung.
Kondisi 3: Jenis jendela bukan SESSION
Jenis jendela TUMBLE, HOP, dan CUMULATE didukung. Jendela SESSION tidak mendukung optimisasi dua fase.
Kondisi 4: Semua fungsi agregat mendukung penggabungan parsial
Semua fungsi agregat harus mendukung operasi merge. Fungsi bawaan seperti SUM, COUNT, MIN, MAX, dan AVG didukung. UDAF kustom harus mengimplementasikan metode merge().
Kondisi 5: Aliran input hanya insert dan jendela dapat dikonversi ke bentuk TVF
Semua kondisi berikut harus terpenuhi:
-
Aliran input hanya berisi operasi insert.
-
table.exec.emit.early-fire.enableddiatur kefalse(bawaan). -
table.exec.emit.late-fire.enableddiatur kefalse(bawaan). -
Untuk jendela HOP, jendela harus sejajar (ukuran jendela habis dibagi interval slide).
Kondisi 6: Distribusi data belum memenuhi persyaratan partisi
Distribusi data input belum memenuhi persyaratan partisi untuk agregasi. Jika data sudah didistribusikan berdasarkan kunci partisi, pengoptimal menentukan bahwa tidak diperlukan pra-agregasi tambahan dan tidak menghasilkan node Agregasi Lokal.
Referensi parameter
| Parameter | Tipe | Bawaan | Persyaratan |
|---|---|---|---|
table.optimizer.agg-phase-strategy |
Enum | AUTO | Tidak boleh ONE_PHASE |
table.exec.emit.early-fire.enabled |
Boolean | false | Harus salah |
table.exec.emit.late-fire.enabled |
Boolean | false | Harus false |