Kafka Pattern Untuk Production
Pattern 1: Exactly-Once Semantics (Menjamin Kebenaran Data)
Tujuan utama pola ini adalah mengeliminasi kegagalan kebenaran (correctness failures), seperti pesan ganda (duplikasi) dan race conditions (kondisi balapan).
1.1 Layer 1: Idempotent Producer
Secara default, jika terjadi network timeout setelah pesan terkirim namun sebelum acknowledgment diterima, producer akan mengirim ulang pesan tersebut, sehingga menyebabkan duplikasi.
Solusi: Aktifkan idempotence. Kafka akan menyematkan sequence number pada setiap pesan, sehingga broker bisa mendeteksi dan menolak duplikasi secara otomatis.
Implementasi franz-go:
Library franz-go mengaktifkan idempotence secara default.
package main
import (
"github.com/twmb/franz-go/pkg/kgo"
)
func NewProductionProducer() (*kgo.Client, error) {
client, err := kgo.NewClient(
kgo.SeedBrokers("localhost:9092"),
// Idempotence is enabled by default.
// Menjamin message tidak berubah urutan / tidak duplicate, khususnya saat retry
// Menjamin durabilitas data (menunggu semua replika in-sync)
kgo.RequiredAcks(kgo.AllISRAcks()),
)
return client, err
}1.2 Layer 2: Partition Key Strategy
Tanpa partition key, pesan akan disebar secara acak (round-robin), menyebabkan hilangnya urutan (ordering). Ini memicu race conditions jika dua event terkait (misal: "Order Created" dan "Payment Success") diproses oleh consumer berbeda secara bersamaan.
Solusi: Gunakan Partition Key yang konsisten (misalnya OrderID). Ini menjamin semua pesan dengan ID yang sama masuk ke partisi yang sama dan diproses berurutan oleh satu consumer.
Implementasi franz-go:
1.3 Layer 3 & 4: Transactional Semantics & App-Level Idempotency
Lapisan infrastruktur (Layer 1 & 2) tidak bisa mencegah duplikasi jika consumer crash setelah memproses pesan tapi sebelum commit offset.
Solusi:
Transactions: Menjamin pembacaan dan penulisan ke Kafka bersifat atomik.
App-Level Idempotency: Consumer harus mengecek apakah pesan sudah pernah diproses (misal cek ke DB) sebelum mengeksekusi logika bisnis.
Implementasi franz-go (Transactional):
Pattern 2: Throughput Optimization (Optimalisasi Performa)
Kafka default dioptimalkan untuk latensi rendah (kirim secepatnya), yang justru membunuh throughput pada beban tinggi karena terlalu banyak network round-trips.
2.1 Layer 1: Producer Batching
Alih-alih mengirim pesan satu per satu, kumpulkan pesan dalam memori (batch) dan kirim sekaligus.
Konfigurasi:
batch.size: Ukuran batch dalam bytes.linger.ms: Waktu tunggu maksimal sebelum batch dikirim (meski belum penuh)13131313.
2.2 Layer 2: Compression
Untuk Mengurangi beban bandwidth jaringan. Algoritma lz4 direkomendasikan karena keseimbangan terbaik antara rasio kompresi dan beban CPU.
Implementasi franz-go (Batching & Compression):
2.3 Layer 3: Consumer Fetch Optimization
Optimalkan cara consumer mengambil data. Jangan mengambil data byte demi byte. Paksa consumer menunggu sampai data cukup banyak terkumpul di broker sebelum dikirim melalui jaringan.
Implementasi franz-go:
Pattern 3: Failure Recovery (Ketahanan & Pemulihan)
Fitur auto-commit pada Kafka bekerja berdasarkan waktu (time-based), bukan penyelesaian tugas. Ini berbahaya karena bisa menyebabkan data hilang (jika crash setelah commit tapi sebelum proses selesai) atau duplikasi.
3.1 Manual Commit Strategy
Matikan auto-commit. Lakukan commit offset hanya setelah logika bisnis sukses dieksekusi sepenuhnya.
Implementasi franz-go:
3.2 Static Group Membership
Saat consumer restart (misal saat deploy), Kafka biasanya memicu Rebalance (stop-the-world) yang menghentikan seluruh grup consumer selama beberapa detik.
Solusi: Gunakan Static Group Membership. Dengan memberikan ID statis, Kafka akan menoleransi ketidakhadiran consumer sementara (selama session.timeout.ms) tanpa memicu rebalance.
Implementasi franz-go:
Direkomendasikan untuk menerapkan pola ini secara bertahap:
Correctness (Pattern 1): Wajib. Data yang salah tidak ada gunanya diproses cepat.
Performance (Pattern 2): Terapkan saat volume data mulai meningkat.
Resilience (Pattern 3): Terapkan untuk stabilitas operasional jangka panjang.
Studi Kasus: "TicketMaster Lite" – High-Concurrency Concert Booking System
Skenario: Anda sedang membangun backend untuk penjualan tiket konser artis papan atas (misal: Coldplay atau Taylor Swift).
Masalah: Ribuan pengguna menekan tombol "Beli" secara bersamaan ("War Tiket").
Risiko:
Overselling: Menjual tiket lebih dari kapasitas kursi (Race Condition).
Double Charge: Pengguna tidak sengaja ter-charge 2x karena menekan tombol berulang saat jaringan lambat (Idempotency failure).
System Crash: Server down karena beban mendadak dan pemulihan yang lama (Resilience failure).
Tech Stack:
Language: Golang 1.23+
Web Framework: Go Chi (Lightweight & Fast)
Database: PostgreSQL (dengan
pgxdriver)Message Broker: Kafka (dengan
github.com/twmb/franz-go)
Last updated