Apache Kafka Nedir: Dağıtık Mesajlaşma Sistemine Giriş
Üretim ortamınızda bir servis çöktüğünde, diğer servisler de domino taşları gibi devrilmeye başladıysa, büyük ihtimalle aralarında sıkı bir bağımlılık var demektir. Mesajlaşma sistemleri tam da bu noktada devreye girer: servisleri birbirinden ayırır, yük altında tampon görevi görür ve sistemin genel dayanıklılığını artırır. Apache Kafka ise bu kategorideki araçlar arasında son yıllarda açık ara öne çıkan isim.
Kafka’yı ilk duyduğumda “başka bir mesaj kuyruğu mu?” diye düşünmüştüm açıkçası. RabbitMQ kullanıyorduk, işler yürüyordu. Ama milyonlarca mesajın saniyeler içinde işlenmesi gerektiğinde, geriye dönük mesaj okuma ihtiyacı doğduğunda ya da aynı mesajı birden fazla bağımsız sistemin tüketmesi gerektiğinde tablo değişiyor. Kafka bu senaryolarda bambaşka bir canavarı.
Apache Kafka Nedir, Ne Değildir
Kafka, LinkedIn tarafından 2011 yılında açık kaynak olarak yayınlanan, şu anda Apache Software Foundation çatısı altında geliştirilen dağıtık bir event streaming platformudur. Sadece “mesaj kuyruğu” demek biraz eksik kalır; Kafka aynı zamanda bir log depolama sistemi, bir veri akışı platformu ve bir gerçek zamanlı analitik altyapısıdır.
Geleneksel mesaj kuyruklarından farkı birkaç temel nokta üzerinde yoğunlaşır:
- Kalıcı depolama: Kafka, mesajları tüketen sisteme iletip silmez. Yapılandırdığınız süre boyunca (varsayılan 7 gün) mesajları diskte saklar.
- Log tabanlı mimari: Mesajlar sıralı log dosyaları olarak yazılır, okuma işlemi bu log üzerinde gerçekleşir.
- Consumer grup kavramı: Aynı mesajı birbirinden bağımsız birden fazla uygulama okuyabilir.
- Yatay ölçeklenebilirlik: Partition yapısı sayesinde hem yazma hem okuma işlemleri paralel yürütülür.
- Yüksek throughput: Donanıma bağlı olarak saniyede milyonlarca mesaj işlenebilir.
Kafka’nın uygun olmadığı durumlar da var. Çok küçük ölçekli uygulamalarda, mesaj önceliği önemli olduğunda veya karmaşık yönlendirme mantığı gerektiren durumlarda RabbitMQ gibi araçlar daha pratik olabilir.
Temel Kavramlar
Kafka kurulumuna geçmeden önce terminolojiyi netleştirmek gerekiyor. Bu kavramları anlamadan Kafka’yı yönetmek oldukça zorlaşır.
Topic ve Partition
Topic, mesajların kategorize edildiği mantıksal birimdir. Uygulamanız kullanıcı etkinliklerini takip ediyorsa user-events adında bir topic açarsınız, sipariş bildirimlerini order-notifications topicine yazarsınız.
Her topic birden fazla partition‘a bölünür. Partition, Kafka’nın paralel işleme gücünün temel kaynağıdır. Bir partition sıralıdır ve değiştirilemezdir; yeni mesajlar her zaman sona eklenir. Partition sayısını artırmak, throughput’u artırır ama mesaj sıralaması garantisi yalnızca aynı partition içinde geçerlidir. Bu önemli bir nokta.
Producer ve Consumer
Producer, Kafka’ya mesaj yazan taraftır. Hangi topice yazacağını ve isteğe bağlı olarak hangi partition’a gideceğini belirler.
Consumer, Kafka’dan mesaj okuyan taraftır. Consumer’lar consumer group adı verilen gruplar halinde çalışır. Bir consumer group içindeki her consumer, farklı partition’ları okur. Bu sayede yük dengeleme otomatik olarak gerçekleşir.
Broker ve Cluster
Broker, Kafka’nın çalıştığı sunucu düğümüdür. Birden fazla broker bir araya gelince cluster oluşur. Cluster yapısı hem yüksek erişilebilirlik hem de yatay ölçekleme sağlar.
Offset
Her mesajın partition içinde bir sıra numarası vardır, buna offset denir. Consumer’lar hangi mesajı en son okuduklarını offset bilgisiyle takip eder. Bu mekanizma sayesinde bir consumer çöküp yeniden başladığında kaldığı yerden devam edebilir.
Replication Factor
Her partition’ın birden fazla kopyası farklı broker’larda tutulabilir. Bu kopya sayısına replication factor denir. Bir broker düştüğünde ilgili partition’ların kopyaları diğer broker’larda olduğu için sistem çalışmaya devam eder.
Kafka Kurulumu
Şimdi işin pratik kısmına geçelim. Geliştirme ortamı için tek node kurulum yapacağız, sonra temel yapılandırmaya değineceğiz.
Gereksinimler
Kafka’nın çalışması için Java gerekmektedir. Kafka 3.x sürümlerinde ZooKeeper bağımlılığı kademeli olarak kaldırılmaya başlandı; KRaft modu artık production için de destekleniyor. Ancak çoğu kurumsal ortamda hâlâ ZooKeeper göreceksiniz, o yüzden her iki yapıyı da ele alacağız.
# Java kurulumu (Ubuntu/Debian)
sudo apt update
sudo apt install -y openjdk-17-jdk
# Java versiyonunu kontrol et
java -version
# Kafka indir ve çıkart
wget https://downloads.apache.org/kafka/3.6.1/kafka_2.13-3.6.1.tgz
tar -xzf kafka_2.13-3.6.1.tgz
sudo mv kafka_2.13-3.6.1 /opt/kafka
cd /opt/kafka
ZooKeeper ile Geleneksel Kurulum
ZooKeeper, Kafka cluster’ının meta verilerini (topic bilgileri, partition liderliği, consumer group durumları) yönetir. Kafka 3.x öncesi sürümlerde zorunludur.
# ZooKeeper konfigürasyonu (config/zookeeper.properties)
cat > /opt/kafka/config/zookeeper.properties << 'EOF'
dataDir=/var/lib/zookeeper
clientPort=2181
maxClientCnxns=0
admin.enableServer=false
EOF
# ZooKeeper başlat
/opt/kafka/bin/zookeeper-server-start.sh -daemon /opt/kafka/config/zookeeper.properties
# Kafka broker konfigürasyonu (config/server.properties temel ayarları)
# Bu dosyada kritik parametreler:
# broker.id=0 -> Her broker'ın benzersiz kimliği
# listeners=PLAINTEXT://0.0.0.0:9092
# log.dirs=/var/lib/kafka/logs
# zookeeper.connect=localhost:2181
# Kafka broker başlat
/opt/kafka/bin/kafka-server-start.sh -daemon /opt/kafka/config/server.properties
KRaft Modu ile Modern Kurulum
Kafka 3.3+ sürümlerinde KRaft modu production-ready olarak sunuluyor. ZooKeeper bağımlılığını ortadan kaldırıyor, daha az karmaşıklık, daha hızlı metadata operasyonları sağlıyor.
# KRaft için benzersiz cluster ID üret
KAFKA_CLUSTER_ID=$(/opt/kafka/bin/kafka-storage.sh random-uuid)
echo "Cluster ID: $KAFKA_CLUSTER_ID"
# KRaft konfigürasyon dosyasını düzenle
# config/kraft/server.properties içindeki kritik parametreler:
# process.roles=broker,controller
# node.id=1
# controller.quorum.voters=1@localhost:9093
# listeners=PLAINTEXT://localhost:9092,CONTROLLER://localhost:9093
# Storage formatla
/opt/kafka/bin/kafka-storage.sh format
-t $KAFKA_CLUSTER_ID
-c /opt/kafka/config/kraft/server.properties
# Kafka'yı KRaft moduyla başlat
/opt/kafka/bin/kafka-server-start.sh -daemon
/opt/kafka/config/kraft/server.properties
# Servisi kontrol et
/opt/kafka/bin/kafka-broker-api-versions.sh
--bootstrap-server localhost:9092
Systemd Servis Tanımları
Production ortamında Kafka’yı systemd ile yönetmek en mantıklı yaklaşım.
# /etc/systemd/system/kafka.service
sudo tee /etc/systemd/system/kafka.service > /dev/null << 'EOF'
[Unit]
Description=Apache Kafka Server
Documentation=http://kafka.apache.org/documentation.html
Requires=network.target
After=network.target
[Service]
Type=simple
User=kafka
Group=kafka
Environment="JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64"
Environment="KAFKA_HEAP_OPTS=-Xmx2G -Xms2G"
ExecStart=/opt/kafka/bin/kafka-server-start.sh /opt/kafka/config/kraft/server.properties
ExecStop=/opt/kafka/bin/kafka-server-stop.sh
Restart=on-failure
RestartSec=10
TimeoutStopSec=30
[Install]
WantedBy=multi-user.target
EOF
# Kafka kullanıcısı oluştur
sudo useradd -r -s /bin/false kafka
sudo chown -R kafka:kafka /opt/kafka /var/lib/kafka
# Servisi etkinleştir ve başlat
sudo systemctl daemon-reload
sudo systemctl enable kafka
sudo systemctl start kafka
sudo systemctl status kafka
Temel Kafka Operasyonları
Kafka kurulumunun ardından günlük yönetim operasyonlarını öğrenmek gerekiyor.
# Topic oluştur
/opt/kafka/bin/kafka-topics.sh
--create
--bootstrap-server localhost:9092
--topic user-events
--partitions 3
--replication-factor 1
# Topic listele
/opt/kafka/bin/kafka-topics.sh
--list
--bootstrap-server localhost:9092
# Topic detaylarını görüntüle
/opt/kafka/bin/kafka-topics.sh
--describe
--bootstrap-server localhost:9092
--topic user-events
# Mesaj gönder (console producer)
/opt/kafka/bin/kafka-console-producer.sh
--bootstrap-server localhost:9092
--topic user-events
# Mesaj oku (baştan itibaren)
/opt/kafka/bin/kafka-console-consumer.sh
--bootstrap-server localhost:9092
--topic user-events
--from-beginning
--group test-consumer-group
# Consumer group lag durumunu kontrol et
/opt/kafka/bin/kafka-consumer-groups.sh
--bootstrap-server localhost:9092
--describe
--group test-consumer-group
# Topic silme
/opt/kafka/bin/kafka-topics.sh
--delete
--bootstrap-server localhost:9092
--topic user-events
Gerçek Dünya Senaryosu: E-Ticaret Platformu
Soyut kavramları bir kenara bırakıp somut bir senaryoya bakalım. Diyelim ki orta ölçekli bir e-ticaret platformunuz var. Sipariş verildiğinde şu sistemlerin haberdar olması gerekiyor:
- Stok yönetim sistemi (stok düşülmeli)
- Bildirim servisi (müşteriye e-posta/SMS gönderilmeli)
- Muhasebe sistemi (fatura oluşturulmalı)
- Analitik platform (raporlama için veri aktarılmalı)
Kafka öncesinde bu sistemlerin her birini doğrudan çağırıyordunuz. Bildirim servisi çöktüğünde sipariş işlemi de başarısız oluyordu ya da onlarca satır retry mantığı yazıyordunuz.
Kafka ile çözüm şu şekilde işliyor: Sipariş servisi sadece order-created topicine bir mesaj yazar. Bu kadar. Stok servisi, bildirim servisi, muhasebe sistemi ve analitik platform hepsi bu topici bağımsız consumer group’larla dinler. Bildirim servisi çöküp 10 dakika sonra ayağa kalktığında, o süre zarfında gelen tüm siparişlerin mesajlarını sırayla okuyup e-postaları gönderir. Diğer sistemler bundan hiç etkilenmemiştir.
# E-ticaret topiclerini oluştur
for topic in order-created order-updated payment-events inventory-updates; do
/opt/kafka/bin/kafka-topics.sh
--create
--bootstrap-server localhost:9092
--topic $topic
--partitions 6
--replication-factor 2
--config retention.ms=604800000
--config min.insync.replicas=2
echo "Topic oluşturuldu: $topic"
done
# Partition sayısını sonradan artırma (azaltmak mümkün değil)
/opt/kafka/bin/kafka-topics.sh
--alter
--bootstrap-server localhost:9092
--topic order-created
--partitions 12
Önemli Konfigürasyon Parametreleri
server.properties dosyasındaki kritik parametreleri bilmek, Kafka’yı sağlıklı çalıştırmanın olmazsa olmazı.
Broker Konfigürasyonu:
- log.retention.hours=168: Mesajların ne kadar süre saklanacağı (varsayılan 7 gün)
- log.retention.bytes=-1: Topic başına maksimum disk alanı (-1 sınırsız demek)
- log.segment.bytes=1073741824: Her log segmentinin maksimum boyutu (1 GB)
- num.partitions=3: Yeni topic’ler için varsayılan partition sayısı
- default.replication.factor=2: Varsayılan replication faktörü
- min.insync.replicas=2: Yazma onayı için minimum senkron replica sayısı
- auto.create.topics.enable=false: Otomatik topic oluşturmayı kapatın, production’da şart
Producer Konfigürasyonu:
- acks=all: Tüm in-sync replica’lardan onay bekle, veri kaybını önler
- retries=3: Başarısız yazma denemelerinde yeniden deneme sayısı
- batch.size=16384: Toplu mesaj gönderiminde batch boyutu (byte)
- linger.ms=5: Batch dolmadan önce bekleme süresi (ms)
- compression.type=lz4: Mesaj sıkıştırma, ağ ve disk kullanımını azaltır
Consumer Konfigürasyonu:
- auto.offset.reset=earliest: Consumer grubu ilk başladığında baştan oku
- enable.auto.commit=false: Offset commit’i manuel yönetin, veri kaybı riskini azaltır
- max.poll.records=500: Tek poll’da maksimum alınacak mesaj sayısı
- session.timeout.ms=30000: Consumer’ın canlı olduğunu bildirmesi için maksimum süre
Monitoring ve Sağlık Kontrolü
Kafka’yı kurup bırakmak olmaz. Neler olup bittiğini sürekli izlemek gerekiyor.
# JMX üzerinden metrik almak için
# KAFKA_JMX_OPTS ortam değişkenini ayarla
export KAFKA_JMX_OPTS="-Dcom.sun.jmx.snmp.daemon.port=9999
-Dcom.sun.jmx.snmp.daemon.hostname=localhost
-Dcom.sun.management.jmxremote=true
-Dcom.sun.management.jmxremote.port=9999
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false"
# Consumer lag izleme scripti
#!/bin/bash
# kafka-lag-check.sh
BOOTSTRAP="localhost:9092"
GROUP=$1
if [ -z "$GROUP" ]; then
echo "Kullanim: $0 <consumer-group-adi>"
exit 1
fi
echo "=== Consumer Group Lag Raporu: $GROUP ==="
/opt/kafka/bin/kafka-consumer-groups.sh
--bootstrap-server $BOOTSTRAP
--describe
--group $GROUP
2>/dev/null | awk 'NR>1 {
if ($5 != "-") {
lag += $5
count++
}
}
END {
print "Toplam Lag: " lag
print "Partition Sayisi: " count
if (lag > 10000) print "UYARI: Yuksek lag tespit edildi!"
}'
# Broker liderlik dağılımını kontrol et
/opt/kafka/bin/kafka-topics.sh
--describe
--bootstrap-server localhost:9092
--under-replicated-partitions
# Log dizini boyutunu kontrol et
du -sh /var/lib/kafka/logs/*/
Kafka için Kafka UI (eski adıyla AKHQ), Prometheus + Grafana stack’i veya Confluent Control Center gibi görsel araçlar da oldukça işe yarıyor. Küçük ortamlar için Kafka UI yeterli olacaktır; Docker ile birkaç dakikada ayağa kaldırabilirsiniz.
Sık Yapılan Hatalar
Birkaç yıllık Kafka yönetiminden derlediğim hatalar listesi:
Çok az partition açmak: Sonradan artırabilirsiniz ama başlangıçta düşük açılan partition sayısı throughput darboğazına yol açar. Genellikle broker sayısının 3-5 katı kadar partition açmak iyi bir başlangıçtır.
auto.create.topics.enable=true bırakmak: Yanlış topic adına mesaj gönderildiğinde otomatik oluşturulan topic’ler izlenmesi güç bir kaosa yol açar.
Retention süresini çok düşük ayarlamak: Consumer’lar geride kaldığında mesajlar silinmiş olabilir. Kapasiteniz yeterliyse retention süresini yüksek tutun.
Replication factor=1 kullanmak: Tek broker çöktüğünde tüm veriyi kaybedebilirsiniz. Minimum 2, tercihen 3 replication factor kullanın.
Heap size’ı ayarlamamak: Kafka varsayılan olarak 1 GB heap kullanır. Production ortamında bu yetersizdir. KAFKA_HEAP_OPTS="-Xmx6G -Xms6G" gibi bir değer genellikle daha uygun olur.
Sonuç
Kafka, doğru probleme uygulandığında gerçekten transformatif bir araç. Servisleri birbirinden ayırmak, milyonlarca eventi gerçek zamanlı işlemek, geçmiş veriyi yeniden işleyebilmek – bunlar Kafka’nın parlayan yönleri.
Ama her şeyde olduğu gibi burada da “doğru araç, doğru iş” prensibi geçerli. Günde birkaç bin mesaj işleyen, basit yönlendirme mantığı gerektiren bir sistem için Kafka’yı devreye almak gereksiz operasyonel yük demektir. RabbitMQ ya da hatta basit bir veritabanı tablosu bazen daha pragmatik çözümler sunar.
Geliştirme ortamında Kafka’yı kurup oynayın, consumer lag kavramını deneyimleyin, bir broker’ı kapatıp cluster’ın nasıl tepki verdiğini gözlemleyin. Bu kavramları el ile yaşamak, teorik olarak okumaktan çok daha akılda kalıcı oluyor. Sonraki yazılarda cluster kurulumu, güvenlik yapılandırması (SSL/SASL) ve Kafka Streams’e değineceğiz.
