Inti pemantauan

Metrik yang benar-benar dipantau: consumer lag, throughput, kesehatan ISR, dan JMX sebagai sumbernya.

Daftar isi

Pemantauan cluster Kafka menjadi efektif bila metrik yang dibaca mewakili keadaan operasional, bukan sekadar banyak jumlahnya. Topik ini membahas empat kelompok metrik yang benar-benar dipantau pada operasi harian, yaitu throughput, kesehatan ISR, consumer lag, dan request latency, beserta JMX sebagai sumber metriknya. Demo dijalankan pada broker lokal, sehingga setiap angka pada keluaran dapat direproduksi. Setelah membaca topik ini, pilihan metrik untuk dasbor operasional beserta ambang peringatannya dapat ditetapkan dengan alasan yang jelas.

Empat kelompok metrik yang dipantau#

Empat kelompok berikut mencakup keadaan cluster dari sisi yang berbeda. Throughput menunjukkan beban, kesehatan ISR menunjukkan keandalan penyimpanan, consumer lag menunjukkan ketertinggalan pemrosesan, dan request latency menunjukkan kecepatan broker melayani permintaan. Keempatnya saling melengkapi karena cluster dapat padat beban tetapi sehat, atau ringan tetapi tertinggal, dan pengukuran dilakukan berkala, misalnya setiap sepuluh detik, agar trennya terbaca. Sampel tunggal mudah menyesatkan, karena lonjakan sesaat pada sistem yang berjalan adalah keadaan yang wajar. Tabel berikut memadankan setiap metrik dengan artinya dan tindakan yang mengikutinya.

MetrikArtiAksi bila nilainya tidak normal
OfflinePartitionsCountJumlah partisi yang tidak memiliki leader aktifDitindaklanjuti segera karena tulisan dan pembacaan berhenti pada partisi tersebut
UnderReplicatedPartitionsJumlah partisi dengan ISR lebih kecil dari salinan lengkapnyaPeriksa broker lambat, diska, dan jaringan, lalu pulihkan salinannya
Consumer lagSelisih log-end-offset dan offset committed sebuah groupTambah konsumen sampai batas jumlah partisi atau perbaiki pemrosesannya
TotalTimeMsWaktu total broker melayani permintaan seperti Produce dan FetchPeriksa diska lambat, antrean permintaan, dan lonjakan beban
MessagesInPerSecLaju pesan masuk per detikCocokkan dengan laju pemrosesan dan jumlah konsumen
BytesInPerSecLaju byte masuk dari klien per detikPeriksa ukuran pesan dan kapasitas jaringan masuk
BytesOutPerSecLaju byte keluar ke klien per detikPeriksa jumlah konsumen dan kapasitas jaringan keluar

Urutan pemeriksaan biasanya bergerak dari kesehatan ke beban. OfflinePartitionsCount selain nol dan consumer lag yang terus naik menandakan gangguan yang langsung dirasakan pengguna, sedangkan perubahan throughput dan latensi lebih sering menjadi gejala awal yang mendahului gangguan. Ambang peringatan ditetapkan per topic karena laju normal setiap topic berbeda, dan tabel ini menjadi daftar minimum dasbor operasional, sedangkan metrik komponen lain seperti klien dan Connect ditambahkan sesuai komponen yang dijalankan.

JMX sebagai sumber metrik#

Broker Kafka menerbitkan metrik melalui JMX (Java Management Extensions), yaitu fasilitas Java untuk mengawasi dan mengelola proses yang berjalan. Setiap metrik diterbitkan sebagai MBean, objek terkelola dengan nama terstruktur, misalnya kafka.server:type=BrokerTopicMetrics,name=BytesInPerSec untuk laju byte masuk tingkat broker. Bagian type menunjuk komponen pemilik metrik, bagian name menunjuk metriknya, dan dimensi tambahan seperti topic= muncul pada metrik per topic. Alat apa pun yang mampu membaca JMX dapat mengumpulkan nilai MBean tersebut tanpa menyentuh broker secara langsung.

Remote JMX tidak aktif secara default, dan diaktifkan dengan menetapkan variabel lingkungan JMX_PORT sebelum broker dijalankan. Broker sandbox menjalankan konfigurasi bawaan tanpa port JMX, sehingga blok berikut ditandai tidak dijalankan dan hanya memperlihatkan bentuk pemanggilannya. Alat JmxTool bawaan distribusi membaca MBean dan mencetak nilainya ke keluaran standar, berguna untuk pemeriksaan cepat sebelum kolektor penuh dipasang.

bash
# tidak-dijalankan
# broker sandbox tidak membuka port JMX, sehingga koneksi ke sana tidak dapat dibuat
bin/kafka-run-class.sh org.apache.kafka.tools.JmxTool --jmx-url service:jmx:rmi:///jndi/rmi://localhost:9999/jmxrmi \
  --one-time \
  --object-name kafka.server:type=BrokerTopicMetrics,name=BytesInPerSec \
  --attributes Count

Klien Java menerbitkan metrik JMX pada proses klien itu sendiri, bukan pada broker, sehingga pengumpulannya diarahkan ke host aplikasi. Aplikasi yang tidak menggunakan klien Java, misalnya klien Python, tidak menerbitkan metrik JMX sama sekali, sehingga pemantauan sisi klien mengandalkan pengukuran CLI dan klien yang diprogram sendiri. Pada operasi harian, kolektor membaca nilai MBean berkala dan menyimpannya sebagai deret waktu, sedangkan alat seperti jconsole cukup untuk pemeriksaan sesaat.

Throughput pada tingkat broker#

Tiga metrik menjadi ukuran beban broker, yaitu MessagesInPerSec untuk laju pesan masuk, BytesInPerSec untuk laju byte masuk dari klien, dan BytesOutPerSec untuk laju byte keluar ke klien. Trafik replikasi antar broker tidak dicampur ke dalam metrik byte tersebut, karena direkam terpisah pada ReplicationBytesInPerSec dan ReplicationBytesOutPerSec di tingkat broker. Ketiga metrik inti juga tersedia per topic lewat dimensi topic= pada MBean yang sama, sehingga topic paling berat dapat dicari langsung.

Metrik laju tersedia langsung dari broker, tetapi cara menghitungnya tetap berguna bila nilai yang terbaca adalah penghitung kumulatif. Skrip berikut menghitung laju dari dua sampel penghitung kumulatif dengan angka tetap, sehingga hasilnya selalu dapat dihitung ulang.

python laju-throughput.py
# Menghitung laju throughput dari dua sampel metrik kumulatif broker.
# Angka sampel ditetapkan tetap, sehingga hasilnya selalu dapat dihitung ulang.

# (detik ke-, byte masuk kumulatif, byte keluar kumulatif, pesan masuk kumulatif)
sampel = [
    (100, 48_300_000, 96_400_000, 52_000),
    (110, 78_500_000, 158_900_000, 82_000),
]

t1, masuk1, keluar1, pesan1 = sampel[0]
t2, masuk2, keluar2, pesan2 = sampel[1]
durasi = t2 - t1

laju_masuk = (masuk2 - masuk1) / durasi
laju_keluar = (keluar2 - keluar1) / durasi
laju_pesan = (pesan2 - pesan1) / durasi

print(f"MessagesInPerSec : {laju_pesan:,.0f} pesan per detik")
print(f"BytesInPerSec    : {laju_masuk:,.0f} byte per detik ({laju_masuk / 1_000_000:.1f} MB per detik)")
print(f"BytesOutPerSec   : {laju_keluar:,.0f} byte per detik ({laju_keluar / 1_000_000:.1f} MB per detik)")
print(f"rata-rata ukuran pesan: {laju_masuk / laju_pesan:,.0f} byte")
text Keluaran
MessagesInPerSec : 3,000 pesan per detik
BytesInPerSec    : 3,020,000 byte per detik (3.0 MB per detik)
BytesOutPerSec   : 6,250,000 byte per detik (6.2 MB per detik)
rata-rata ukuran pesan: 1,007 byte

Selisih penghitung dibagi durasi antar sampel menghasilkan laju per detik, dan pembagian byte terhadap pesan menghasilkan ukuran pesan rata-rata. Ukuran rata-rata itu penting karena dua topic dengan laju pesan yang sama dapat membebani diska dan jaringan dengan cara yang berbeda.

Laju tinggi bukan masalah selama latensi terkendali, dan kondisi itu diukur dengan metrik request latency. MBean kafka.network:type=RequestMetrics,name=TotalTimeMs,request=Produce dan request=FetchConsumer merekam waktu total broker melayani tulisan dan pembacaan, yang terbagi atas antrean, pemrosesan lokal, penantian follower, dan pengiriman jawaban. Batch yang lebih besar menaikkan throughput tetapi juga menaikkan latensi tulisan, sehingga keduanya selalu dibaca bersama saat penyetelan.

Kesehatan ISR dan partisi offline#

UnderReplicatedPartitions pada MBean kafka.server:type=ReplicaManager menghitung partisi yang ISR-nya lebih kecil dari salinan lengkapnya, keadaan yang berarti satu atau lebih salinan tidak lagi sinkron. Broker yang lambat menyalin karena diska atau jaringan, broker yang mati, dan rebalancing yang berat adalah penyebab yang paling lazim. Nilai di atas nol menurunkan jaminan ketahanan topic bersangkutan karena pesan committed hanya tersedia pada salinan yang lebih sedikit. Metrik pendampingnya, UnderMinIsrPartitionCount, menandai partisi yang ISR-nya turun di bawah min.insync.replicas, keadaan yang membuat tulisan dengan acks=all mulai ditolak.

OfflinePartitionsCount pada MBean kafka.controller menghitung partisi yang tidak memiliki leader aktif, dan keadaan ini menghentikan tulisan serta pembacaan pada partisi tersebut. Nilai selain nol ditindaklanjuti segera karena tidak pulih dengan sendirinya, biasanya dengan memeriksa broker yang mati dan keadaan controller aktif.

Kedua metrik ini adalah kelanjutan langsung dari mekanisme replikasi, sehingga penyebab dan perbaikannya mengikuti pembahasan leader, follower, dan min.insync.replicas. Pada cluster kecil dengan replication factor 1, setiap kegagalan broker langsung membuat partisinya offline, sehingga alarm pada OfflinePartitionsCount menjadi pertahanan pertama. Pada cluster multi-broker dengan replication factor 3, nilai UnderReplicatedPartitions biasanya naik lebih dahulu dan menjadi peringatan sebelum ketersediaan benar-benar hilang.

Consumer lag#

Consumer lag adalah ukuran ketertinggalan sebuah group terhadap ujung log, dihitung dari selisih log-end-offset dan offset committed per partisi. Pengertian lengkapnya, ambang peringatan, dan pola backpressure dibahas pada topik khusus consumer lag di modul Keandalan, sedangkan bagian ini menyiapkan pengukurannya sebagai rutinitas operasi. Alat utamanya adalah kafka-consumer-groups --describe, dan angka lag itulah yang dijadwalkan berkala untuk membentuk tren.

Blok berikut menyiapkan bahan pengukurannya. Group m7-grup-monitor dan topic m7-monitor-demo dihapus terlebih dahulu, topic dibuat ulang dari awal agar isinya selalu sama, lalu delapan pesan dikirim oleh skrip Python.

bash
(
  cd /home/kal/my-project/kafka-runtime/kafka
  bin/kafka-consumer-groups.sh --bootstrap-server localhost:9092 --delete --group m7-grup-monitor >/dev/null 2>&1
  bin/kafka-topics.sh --bootstrap-server localhost:9092 --delete --if-exists --topic m7-monitor-demo >/dev/null 2>&1
  sleep 2
  bin/kafka-topics.sh --bootstrap-server localhost:9092 --create --topic m7-monitor-demo --partitions 1
)
text Keluaran
Created topic m7-monitor-demo.

Skrip pengirimnya membuat delapan pesan bacaan sensor dan mengirimkannya ke topic tetap tersebut. Isinya bernomor berurutan agar posisi setiap pesan mudah dilacak pada tabel describe berikutnya.

python kirim-metrik.py
# Mengirim delapan pesan bacaan sensor ke topic tetap m7-monitor-demo
from kafka import KafkaProducer

producer = KafkaProducer(bootstrap_servers="localhost:9092")
for i in range(8):
    producer.send("m7-monitor-demo", value=f"bacaan-sensor-{i}".encode())
producer.flush()
producer.close()
print("8 pesan terkirim ke m7-monitor-demo")
text Keluaran
8 pesan terkirim ke m7-monitor-demo

Konsumen berikut sengaja diberhentikan setelah tiga pesan dengan --max-messages 3, sehingga lag dapat dibaca saat konsumsi baru berjalan setengah jalan, lalu groupnya dideskripsikan pada blok yang sama. Perintah describe dijalankan segera setelah konsumen keluar, sehingga offset committed sudah tercatat saat tabelnya dibuat.

bash
(
  cd /home/kal/my-project/kafka-runtime/kafka
  bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic m7-monitor-demo --group m7-grup-monitor --from-beginning --max-messages 3 2>/dev/null
  bin/kafka-consumer-groups.sh --bootstrap-server localhost:9092 --describe --group m7-grup-monitor 2>/dev/null
)
text Keluaran
bacaan-sensor-0
bacaan-sensor-1
bacaan-sensor-2

GROUP           TOPIC           PARTITION  CURRENT-OFFSET  LOG-END-OFFSET  LAG             CONSUMER-ID     HOST            CLIENT-ID
m7-grup-monitor m7-monitor-demo 0          3               8               5               -               -               -

Tabel describe memperlihatkan CURRENT-OFFSET bernilai 3 pada log berisi 8 pesan, sehingga LAG berisi 5. Tiga kolom terakhir berisi - karena konsumen sudah keluar dari group saat pengukuran diambil, dan baris kosong di atas tabel merupakan perilaku alatnya. Pada operasi harian, perintah ini dijadwalkan setiap beberapa detik untuk seluruh group penting, dan tren lag itulah yang menjadi dasar alarm, bukan satu sampel tunggal.

Kesalahan umum#

  1. Memantau seluruh metrik tanpa memilih. Dasbor dengan ratusan grafik menyulitkan pengenalan keadaan penting, dan alarm yang terlalu banyak membuat keadaan yang benar-benar kritis terlewat. Mulai dari daftar empat kelompok di atas, lalu tambahkan metrik lain hanya setelah kebutuhannya muncul.
  2. Membaca laju byte tanpa laju pesan. Topic dengan pesan besar menaikkan BytesInPerSec tanpa mengubah MessagesInPerSec, sehingga kesimpulan tentang beban permintaan dapat keliru. Baca keduanya bersama dan catat ukuran pesan rata-rata setiap topic.
  3. Menganggap metrik klien tersedia dari broker. Metrik JMX klien diterbitkan di proses klien, sedangkan consumer lag hanya terlihat dari offset yang di-commit group. Kumpulkan metrik klien di host aplikasi dan lag melalui kafka-consumer-groups.
  4. Menilai latensi hanya dari rata-rata. Nilai rata-rata menyembunyikan permintaan yang lambat pada persentil teratas, sementara producer biasa mengalami timeout pada persentil tersebut. Pantau atribut persentil pada MBean RequestMetrics, bukan hanya rata-ratanya.
  5. Menjadwalkan pengukuran lag dengan interval yang terlalu jarang. Group yang pulih atau macet dalam satu menit dapat terlewat sepenuhnya pada pemeriksaan per jam, sehingga alarmnya terlambat. Jadwalkan pengukuran untuk group penting dalam hitungan detik atau menit sesuai laju topicnya.

Ringkasan#

  • Empat kelompok metrik memadai untuk operasi harian, yaitu throughput broker, kesehatan ISR, consumer lag, dan request latency.
  • Broker menerbitkan metrik melalui JMX sebagai MBean bernama terstruktur, remote JMX diaktifkan lewat JMX_PORT, dan JmxTool membacanya sekali sesaat.
  • UnderReplicatedPartitions dan OfflinePartitionsCount menandai keandalan penyimpanan, sedangkan BytesInPerSec, BytesOutPerSec, dan MessagesInPerSec menandai beban.
  • Consumer lag diukur dengan kafka-consumer-groups --describe per group dan partisi, lalu ditinjau dari trennya, bukan dari satu sampel.

Referensi#