Kafka Cluster İzleme ve Performans Optimizasyonu
Kafka cluster’ını ilk kurduğunuzda her şey güzel görünür. Mesajlar akıyor, consumer’lar işliyor, producer’lar memnun. Sonra bir sabah geliyorsunuz, consumer lag patlamış, broker’lardan biri under-replicated partition saçıyor, disk dolmak üzere ve kimsenin haberi yok. Bu yazı, o sabahı yaşamamanız için neler yapmanız gerektiği hakkında.
Temel Metrikler: Neye Bakacaksınız?
Kafka’yı izlerken her metriği toplamaya çalışmak yerine gerçekten önemli olanlara odaklanmak gerekiyor. Yıllar içinde edindiğim deneyimle şunu söyleyebilirim: çoğu Kafka problemi birkaç temel metrikin ihmal edilmesinden kaynaklanıyor.
Broker tarafında izlenmesi gereken kritik metrikler:
- UnderReplicatedPartitions: Sıfır olmalı. Sıfırdan farklıysa acil durum.
- ActiveControllerCount: Cluster genelinde toplamı 1 olmalı.
- OfflinePartitionsCount: Yine sıfır olmalı, herhangi bir değer veri kaybı riski demek.
- RequestHandlerAvgIdlePercent: %30’un altına düşerse broker bunalıyor.
- NetworkProcessorAvgIdlePercent: Ağ thread’leri meşgul, dikkat et.
- BytesInPerSec / BytesOutPerSec: Trafik baseline’ını bilmek anomali tespitini kolaylaştırır.
Consumer tarafında:
- ConsumerLag: En kritik metrik. Lag büyüyorsa işleme kapasitesi yetersiz demek.
- FetchRate: Consumer’ların ne kadar aktif olduğunu gösterir.
JMX ile Metrik Toplama
Kafka, metrikleri JMX üzerinden expose eder. Bunları toplamak için Prometheus JMX Exporter kullanmak production ortamlarda en yaygın yaklaşım.
Önce kafka başlatma scriptine JMX exporter’ı ekleyin:
# kafka-server-start.sh öncesinde environment variable set et
export KAFKA_OPTS="-javaagent:/opt/kafka/jmx_prometheus_javaagent-0.19.0.jar=7071:/opt/kafka/kafka-jmx-config.yml"
# Broker'ı bu şekilde başlatın
/opt/kafka/bin/kafka-server-start.sh /opt/kafka/config/server.properties
JMX exporter konfigürasyonu için temel bir config dosyası:
# /opt/kafka/kafka-jmx-config.yml
lowercaseOutputName: true
lowercaseOutputLabelNames: true
rules:
- pattern: kafka.server<type=(.+), name=(.+), clientId=(.+), topic=(.+), partition=(.*)><>Value
name: kafka_server_$1_$2
type: GAUGE
labels:
clientId: "$3"
topic: "$4"
partition: "$5"
- pattern: kafka.server<type=(.+), name=(.+), clientId=(.+), brokerHost=(.+), brokerPort=(.+)><>Value
name: kafka_server_$1_$2
type: GAUGE
labels:
clientId: "$3"
broker: "$4:$5"
- pattern: kafka.server<type=(.+), name=(.+)><>OneMinuteRate
name: kafka_server_$1_$2_rate
type: GAUGE
- pattern: kafka.controller<type=(.+), name=(.+)><>Value
name: kafka_controller_$1_$2
type: GAUGE
Şimdi Prometheus’un bu endpoint’i scrape etmesi için konfigürasyon:
# prometheus.yml içine ekle
scrape_configs:
- job_name: 'kafka'
static_configs:
- targets:
- 'kafka-broker-1:7071'
- 'kafka-broker-2:7071'
- 'kafka-broker-3:7071'
scrape_interval: 30s
scrape_timeout: 10s
Consumer Lag İzleme: Burgercraft Gerçek Dünya Senaryosu
Geçen yıl bir e-ticaret müşterisinde şöyle bir durum yaşadık. Sipariş işleme pipeline’ı Kafka üzerinden akıyordu. Güvenlik kamerası gibi izleme kurulmuş ama consumer lag metriği Prometheus’a düzgün çekilmiyordu. Bir kampanya günü consumer lag 2 milyona fırladı, siparişler saatlerce işlenmedi. Sonuçta hem müşteri kaybı hem de ekip içinde ciddi bir özeleştiri seansı oldu.
Consumer lag için en güvenilir yöntem Kafka’nın kendi araçlarını kullanmak:
# Tüm consumer group'ları listele
kafka-consumer-groups.sh --bootstrap-server kafka-broker-1:9092
--list
# Belirli bir group için lag detayı
kafka-consumer-groups.sh --bootstrap-server kafka-broker-1:9092
--describe
--group siparis-isleyici-group
# Lag'ı sürekli izlemek için watch ile kullan
watch -n 5 'kafka-consumer-groups.sh --bootstrap-server kafka-broker-1:9092
--describe --group siparis-isleyici-group'
Burrow, consumer lag izleme için çok daha sofistike bir çözüm. LinkedIn tarafından geliştirildi, HTTP API sunuyor ve lag’ı sadece sayısal değil, trend olarak değerlendiriyor:
# Burrow kurulumu
cd /opt
wget https://github.com/linkedin/Burrow/releases/download/v1.4.0/Burrow_1.4.0_linux_amd64.tar.gz
tar -xzf Burrow_1.4.0_linux_amd64.tar.gz
# Temel konfigürasyon
cat > /etc/burrow/burrow.toml << 'EOF'
[general]
pidfile="/var/run/burrow.pid"
stdout-logfile="/var/log/burrow/burrow.out"
access-control-allow-origin="*"
[logging]
level="info"
[zookeeper]
servers=["zk-1:2181", "zk-2:2181", "zk-3:2181"]
timeout=6
root-path="/kafka"
[kafka.production]
brokers=["kafka-broker-1:9092", "kafka-broker-2:9092", "kafka-broker-3:9092"]
zookeeper=["zk-1:2181"]
[httpserver.default]
address=":8000"
EOF
# Burrow'u başlat
/opt/burrow/burrow --config-dir=/etc/burrow
Broker Performans Optimizasyonu
Broker konfigürasyonu, Kafka performansının belkemiğini oluşturuyor. server.properties dosyasında doğru değerleri bulmak biraz deneyim gerektiriyor.
# /opt/kafka/config/server.properties - Production için optimize edilmiş ayarlar
# Log flush ayarları - disk I/O optimizasyonu
log.flush.interval.messages=10000
log.flush.interval.ms=1000
# Retention ayarları - disk kullanımı kontrolü
log.retention.hours=168
log.retention.bytes=107374182400
log.segment.bytes=1073741824
# Replikasyon performansı
num.replica.fetchers=4
replica.fetch.max.bytes=1048576
replica.lag.time.max.ms=30000
# Network thread'leri
num.network.threads=8
num.io.threads=16
socket.send.buffer.bytes=102400
socket.receive.buffer.bytes=102400
socket.request.max.bytes=104857600
# Background thread optimizasyonu
background.threads=10
num.partitions=6
# Sıkıştırma
compression.type=producer
OS tarafında da bazı kernel parametrelerini ayarlamak performansı ciddi ölçüde artırıyor:
# /etc/sysctl.conf veya /etc/sysctl.d/kafka.conf
# vm.swappiness düşük tutmak Kafka için kritik
vm.swappiness=1
# Dirty page oranları
vm.dirty_ratio=80
vm.dirty_background_ratio=5
# Network buffer'ları
net.core.wmem_default=131072
net.core.rmem_default=131072
net.core.wmem_max=2097152
net.core.rmem_max=2097152
# TCP ayarları
net.ipv4.tcp_window_scaling=1
net.ipv4.tcp_rmem=4096 87380 2097152
net.ipv4.tcp_wmem=4096 65536 2097152
# Sysctl değerlerini uygula
sysctl -p /etc/sysctl.d/kafka.conf
JVM heap boyutu da çok kritik. Kafka için genellikle 6-8 GB heap yeterli; daha fazlası GC pause sürelerini artırır:
# kafka-server-start.sh içindeki KAFKA_HEAP_OPTS
export KAFKA_HEAP_OPTS="-Xmx6g -Xms6g"
# GC logları için
export KAFKA_JVM_PERFORMANCE_OPTS="-server -XX:+UseG1GC
-XX:MaxGCPauseMillis=20
-XX:InitiatingHeapOccupancyPercent=35
-XX:+ExplicitGCInvokesConcurrent
-XX:MaxInlineLevel=15
-Djava.awt.headless=true"
Producer ve Consumer Optimizasyonu
Sadece broker’a odaklanmak yetmez. Producer ve consumer konfigürasyonları da performansı doğrudan etkiliyor.
Producer için kritik parametreler:
- batch.size: Varsayılan 16KB, production’da 64KB-1MB arasında değerler throughput’u artırır
- linger.ms: Producer’ın batch dolmasını bekleme süresi, 5-20ms arası iyi bir başlangıç
- compression.type:
lz4veyasnappynetwork ve disk kullanımını azaltır - acks:
allveri güvenliği için,1performans için - max.in.flight.requests.per.connection: Sıralama önemliyse 1 yapın
Consumer tarafında:
- fetch.min.bytes: Küçük değerler daha fazla istek, büyük değerler daha az ama gecikmeli
- fetch.max.wait.ms: fetch.min.bytes dolmasa bile maksimum bekleme süresi
- max.poll.records: Tek poll’da alınan maksimum kayıt sayısı
- auto.offset.reset:
earliestveyalatest– durumunuza göre seçin
# Consumer group'u sıfırlamak gerektiğinde
# Önce consumer'ları durdurun!
kafka-consumer-groups.sh --bootstrap-server kafka-broker-1:9092
--group siparis-isleyici-group
--reset-offsets
--to-earliest
--topic siparisler
--execute
# Belirli bir timestamp'e gitmek için
kafka-consumer-groups.sh --bootstrap-server kafka-broker-1:9092
--group siparis-isleyici-group
--reset-offsets
--to-datetime 2024-01-15T10:00:00.000
--topic siparisler
--execute
Disk Kullanımı ve Log Yönetimi
Kafka’da disk dolması en sık karşılaşılan sorunlardan biri. Özellikle retention politikası iyi ayarlanmamış cluster’larda gece yarısı pager almak çok nahoş.
# Topic bazında disk kullanımını kontrol et
kafka-log-dirs.sh --bootstrap-server kafka-broker-1:9092
--topic-list siparisler,kullanici-olaylari
--describe | python3 -c "
import json, sys
data = json.load(sys.stdin)
for broker in data['brokers']:
print(f'Broker {broker["broker"]}:')
for log in broker['logDirs']:
print(f' Dir: {log["logDir"]}')
for part in log.get('partitions', []):
size_mb = part['size'] / (1024*1024)
print(f' {part["partition"]}: {size_mb:.1f} MB')
"
# Belirli bir topic için retention'ı dinamik olarak değiştir
kafka-configs.sh --bootstrap-server kafka-broker-1:9092
--alter
--entity-type topics
--entity-name siparisler
--add-config retention.ms=86400000,retention.bytes=5368709120
Under-replicated partition durumunu sürekli kontrol eden basit bir script:
#!/bin/bash
# /opt/kafka/scripts/check-urp.sh
BOOTSTRAP="kafka-broker-1:9092"
ALERT_EMAIL="[email protected]"
URP=$(kafka-topics.sh --bootstrap-server $BOOTSTRAP
--describe
--under-replicated-partitions 2>/dev/null | wc -l)
if [ "$URP" -gt 0 ]; then
echo "UYARI: $URP adet under-replicated partition tespit edildi!" |
mail -s "[KAFKA ALERT] Under-Replicated Partitions" $ALERT_EMAIL
# Hangi partition'ların etkilendiğini logla
kafka-topics.sh --bootstrap-server $BOOTSTRAP
--describe
--under-replicated-partitions >> /var/log/kafka/urp-$(date +%Y%m%d).log
fi
Grafana Dashboard ile Görselleştirme
Prometheus metriklerini Grafana’da görselleştirmek için bazı temel PromQL sorguları:
# Consumer lag toplam (PromQL)
sum(kafka_consumergroup_lag) by (consumergroup, topic)
# Broker request handler idle percent
avg(kafka_server_kafkarequesthandlerpool_requesthandleravgidlepercent) by (instance)
# Bytes in/out rate (5 dakika ortalaması)
rate(kafka_server_brokertopicmetrics_bytesinpersec[5m])
rate(kafka_server_brokertopicmetrics_bytesoutpersec[5m])
# Under-replicated partition sayısı
sum(kafka_server_replicamanager_underreplicatedpartitions) by (instance)
Grafana için alert kuralları da oluşturmak şart. Özellikle şu durumlar için alert olmalı:
- URP > 0 ve 5 dakika boyunca devam ediyor: Kritik
- Consumer Lag > threshold ve artıyor: Uyarı
- Disk kullanımı > %80: Uyarı, > %90: Kritik
- ActiveControllerCount != 1: Kritik
Partition Rebalance ve Leader Election
Broker yeniden başladığında veya ağ problemi yaşandığında partition leader’ları dengesiz dağılabilir. Bunu düzeltmek için:
# Mevcut leader dağılımını kontrol et
kafka-topics.sh --bootstrap-server kafka-broker-1:9092
--describe
--topic siparisler
# Preferred leader election tetikle
kafka-leader-election.sh --bootstrap-server kafka-broker-1:9092
--election-type preferred
--all-topic-partitions
# Partition reassignment için plan oluştur
cat > /tmp/topics-to-rebalance.json << 'EOF'
{
"topics": [
{"topic": "siparisler"},
{"topic": "kullanici-olaylari"}
],
"version": 1
}
EOF
kafka-reassign-partitions.sh
--bootstrap-server kafka-broker-1:9092
--broker-list "1,2,3"
--topics-to-move-json-file /tmp/topics-to-rebalance.json
--generate
# Üretilen planı uygula (generate çıktısından alınan JSON ile)
kafka-reassign-partitions.sh
--bootstrap-server kafka-broker-1:9092
--reassignment-json-file /tmp/reassignment-plan.json
--execute
# İlerlemeyi takip et
kafka-reassign-partitions.sh
--bootstrap-server kafka-broker-1:9092
--reassignment-json-file /tmp/reassignment-plan.json
--verify
Yaygın Sorunlar ve Hızlı Çözümler
Yıllar içinde tekrar tekrar karşılaştığım birkaç durumu paylaşayım:
“Brokere bağlanamıyorum” senaryosu: İlk baktığınız yer advertised.listeners olsun. Broker’ın kendi IP’sini doğru announce etmediği durumlar çok yaygın. Docker veya cloud ortamında özellikle dikkat edin.
“Consumer lag birden fırladı” senaryosu: Önce consumer’ların çalışıp çalışmadığını kontrol edin, sonra mesaj boyutunun değişip değişmediğine bakın, ardından GC duraksama loglarını inceleyin.
“Disk doldu” senaryosu: Panik yapmayın. Önce log retention’ı geçici olarak düşürün, sonra kalıcı çözümü planlayın. En hızlı disk kazanma yöntemi log.retention.ms değerini küçültmek.
“Yavaş producer” senaryosu: batch.size ve linger.ms değerlerini artırın. acks=all kullanıyorsanız ve min.insync.replicas düşükse acks=1 ile test edin.
Sonuç
Kafka cluster izleme, reaktif değil proaktif bir yaklaşım gerektiriyor. URP ve consumer lag için sağlam alertler kurmadan, JVM ve OS parametrelerini doğru ayarlamadan Kafka’yı production’a almak zamanla ciddi sorunlara kapı aralıyor.
Burada anlattıklarımın özeti şu: önce temel metrikleri toplayın ve görselleştirin, ardından alertleri kademeli eşiklerle kurun, sonra konfigürasyonu yük testleriyle optimize edin. Kafka’yı kurup unutmak değil, canlı bir sistem gibi takip etmek gerekiyor.
Özellikle Burrow ile consumer lag trend analizi ve Prometheus + Grafana stack’i birleştiğinde çok iyi bir gözlemlenebilirlik elde ediyorsunuz. Bu kurulumu yapıp aktif olarak kullanan ekipler, sorunları kullanıcılar fark etmeden önce tespit edip çözebiliyor. Sonunda bu işin özü de zaten bu.
