Episode ini membahas menghubungkan event CDC ke Kafka consumers dan stream processors, memanfaatkan Kafka Streams, ksqlDB, Flink, Spark, dan sink database, mengalirkan data ke data lake dan data warehouse, serta use case materialized views dan analytics.

Event CDC yang mengalir ke Kafka tidak berguna jika hanya diam di topic. Episode 8 ini membahas sisi konsumsi: bagaimana aplikasi membaca event, bagaimana stream processors mengolahnya secara real-time, dan bagaimana sink connector mengantarkan data ke sistem lain seperti database, Elasticsearch, dan data warehouse.
Ada satu perbedaan mendasar yang harus dipahami sejak awal: source connector (Debezium) memproduksi, sedangkan sink connector mengonsumsi. Pola ini membuat Kafka menjadi hub — data berubah sekali di sumber, lalu disebarkan ke banyak tujuan tanpa menambah beban ke database sumber.
Konsumen paling sederhana adalah console consumer untuk inspeksi cepat:
docker exec -it kafka /opt/kafka/bin/kafka-console-consumer.sh \
--bootstrap-server localhost:9092 \
--topic dbserver1.inventory.customers \
--from-beginning \
--property print.key=trueUntuk aplikasi nyata, konsumen memakai library seperti Kafka client, dengan prinsip yang sama: baca key dan value, cek bidang op, lalu lakukan aksi sesuai operasi. Karena Debezium memakai primary key sebagai message key, aplikasi bisa langsung memetakan event ke record di database target.
Alih-alih menulis logika consumer dari nol, kalian bisa memakai ksqlDB yang menyediakan SQL untuk stream processing:
CREATE STREAM customers_stream (
id INT,
first_name VARCHAR,
last_name VARCHAR,
email VARCHAR
) WITH (
KAFKA_TOPIC = 'dbserver1.inventory.customers',
VALUE_FORMAT = 'json'
);Perhatikan bahwa topic CDC membawa wrapper schema dan payload, sehingga struktur VALUE_FORMAT = 'json' di atas disederhanakan — di produksi kalian memakai Unwrap SMT terlebih dahulu untuk melepas wrapper sebelum konsumen SQL memprosesnya.
Alternatif lain yang kuat:
Semuanya bisa membaca topic Debezium secara langsung sebagai sumber event.
Untuk mengalirkan data keluar dari Kafka, daftarkan sink connector. Contoh JDBC sink ke PostgreSQL:
{
"name": "jdbc-sink",
"config": {
"connector.class": "io.confluent.connect.jdbc.JdbcSinkConnector",
"tasks.max": "1",
"topics": "dbserver1.inventory.customers",
"connection.url": "jdbc:postgresql://postgres:5432/warehouse",
"connection.user": "warehouse",
"connection.password": "warehouse",
"insert.mode": "upsert",
"pk.fields": "id",
"auto.create": "true",
"auto.evolve": "true"
}
}Dengan insert.mode: "upsert", sink menimpa baris berdasarkan primary key — persis sesuai semantik event CDC. Tujuan sink lain yang umum:
Kombinasi source dan sink menghasilkan pola arsitektur yang powerful:
before dan after disimpan lengkap sebagai riwayat perubahan.MySQL → Debezium → Kafka topic → ksqlDB / Kafka Streams
├── materialized view
├── JDBC sink → warehouse
└── Elasticsearch sink → searchKunci keberhasilan pola ini adalah menjaga event tetap append-only di Kafka, sehingga sumber kebenaran tidak terpecah dan setiap tujuan bisa membaca dari titik yang sama.
Satu catatan penting: karena Kafka menjamin urutan per partisi, bukan per key lintas partisi, pastikan jumlah partisi topic sesuai kebutuhan sink. Konsumen sink yang membutuhkan urutan harus membaca partisi yang sama tempat key baris berada.
Episode 8 menutup sirkuit konsumsi: konsumen aplikasi membaca event langsung, stream processors mengolahnya secara real-time, dan sink connector mengantarkan data ke database, search, data lake, dan warehouse — semuanya dari satu aliran event yang sama.
Inti yang harus dibawa pulang:
Di episode 9 selanjutnya kita akan membahas schema registry dan data contracts — membangun kontrak data untuk skema event, mengelola versioning dan compatibility rules, menangani evolusi skema pada payload Debezium, serta validasi konsumen dengan Avro dan Protobuf.