Belajar Apache Flink - Event Time, Watermarks, & Windowing
Episode 5 of 23

Belajar Apache Flink - Event Time, Watermarks, & Windowing

Episode ini membedah konsep waktu paling penting di Flink: event time versus processing time. Kalian akan membangkitkan watermark untuk menangani data yang datang terlambat, mengenal window types tumbling, sliding, dan session, serta mengatur window trigger, allowed lateness, dan side output untuk late events.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Pendahuluan

Episode 4 sudah mengajarkan transformasi dasar dan menyentuh operator window. Episode 5 ini menaikkan level akurasi kalian: sebagian besar analitik streaming bergantung pada waktu, dan Flink menawarkan model waktu yang jauh lebih canggih daripada sekadar jam dinding mesin. Tanpa pemahaman ini, laporan kalian bisa keliru hanya karena beberapa event tiba terlambat.

Topik yang kita bedah: perbedaan event time dan processing time, cara membangkitkan watermark untuk menangani keterlambatan, tiga window type utama yaitu tumbling, sliding, dan session, serta trigger, allowed lateness, dan side output untuk late events. Setelah episode ini, kalian bisa membangun analitik berbasis waktu yang akurat meskipun data datang terlambat atau tersusun ulang.

Event Time vs Processing Time

Dua Jam yang Berbeda

Processing time adalah waktu saat mesin pemroses menangani event. Event time adalah waktu yang tercatat di dalam data itu sendiri, biasanya timestamp yang dibuat sumber. Bagi analitik yang harus merefleksikan kapan kejadian sungguhan terjadi — misalnya jam berapa transaksi dilakukan — event time adalah satu-satunya jawaban yang benar.

Dua definisi waktu dalam satu baris
event time (waktu di dalam data) vs processing time (waktu mesin saat memproses)

Timestamp di Dalam Data

Agar event time bekerja, setiap event diharapkan membawa field timestamp:

Event dengan timestamp
{
  "userId": "u-1001",
  "action": "purchase",
  "amount": 250000,
  "eventTs": "2026-08-10T08:15:00+07:00"
}

Kode di atas memakai eventTs sebagai event time. Kalian akan menunjuk field ini saat menyiapkan watermark strategy.

Watermark Generation

Menandai Kemajuan Waktu Event

Watermark adalah penanda yang memberi tahu Flink: semua event dengan event time sebelum titik ini sudah dianggap datang. Strategi paling umum adalah bounded out of order — mengasumsikan event bisa datang terlambat maksimal sekian detik:

Watermark dengan lateness 5 detik
import org.apache.flink.api.common.eventtime.WatermarkStrategy;
import java.time.Duration;
 
WatermarkStrategy<Order> strategy =
    WatermarkStrategy.<Order>forBoundedOutOfOrderness(Duration.ofSeconds(5))
        .withTimestampAssigner((event, timestamp) -> event.getEventTs());

forBoundedOutOfOrderness menentukan batas lateness, dan withTimestampAssigner memberi tahu Flink field mana yang menjadi event time. Semakin besar batas ini, semakin akurat hasilnya tetapi semakin lama window menunggu sebelum menembak.

Memasang Strategy pada Source

Strategy dipasang saat source dibaca, sehingga seluruh pipeline memahami urutan event time:

Assign timestamp dan watermark ke stream
DataStream<Order> orders = env.fromSource(
    kafkaSource,
    strategy,
    "kafka-orders");

Tanpa langkah ini, windowing berbasis event time tidak akan berfungsi — Flink tidak bisa menilai keterlambatan tanpa baseline yang jelas.

Window Types

Tumbling Window

Tumbling window membagi stream menjadi jendela berukuran tetap yang tidak saling tumpang tindih. Setiap event tepat berada dalam satu window:

Tumbling window satu menit
orders.keyBy(Order::getUserId)
    .window(TumblingEventTimeWindows.of(Time.minutes(1)))
    .sum("amount");

Sliding Window

Sliding window bisa saling tumpang tindih — window baru dibuka setiap slide step. Cocok untuk menghitung rata-rata bergerak:

Sliding window 10 menit dengan slide 5 menit
orders.keyBy(Order::getUserId)
    .window(SlidingEventTimeWindows.of(Time.minutes(10), Time.minutes(5)))
    .sum("amount");

Session Window

Session window mengelompokkan event yang berdekatan dan menutup diri setelah tidak ada event selama gap tertentu. Ideal untuk menganalisis sesi pengguna:

Session window dengan gap 30 menit
orders.keyBy(Order::getUserId)
    .window(EventTimeSessionWindows.withGap(Time.minutes(30)))
    .sum("amount");

Pemilihan window type menentukan bentuk agregasi: tumbling untuk hitungan periodik, sliding untuk tren bergerak, dan session untuk pola aktivitas.

Window Trigger, Allowed Lateness, dan Late Events

Trigger Menentukan Kapan Window Diproses

Trigger adalah logika yang memutuskan kapan hasil window dikeluarkan. Default bawaan Flink sudah memadai untuk sebagian besar kasus: window menembak ketika watermark melewati batas akhirnya.

Allowed Lateness dan Side Output

Meski watermark sudah diatur, event yang sangat terlambat tetap bisa datang. Atur berapa lama window masih menerima event terlambat, lalu arahkan sisanya ke side output:

Allowed lateness dengan side output
OutputTag<Order> lateTag = new OutputTag<Order>("late-orders") {};
 
SingleOutputStreamOperator<Order> windowed =
    orders.keyBy(Order::getUserId)
        .window(TumblingEventTimeWindows.of(Time.minutes(1)))
        .allowedLateness(Time.minutes(2))
        .sideOutputLateData(lateTag)
        .sum("amount");
 
DataStream<Order> lateOrders = windowed.getSideOutput(lateTag);
lateOrders.print();

.allowedLateness memperpanjang masa hidup window dua menit setelah watermark melewatinya, dan .sideOutputLateData memisahkan event yang datang setelah itu agar tidak mengotori agregasi utama.

Menyeimbangkan Latency dan Akurasi

Aturan mainnya sederhana: makin besar lateness yang diizinkan, makin lengkap hasilnya tetapi makin lama window menunggu. Simulasikan perilaku ini dengan menjalankan job dan mengamati hasilnya:

Menjalankan job windowing
./bin/flink run -d target/window-job.jar
./bin/flink list -a

Perintah ./bin/flink run -d mengirim job dalam mode detached, dan ./bin/flink list -a menampilkan statusnya. Dari web dashboard, kalian bisa melihat kapan tiap window menembak dan seberapa banyak late event yang masuk ke side output.

Penutup

Episode 5 memberi kalian kendali penuh atas waktu: membedakan event time dan processing time, membangkitkan watermark dengan forBoundedOutOfOrderness, memilih window type yang tepat, serta mengatur trigger, allowed lateness, dan side output untuk late events. Keterampilan ini menjadi fondasi hampir semua analitik streaming yang benar.

Inti yang harus dibawa pulang:

  • Event time mencerminkan kapan kejadian sungguhan terjadi; processing time hanya jam mesin.
  • Watermark menandai kemajuan waktu event dan menangani lateness terikat.
  • Tumbling window tanpa tumpang tindih, sliding window bertumpuk, session window mengikuti gap aktivitas.
  • Allowed lateness memperpanjang masa hidup window; side output menangkap event yang terlalu terlambat.
  • Selalu seimbangkan akurasi dan latency saat memilih nilai lateness.

Di episode 6 selanjutnya kita akan membahas state management dan checkpointing — stateful operators dan key/value state, ValueState, ListState, MapState, dan AggregatingState, konfigurasi checkpointing beserta jaminan konsistensinya, serta restart strategies dan fault tolerance. Inilah kunci membangun job Flink yang andal dan tidak kehilangan data saat terjadi kegagalan.

Belajar Apache Flink - Event Time, Watermarks, & Windowing | Belajar Apache Flink