Episode ini mengajarkan cara menghadapi kegagalan di pipeline streaming: menangkap exception di operator dan source, memisahkan data rusak ke side output, memantau status job dan log, menggunakan savepoints untuk recovery, serta debugging dengan local cluster dan flink run -d.

Episode 6 memastikan job kalian bisa pulih dari kegagalan sistem. Episode 7 ini berbalik ke sisi paling manusiawi: kode yang salah. Data di dunia nyata kotor — field hilang, format berubah, JSON rusak. Pertanyaannya bukan apakah error akan muncul, melainkan bagaimana kalian meresponsnya tanpa kehilangan data atau membuat job berhenti.
Kita akan belajar menangkap exception di operator dan source, memisahkan data rusak ke side output, membaca log dan status job, memakai savepoint untuk recovery yang terkontrol, serta teknik debugging dengan local cluster. Di akhir episode, kalian memiliki toolkit lengkap untuk men-debug job streaming apa pun.
Cara paling sehat menangani data rusak adalah menangkapnya di proses, bukan membiarkan job mati. Gunakan ProcessFunction dengan try-catch dan arahkan data gagal ke side output:
OutputTag<String> badTag = new OutputTag<String>("bad-rows") {};
DataStream<Event> valid = lines
.process(new ProcessFunction<String, Event>() {
@Override
public void processElement(
String line, Context ctx, Collector<Event> out) throws Exception {
try {
out.collect(parseJson(line));
} catch (Exception e) {
ctx.output(badTag, line);
}
}
});
DataStream<String> badRows = valid.getSideOutput(badTag);ctx.output mengirim data bermasalah ke side output alih-alih menjatuhkannya. Dari sana kalian bisa menulisnya ke topic dead-letter atau log untuk inspeksi nanti — data tidak hilang, job tetap jalan.
Ada dua filosofi: fail fast (biarkan job error agar cepat diketahui) dan skip bad records (teruskan, catat yang salah). Untuk pipeline produksi, kombinasi paling bijak: parse yang gagal diarahkan ke side output, lalu dihitung dengan metric kustom agar tim tahu jumlahnya naik.
Flink memakai SLF4J sebagai antarmuka logging. Biasakan menulis log kontekstual di operator:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private static final Logger LOG = LoggerFactory.getLogger(ParseEventFunction.class);
LOG.info("Memproses event {}", event.getId());
LOG.warn("Event tanpa timestamp diterima: {}", event);LOG.info memakai format placeholder sehingga pesan log tetap ringkas. Untuk error yang bisa diantisipasi, gunakan LOG.warn; untuk kondisi tak terduga yang bisa membuat job gagal, LOG.error.
Log setiap komponen berada di folder log/:
tail -f $FLINK_HOME/log/taskexecutor.logPerintah tail -f mengikuti log secara real-time. Saat debugging, cari stack trace berisi nama class job kalian — itulah titik asal error, bukan sekadar pesan umum di baris terakhir.
Checkpoint bersifat otomatis dan sementara; savepoint dibuat manual dan disimpan untuk jangka panjang. Buat saat ingin menghentikan job tanpa kehilangan state:
./bin/flink savepoint <jobId> /tmp/flink-savepoints
./bin/flink run -d -s /tmp/flink-savepoints/savepoint-<id> target/app.jar./bin/flink savepoint mengambil snapshot state saat itu, dan flag -s pada flink run -d me-restore job dari savepoint tersebut. Ini juga cara utama meng-upgrade job tanpa kehilangan state — akan kita dalami di episode 16.
| Mekanisme | Otomatis | Tujuan utama |
|---|---|---|
| Checkpoint | Ya | Recovery setelah kegagalan |
| Savepoint | Manual | Upgrade, migrasi, rollback |
Savepoint lebih cocok untuk keputusan sadar (upgrade versi, pindah cluster), sedangkan checkpoint untuk kejadian tak terduga.
Saat mengembangkan, jalankan job dalam mode detached lalu amati log dan dashboard tanpa memblokir terminal:
$FLINK_HOME/bin/flink run -d -p 2 target/debug-job.jar
$FLINK_HOME/bin/flink list -aflink run -d -p 2 mengirim job dengan parallelism 2. Di web dashboard, tab Task dan Backpressure memberi petunjuk visual subtask mana yang lambat atau gagal.
Beberapa pola yang sering menyelamatkan waktu:
env.fromElements berisi data kecil dan deterministik..print() sebelum menambahkan operator berikutnya.EXPLAIN di Flink SQL untuk melihat rencana eksekusi query.data kecil → satu operator → print → tambah operator → amati outputEpisode 7 melatih kalian menghadapi kegagalan dengan tenang: menangkap exception di operator dan source lewat side output, menulis log yang informatif, memantau status job, memakai savepoint untuk recovery terkontrol, dan mendebug secara bertahap dengan local cluster.
Inti yang harus dibawa pulang:
tail -f log task executor memperlihatkan stack trace sumber error.Di episode 8 selanjutnya kita akan membahas source & sink integrations — menghubungkan Kafka, Kinesis, RabbitMQ, dan file sources, menulis ke Kafka, database, object storage, dan Elasticsearch, memahami ekosistem connector serta format data JSON, Avro, Protobuf, dan CSV. Inilah jembatan antara Flink dan seluruh sistem di sekitar kalian.