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

2 · Produksi & Konsumsi · Modul 4 dari 13

Produser: acks, Idempotensi, Batching & Kompresi

Setelan default produser dulu mengutamakan kecepatan. Sejak Kafka 3.0 default sudah aman — tetapi banyak konfigurasi warisan yang masih beredar dan berbahaya.

acks Menentukan Apa Arti "Terkirim"

acksKapan dianggap suksesRisiko
0Begitu pesan keluar dari soketPesan hilang tanpa jejak bila broker mati atau menolak
1Leader sudah menulis ke log-nyaHilang bila leader mati sebelum follower menyalin
allSemua replika sinkron sudah menerimaLatensi sedikit lebih tinggi — dan ini harga yang pantas
🚫 acks=0 bukan "optimasi"

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
⚠️ Konfigurasi warisan bisa mematikan idempotensi diam-diam

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.

SetelanDefaultArti
batch.size16 KBUkuran batch maksimum per partisi
linger.ms0Berapa lama menunggu batch terisi sebelum kirim
compression.typenoneKompresi diterapkan per batch
buffer.memory32 MBTotal buffer produser sebelum blocking
💡 linger.ms = 5 sering merupakan kemenangan gratis

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

TipeRasioCPUCatatan
lz4SedangSangat rendahPilihan aman untuk latensi rendah
zstdTerbaikRendah–sedangPilihan default modern; hemat disk dan bandwidth
snappySedangRendahWarisan, masih baik
gzipBaikTinggiHindari — CPU-nya mahal

Menangani Kegagalan dengan Benar

🚫 Mengabaikan hasil pengiriman asinkron

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
⚠️ Selalu panggil flush() atau close() saat 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.