Kafka Metrics: Panduan Utama Memantau Metrik Kunci Apache Kafka #

Mengoperasikan kluster Apache Kafka di tingkat produksi tanpa sistem monitoring yang mumpuni bagaikan menerbangkan pesawat di malam hari tanpa instrumen panel. Kafka adalah sistem terdistribusi berkinerja tinggi yang menangani jutaan pesan per detik, tetapi kompleksitas internalnya melibatkan interaksi konstan antara sistem operasi, I/O disk, alokasi memori JVM (Java Virtual Machine), latensi jaringan, dan koordinasi konsensus. Ketika terjadi degradasi performa atau gangguan pada replikasi data, kita harus dapat mengidentifikasi akar masalah secara instan sebelum berdampak pada SLA aplikasi.

Monitoring Apache Kafka bertumpu pada metrik JMX (Java Management Extensions) yang diekspos secara bawaan oleh JVM broker. Ribuan metrik tersedia, namun tidak semuanya memiliki tingkat kepentingan yang sama. Kita harus berfokus pada metrik-metrik kunci (golden signals) yang mencerminkan kesehatan sejati dari replikasi partisi, efisiensi thread broker, kinerja Garbage Collection, dan laju transfer I/O data.

Dalam panduan mendalam ini, kita akan membedah arsitektur pemantauan JMX di Kafka, merinci metrik-metrik kesehatan kluster paling kritis beserta nama MBean aslinya, menganalisis efisiensi thread handler, mengulas metrik JVM/GC beserta parameter tuningnya, serta menyediakan contoh berkas konfigurasi Prometheus JMX Exporter yang siap digunakan di lingkungan produksi.

Arsitektur Alur Pengumpulan Metrik di Apache Kafka #

Sebelum kita melihat daftar metrik secara detail, mari kita pelajari bagaimana metrik dari dalam sistem JVM Apache Kafka diekstrak, diproses, dan divisualisasikan dalam arsitektur modern:

flowchart LR
    subgraph KafkaBrokerNode ["NODE BROKER KAFKA"]
        KafkaApp["Apache Kafka (JVM)"] -->|MBeans Native JMX| JMXEngine["JMX Registry"]
        JMXAgent["JMX Exporter (Java Agent)"] -->|Membaca Internal JMX| JMXEngine
    end

    Prometheus["Prometheus Server"] -->|HTTP Scraping via Port 7071| JMXAgent
    Prometheus -->|TSDB Storage / Querying| Grafana["Grafana Dashboard"]
    
    style KafkaBrokerNode stroke-width:2px

Dalam alur ini, Java Agent Prometheus JMX Exporter berjalan di dalam ruang memori JVM Kafka yang sama. Agent ini membaca MBeans secara lokal, menyaringnya sesuai aturan regex, mengubah formatnya menjadi deret data deret waktu (time-series) HTTP yang ramah Prometheus, dan menyajikannya pada port port lokal (misalnya port 7071) untuk dikikis (scraped) oleh Prometheus Server secara berkala.


Metrik Kesehatan Kluster Paling Kritis #

Berikut adalah kelompok metrik utama yang menunjukkan apakah kluster kita sedang sehat atau berada dalam kondisi kritis. Peringatan (Alerts) wajib dikonfigurasikan pada metrik-metrik ini.

1. Under-Replicated Partitions (URP) #

  • Nama JMX MBean: kafka.server:type=ReplicaManager,name=UnderReplicatedPartitions
  • Deskripsi: Menunjukkan jumlah partisi yang replikanya tidak sinkron penuh (not fully in-sync). Artinya, jumlah replika aktif yang sinkron (ISR) saat ini lebih sedikit daripada nilai Replication Factor (RF) yang ditentukan untuk topik tersebut.
  • Tindakan: Nilai normal harus selalu 0. Jika nilai URP > 0 secara persisten, itu berarti ada broker yang mati, mengalami masalah jaringan (network partition), atau disk I/O yang sangat lambat sehingga pengikut (follower) tidak mampu mengejar offset pemimpin (leader). Ini adalah metrik terpenting untuk mengukur risiko kehilangan data (data loss risk).

2. Offline Partitions Count #

  • Nama JMX MBean: kafka.server:type=KafkaController,name=OfflinePartitionsCount
  • Deskripsi: Menunjukkan jumlah partisi yang tidak memiliki pemimpin (leader) aktif. Jika suatu partisi kehilangan leader-nya dan tidak ada pengikut (follower) di dalam ISR yang dapat menggantikannya, partisi tersebut menjadi offline.
  • Tindakan: Nilai normal wajib 0. Jika offline partitions > 0, aplikasi produser akan mengalami penolakan pengiriman (NotLeaderOrFollowerException) dan konsumen tidak dapat membaca data dari partisi tersebut. Ini menandakan terjadinya downtime sebagian pada aplikasi kita.

3. Active Controller Count #

  • Nama JMX MBean: kafka.server:type=KafkaController,name=ActiveControllerCount
  • Deskripsi: Menunjukkan apakah broker tersebut bertindak sebagai active controller (koordinator utama) dari kluster.
  • Tindakan: Di dalam satu kluster Kafka, hanya boleh ada tepat 1 active controller. Jika jumlahnya 0, kluster kehilangan koordinator metadata dan tidak dapat memproses pembuatan topik atau failover partition. Jika jumlahnya > 1 (split-brain), segera periksa jaringan internal kluster kita.

4. Unclean Leader Elections Per Second #

  • Nama JMX MBean: kafka.server:type=ControllerStats,name=UncleanLeaderElectionsPerSec
  • Deskripsi: Frekuensi terpilihnya replika di luar ISR (yang datanya belum sinkron penuh) menjadi leader baru akibat matinya leader lama ketika parameter unclean.leader.election.enable=true diaktifkan.
  • Tindakan: Nilai normal harus 0. Setiap kali terjadi unclean leader election, kita dipastikan kehilangan data (data loss) karena replika yang tertinggal dipaksa menjadi acuan data utama bagi partisi tersebut.

Metrik Efisiensi Jaringan dan Utilitas Thread #

Kafka menggunakan arsitektur jaringan non-blocking berbasis Java NIO dengan dua kelompok thread pool utama: Network Threads (menerima request socket TCP) dan Request Handler Threads (memproses logika request seperti menulis ke disk).

flowchart LR
    Client["Klien (SDK)"] ==> NT["Network Threads"]
    NT ==> RQ["Request Queue"]
    RQ ==> HT["Handler Threads"]
    NT --- Metric1["NetworkProcessorIdlePercent"]
    HT --- Metric2["RequestHandlerIdlePercent"]

1. Request Handler Idle Percent #

  • Nama JMX MBean: kafka.server:type=KafkaRequestHandlerPool,name=RequestHandlerIdlePercent
  • Deskripsi: Persentase waktu luang (idle time) dari thread pool pemroses request (I/O threads).
  • Tindakan: Nilai metrik berkisar antara 0.0 (0% idle / 100% sibuk) hingga 1.0 (100% idle / menganggur). Nilai sehat adalah di atas 0.3 (30% idle). Jika nilai rata-rata metrik ini turun di bawah 0.2 (20% idle), itu berarti broker kewalahan memproses request disk I/O. Kluster kita akan mulai mengalami peningkatan latensi respons secara drastis (request queuing delay). Solusinya adalah menambah thread handler (num.io.threads) atau melakukan penskalaan horizontal (menambah broker).

2. Network Processor Idle Percent #

  • Nama JMX MBean: kafka.network:type=Processor,name=NetworkProcessorIdlePercent
  • Deskripsi: Persentase waktu luang dari network threads (pemroses enkripsi SSL, network parsing).
  • Tindakan: Serupa dengan handler, nilai sehat adalah di atas 0.3. Jika nilai ini sangat rendah, periksa apakah CPU terbebani akibat jabat tangan SSL/TLS yang berlebihan. Kita dapat menambah jumlah network threads melalui parameter num.network.threads.

Metrik Kinerja JVM dan Garbage Collection (GC) #

Karena Apache Kafka dibangun di atas bahasa Scala/Java, perilakunya sangat dipengaruhi oleh manajemen memori JVM. Pemantauan metrik Garbage Collection adalah hal wajib untuk menghindari bencana kluster hang akibat pause GC yang terlalu lama.

1. Durasi GC Pause (GC Time) #

  • Nama JMX MBean: java.lang:type=GarbageCollector,name=* (Metrik: CollectionTime dan CollectionCount)
  • Deskripsi: Melacak frekuensi dan durasi (dalam milidetik) aktivitas pengumpulan memori sampah oleh JVM.
  • Dampak: Jika JVM broker menggunakan algoritma pembersihan memori standar dan mengalami pause “Stop-the-World” (STW) yang lama (misal > 5-10 detik), seluruh aktivitas broker akan dibekukan sementara. Selama pembekuan ini, broker tidak merespons jabat tangan (heartbeat) pengawas KRaft/Zookeeper. Broker lain menganggap broker yang membeku tersebut mati, lalu memicu failover partisi. Ketika broker terbangun dari GC pause, ia akan kaget karena partisi yang ia pimpin telah direbut, memicu badai rebalance dan ketidakstabilan kluster.

2. Konfigurasi JVM Garbage Collector yang Optimal #

Untuk meminimalkan GC pause di lingkungan produksi, kita sangat direkomendasikan menggunakan Garbage-First Garbage Collector (G1GC) dengan parameter tuning berikut pada JVM broker:

# Pengaturan JVM Garbage Collector produksi untuk Apache Kafka
export KAFKA_GC_LOG_OPTS="-Xlog:gc*,gc+age=trace,gc+phases=debug:file=/var/log/kafka/kafka-gc.log:time,uptime,pid:filecount=10,filesize=100M"

export KAFKA_JVM_PERFORMANCE_OPTS="-server \
  -XX:+UseG1GC \
  -XX:MaxGCPauseMillis=20 \
  -XX:InitiatingHeapOccupancyPercent=35 \
  -XX:G1ReservePercent=15 \
  -XX:MinMetaspaceFreeRatio=50 \
  -XX:MaxMetaspaceFreeRatio=80"

Penjelasan Parameter:

  • -XX:+UseG1GC: Mengaktifkan algoritma Garbage Collector G1.
  • -XX:MaxGCPauseMillis=20: Target waktu jeda maksimum Garbage Collector sebesar 20 milidetik (sangat agresif untuk menjaga latensi tetap rendah).
  • -XX:InitiatingHeapOccupancyPercent=35: Memicu siklus GC GC lebih awal ketika akumulasi data heap mencapai 35% (mencegah penumpukan memori penuh/full GC).
  • -XX:G1ReservePercent=15: Menyediakan cadangan memori bebas 15% untuk menghindari kegagalan alokasi memori saat proses penyerahan data dari page cache OS ke JVM.

Konfigurasi Produksi: Prometheus JMX Exporter #

Untuk mengekstrak metrik-metrik di atas ke dalam server Prometheus, kita harus memasang Prometheus JMX Exporter sebagai Java Agent pada proses startup Kafka.

Berikut adalah isi file konfigurasi /etc/kafka/jmx_exporter.yaml yang telah dioptimalkan untuk menyaring ribuan metrik mentah Kafka menjadi format Prometheus yang ringkas dan efisien:

# ==============================================================================
# jmx_exporter.yaml - KONFIGURASI PRODUKSI JMX EXPORTER UNTUK KAFKA
# ==============================================================================

lowercaseOutputName: true
lowercaseOutputLabelNames: true

rules:
  # 1. Metrik Kesehatan Utama: UnderReplicatedPartitions & OfflinePartitionsCount
  - pattern: 'kafka.server<type=ReplicaManager, name=UnderReplicatedPartitions><>Value'
    name: kafka_server_replicamanager_underreplicatedpartitions
    type: GAUGE
  - pattern: 'kafka.server<type=KafkaController, name=OfflinePartitionsCount><>Value'
    name: kafka_server_kafkacontroller_offlinepartitionscount
    type: GAUGE
  - pattern: 'kafka.server<type=KafkaController, name=ActiveControllerCount><>Value'
    name: kafka_server_kafkacontroller_activecontrollercount
    type: GAUGE

  # 2. Metrik Throughput Data (Byte Rates & Message Rates)
  - pattern: 'kafka.server<type=BrokerTopicMetrics, name=(BytesInPerSec|BytesOutPerSec|MessagesInPerSec), topic=(.+)><>Count'
    name: kafka_server_brokertopicmetrics_$1_total
    labels:
      topic: "$2"
    type: COUNTER
  - pattern: 'kafka.server<type=BrokerTopicMetrics, name=(BytesInPerSec|BytesOutPerSec|MessagesInPerSec)><>Count'
    name: kafka_server_brokertopicmetrics_$1_global_total
    type: COUNTER

  # 3. Metrik Utilitas Thread Pool (RequestHandler & NetworkProcessor)
  - pattern: 'kafka.server<type=KafkaRequestHandlerPool, name=RequestHandlerIdlePercent><>MeanRate'
    name: kafka_server_kafkarequesthandlerpool_requesthandleridlepercent_meanrate
    type: GAUGE
  - pattern: 'kafka.network<type=Processor, name=NetworkProcessorIdlePercent, networkProcessor=(.+)><>Value'
    name: kafka_network_processor_networkprocessoridlepercent
    labels:
      processor: "$1"
    type: GAUGE

  # 4. Metrik Waktu Tunggu Request (Request Latencies)
  - pattern: 'kafka.server<type=RequestMetrics, name=RequestsPerSec, request=(.+)><>Count'
    name: kafka_server_requestmetrics_requests_total
    labels:
      request: "$1"
    type: COUNTER
  - pattern: 'kafka.server<type=RequestMetrics, name=TotalTimeMs, request=(.+)><>99thPercentile'
    name: kafka_server_requestmetrics_totaltimems_p99
    labels:
      request: "$1"
    type: GAUGE

  # 5. Metrik Group Coordinator (Consumer Group Rebalances)
  - pattern: 'kafka.coordinator.group<type=GroupMetadataManager, name=MinActiveMembers><>Value'
    name: kafka_coordinator_group_groupmetadatamanager_minactivemembers
    type: GAUGE

  # 6. Metrik JVM Garbage Collection & Memory
  - pattern: 'java.lang<type=GarbageCollector, name=(.+)><>(CollectionCount|CollectionTime)'
    name: jvm_gc_$2_total
    labels:
      gc_name: "$1"
    type: COUNTER

Cara Memasang Java Agent JMX Exporter di Kafka Startup: #

Untuk mengaktifkan eksportir ini, tambahkan variabel lingkungan KAFKA_OPTS sebelum menjalankan broker Kafka. Konfigurasikan agar agent mendengarkan port 7071 dengan membaca file konfigurasi di atas:

# Menjalankan Kafka Broker dengan JMX Exporter Java Agent
export KAFKA_OPTS="-javaagent:/usr/share/jmx-exporter/jmx_prometheus_javaagent.jar=7071:/etc/kafka/jmx_exporter.yaml"
bin/kafka-server-start.sh -daemon config/server.properties

Setelah broker berjalan, kita dapat menguji ekstraksi metrik dengan melakukan curl ke port 7071:

curl http://localhost:7071/metrics

Output curl harus menampilkan metrik mentah dalam format deret waktu Prometheus (misalnya kafka_server_replicamanager_underreplicatedpartitions 0.0).


Checklist Audit Konfigurasi Pemantauan Metrik #

Pastikan pertahanan sistem monitoring kluster kita telah memenuhi checklist kepatuhan berikut sebelum dinyatakan siap rilis (production ready):

No Item Kepatuhan Audit Metrik Metode Verifikasi Status
1 Alerting URP Aktif Pastikan sistem alert (Alertmanager/Grafana) diprogram memicu notifikasi kritis jika kafka_server_replicamanager_underreplicatedpartitions > 0 selama lebih dari 2 menit. [ ]
2 Alerting Offline Partitions Aktif Pastikan alert terpicu instan jika kafka_server_kafkacontroller_offlinepartitionscount > 0. [ ]
3 Pemantauan GC Pauses Buat grafik visualisasi frekuensi dan durasi GC Collection Time. Buat alert jika sisa waktu pause rata-rata > 1 detik. [ ]
4 Port JMX Exporter Terisolasi Pastikan port HTTP JMX Exporter (misal port 7071) dilindungi firewall dan hanya dapat diakses oleh alamat IP server Prometheus. [ ]
5 Monitoring Thread Starvation Buat ambang batas warning di Grafana jika metrik RequestHandlerIdlePercent turun di bawah 0.2 secara persisten. [ ]
6 Pembersihan Metrik Sampah Pastikan file jmx_exporter.yaml menyaring metrik dengan benar agar tidak membanjiri ruang penyimpanan TSDB Prometheus (high cardinality metrics cleanup). [ ]

Ringkasan #

  • Fokus Golden Signals — Jangan memantau semua metrik secara mentah. Berfokuslah pada metrik kesehatan terpenting: URP (Under-Replicated Partitions), Offline Partitions Count, dan Request Handler Idle Percent.
  • Wajibkan Alerting URP — URP bernilai di atas 0 adalah indikator utama kerusakan replikasi. Integrasikan notifikasi URP langsung ke tim on-call untuk pencegahan downtime.
  • Tuning JVM G1GC — GC pause yang panjang adalah penyebab utama hilangnya broker dari deteksi kluster secara misterius. Selalu optimalkan konfigurasi JVM G1GC dan pantau waktu pembersihan memorinya.
  • Filter Metrik JMX — Gunakan filter regex yang efisien pada berkas JMX Exporter untuk membatasi ukuran data yang dikikis oleh Prometheus, menjaga performa server monitoring kita tetap ringan.

← Sebelumnya: Multi-Tenant Security   Berikutnya: Consumer Lag →

About | Author | Content Scope | Editorial Policy | Privacy Policy | Disclaimer | Contact