acks Menentukan Apa Arti "Terkirim"
| acks | Kapan dianggap sukses | Risiko |
|---|---|---|
0 | Begitu pesan keluar dari soket | Pesan hilang tanpa jejak bila broker mati atau menolak |
1 | Leader sudah menulis ke log-nya | Hilang bila leader mati sebelum follower menyalin |
all | Semua replika sinkron sudah menerima | Latensi sedikit lebih tinggi — dan ini harga yang pantas |
Dengan acks=0 produser tidak pernah tahu apakah pesan sampai. Tidak ada retry, tidak ada galat, tidak ada metrik kegagalan — pesan hanya lenyap. Ini hanya dapat diterima untuk data yang benar-benar boleh hilang seperti metrik sampling. Untuk apa pun yang berkaitan dengan transaksi, uang, atau status pengguna, gunakan acks=all.
Idempotensi Menghapus Duplikat Akibat Retry
Bayangkan produser mengirim pesan, broker menulisnya, lalu jaringan putus sebelum balasan sampai. Produser mencoba lagi — dan pesan yang sama tertulis dua kali.
enable.idempotence=true membuat produser menyertakan producer id dan nomor urut, sehingga broker mengenali dan membuang duplikat.
enable.idempotence=true ← default sejak Kafka 3.0 ↳ memaksa acks=all ↳ memaksa retries besar ↳ memaksa max.in.flight.requests.per.connection <= 5
Menyetel acks=1 atau max.in.flight.requests.per.connection=10 pada klien modern membuat produser gagal start atau menonaktifkan idempotensi, tergantung versi. Banyak berkas konfigurasi lama yang disalin dari internet mengandung nilai-nilai ini. Periksa konfigurasi Anda dan hapus setelan warisan alih-alih menambahkannya.
Batching: Sedikit Menunggu, Jauh Lebih Cepat
Produser tidak mengirim pesan satu per satu. Ia mengumpulkannya per partisi sampai batch penuh atau waktu tunggu habis.
| Setelan | Default | Arti |
|---|---|---|
batch.size | 16 KB | Ukuran batch maksimum per partisi |
linger.ms | 0 | Berapa lama menunggu batch terisi sebelum kirim |
compression.type | none | Kompresi diterapkan per batch |
buffer.memory | 32 MB | Total buffer produser sebelum blocking |
Dengan linger.ms=0, produser mengirim segera dan batch sering hanya berisi satu pesan — kompresi jadi tidak efektif dan overhead permintaan jaringan tinggi. Menunggu 5–20 milidetik biasanya melipatgandakan throughput dan menurunkan pemakaian CPU broker, dengan tambahan latensi yang tidak terasa untuk hampir semua aplikasi.
Memilih Kompresi
| Tipe | Rasio | CPU | Catatan |
|---|---|---|---|
lz4 | Sedang | Sangat rendah | Pilihan aman untuk latensi rendah |
zstd | Terbaik | Rendah–sedang | Pilihan default modern; hemat disk dan bandwidth |
snappy | Sedang | Rendah | Warisan, masih baik |
gzip | Baik | Tinggi | Hindari — CPU-nya mahal |
Menangani Kegagalan dengan Benar
Metode send() bersifat asinkron dan mengembalikan future. Kode yang memanggilnya tanpa callback maupun penanganan galat akan kehilangan pesan tanpa satu pun baris log. Selalu sediakan callback yang mencatat galat, atau tangani exception dari future.
# Python (confluent-kafka)
def laporan(err, msg):
if err is not None:
log.error("gagal kirim: %s", err) # WAJIB ada
else:
log.debug("terkirim ke %s [%d]", msg.topic(), msg.partition())
produser.produce("pesanan", key=b"pesanan-123", value=data, callback=laporan)
produser.flush() # sebelum aplikasi berhenti
Pesan yang masih berada di buffer produser belum terkirim. Proses yang dimatikan tanpa flush kehilangan seluruh isi buffer. Pasang penanganan sinyal shutdown yang memanggil flush dengan batas waktu wajar.