Kodeloka
  1. Kodeloka
  2. Kelas Apache Kafka
  3. Materi

4 · Ekosistem · Modul 10 dari 13

Kafka Streams: Pemrosesan Stateful

Kafka Streams adalah pustaka, bukan klaster. Ia mengubah aplikasi biasa menjadi pemroses aliran yang stateful, toleran gagal, dan bisa diskalakan seperti layanan lain.

Pustaka, Bukan Infrastruktur Baru

Berbeda dari Flink atau Spark yang menuntut klaster tersendiri, Kafka Streams adalah dependensi biasa di dalam aplikasi Anda. Skala dilakukan dengan menjalankan lebih banyak instans — persis seperti menskalakan layanan HTTP.

Aplikasi Anda (JAR / kontainer)
  ├── Kafka Streams sebagai pustaka
  ├── RocksDB untuk state lokal
  └── Kafka untuk masukan, keluaran, dan cadangan state

Stream dan Table

AbstraksiArtinyaContoh
KStreamAliran peristiwa; tiap catatan berdiri sendiri"pesanan-123 dibuat"
KTableKeadaan terkini per kunci; catatan baru menimpa yang lama"status pesanan-123 = dibayar"
GlobalKTableSalinan penuh tabel di tiap instansTabel referensi kecil, misalnya daftar mata uang
💡 Dualitas stream dan table

Keduanya adalah dua cara memandang data yang sama. Menjumlahkan seluruh peristiwa perubahan menghasilkan keadaan terkini (stream ke table), dan mencatat tiap perubahan keadaan menghasilkan aliran peristiwa (table ke stream). Memahami dualitas ini membuat sebagian besar API Kafka Streams terasa wajar.

State Store dan Changelog

Operasi stateful — agregasi, join, penghitungan berjendela — menyimpan data di RocksDB pada disk lokal instans. Agar tahan terhadap kegagalan, tiap perubahan state juga ditulis ke topik changelog di Kafka yang bersifat compacted.

Instans mati → pod baru dijadwalkan
  ↳ baca ulang topik changelog
  ↳ bangun kembali RocksDB lokal
  ↳ lanjutkan dari titik terakhir
⚠️ Pemulihan state bisa memakan waktu lama

State store berukuran puluhan gigabyte membutuhkan waktu lama untuk dibangun ulang dari changelog, dan selama itu partisi terkait tidak diproses. Mitigasinya: standby replica (num.standby.replicas) yang menjaga salinan hangat, dan volume persisten di Kubernetes agar RocksDB tidak hilang saat pod dijadwalkan ulang.

Windowing

JenisPerilakuContoh pemakaian
TumblingJendela tetap, tidak tumpang tindihJumlah pesanan per 5 menit
HoppingJendela tetap yang saling tumpang tindihRata-rata 10 menit, diperbarui tiap menit
SlidingBerbasis selisih waktu antar catatanDeteksi lonjakan
SessionDipisahkan oleh periode tidak aktifSesi aktivitas pengguna
🚫 Event time versus processing time

Kafka Streams default memakai waktu kejadian yang tertanam pada catatan, bukan waktu pemrosesan. Peristiwa yang datang terlambat — dari perangkat seluler yang sempat offline, misalnya — akan jatuh ke jendela masa lalu. Bila jendela itu sudah ditutup melebihi grace period, peristiwa tersebut dibuang tanpa peringatan. Setel grace period sesuai keterlambatan yang realistis di sistem Anda, dan pantau metrik catatan yang terlambat.

Contoh Topologi

StreamsBuilder pembangun = new StreamsBuilder();

KStream<String, Pesanan> pesanan = pembangun.stream("pesanan");
KTable<String, Pelanggan> pelanggan = pembangun.table("pelanggan");

pesanan
    .filter((k, p) -> p.getTotal() > 1_000_000)
    .join(pelanggan, (p, c) -> perkaya(p, c))
    .groupBy((k, p) -> p.getWilayah())
    .windowedBy(TimeWindows.ofSizeAndGrace(
        Duration.ofMinutes(5), Duration.ofMinutes(2)))
    .count()
    .toStream()
    .to("pesanan-besar-per-wilayah");
⚠️ Perubahan topologi bukan hal sepele

Menambah atau memindahkan operator stateful mengubah nama internal topik changelog dan repartition. Rilis yang tampak kecil bisa membuat aplikasi kehilangan seluruh state-nya. Beri nama eksplisit pada state store dan operator penting, dan uji jalur peningkatan versi sebelum menerapkannya di produksi.

Kafka Streams atau Flink?

Pilih Kafka Streams bilaPilih Flink bila
Sumber dan tujuan sama-sama KafkaPerlu banyak sumber dan sink beragam
Tim ingin menjalankannya seperti layanan biasaSudah ada tim data yang mengelola klaster
Tidak ingin menambah infrastruktur baruButuh SQL, batch, dan streaming dalam satu mesin
Skala menengahSkala sangat besar dengan state raksasa