← Kursa Dön
📄 Text · 30 min

Apache Kafka Temelleri

Apache Kafka, LinkedIn tarafından geliştirilen ve Apache Software Foundation'a bağışlanan dağıtık event streaming platformudur. RabbitMQ'dan farklı olarak Kafka, mesajları geleneksel bir kuyruk gibi değil, dağıtık bir commit log olarak depolar. Bu temel fark, Kafka'yı yüksek throughput, dayanıklılık ve mesaj tekrar oynatma (replay) gerektiren senaryolarda tercih edilen çözüm yapar. Bu derste Kafka'nın temel kavramlarını, mimarisini ve çalışma prensiplerini derinlemesine inceleyeceğiz.

Distributed Log (Dağıtık Günlük)

Kafka'nın kalbinde append-only log yapısı yatar. Her mesaj (record), log'un sonuna eklenir ve bir offset numarası alır. Mesajlar kuyruktan "tüketilip silinmez" — belirlenen süre boyunca (retention period) disktte kalır.

Partition Log:
┌─────┬─────┬─────┬─────┬─────┬─────┬─────┐
│  0  │  1  │  2  │  3  │  4  │  5  │  6  │  ← offset numaraları
└─────┴─────┴─────┴─────┴─────┴─────┴─────┘
                          ▲              ▲
                     Consumer A      Consumer B
                    (offset: 3)     (offset: 6)

Bu modelin avantajları:

  1. Replay: Consumer istediği offset'ten tekrar okuyabilir. Hata sonrası veri tekrar işlenebilir.

  2. Birden fazla consumer: Aynı veriyi farklı consumer'lar bağımsızca okuyabilir.

  3. Yüksek throughput: Sıralı disk yazma (sequential I/O), random I/O'dan çok daha hızlıdır.

  4. Zaman yolculuğu: Belirli bir zamandaki veriye geri dönüp yeniden işleyebilirsiniz.

Topic ve Partition

Topic: Kafka'da mesajların mantıksal kategorisidir. Bir veritabanı tablosuna benzetilebilir. Örneğin, orders, payments, user-events gibi topic'ler oluşturulur.

Partition: Her topic, bir veya daha fazla partition'a bölünür. Partition, Kafka'nın paralellik ve ölçekleme birimidir.

Topic: "orders" (3 partition)

Partition 0: [msg-0] [msg-3] [msg-6] [msg-9]
Partition 1: [msg-1] [msg-4] [msg-7]
Partition 2: [msg-2] [msg-5] [msg-8]

Partition'ların kritik özellikleri:

  • Sıralama garantisi: Bir partition içinde mesajlar kesinlikle sıralıdır. Ancak partition'lar arasında sıralama garantisi yoktur.

  • Paralel işleme: Her partition bağımsız olarak bir consumer tarafından okunabilir.

  • Key-based routing: Mesajın key'ine göre hangi partition'a gideceği belirlenir. Aynı key'e sahip mesajlar her zaman aynı partition'a gider.

// Key ile partition belirleme
// Aynı orderId'ye sahip tüm mesajlar aynı partition'a gider
producer.send(new ProducerRecord<>("orders", order.getId(), orderJson));

Consumer Group

Consumer group, aynı topic'i paralel olarak okuyan consumer'lar topluluğudur. Kafka, her partition'ı grup içindeki yalnızca bir consumer'a atar.

Topic: "orders" (4 partition)

Consumer Group "order-service":
  Consumer A ← Partition 0, Partition 1
  Consumer B ← Partition 2, Partition 3

Consumer Group "analytics-service":
  Consumer C ← Partition 0, Partition 1, Partition 2, Partition 3

Önemli kurallar:

  1. Bir partition, aynı grup içinde yalnızca bir consumer tarafından okunur.

  2. Farklı consumer group'lar, tüm mesajları bağımsızca alır (pub/sub davranışı).

  3. Consumer sayısı partition sayısından fazlaysa, fazla consumer'lar idle kalır.

  4. Consumer eklendikçe veya çıktıkça rebalancing gerçekleşir — partition'lar yeniden dağıtılır.

Bu mekanizma, point-to-point (grup içi) ve pub/sub (gruplar arası) modellerini tek bir sistemde birleştirir.

Offset Yönetimi

Offset, consumer'ın bir partition'da hangi mesajı okuduğunu gösteren sayıdır. Kafka, offset yönetimini consumer'a bırakır (broker mesajı silmez):

  • Committed offset: Consumer'ın başarıyla işlediğini bildirdiği son offset.

  • Current offset: Consumer'ın şu an okumakta olduğu offset.

  • Log-end offset: Partition'daki en son mesajın offset'i.

Partition:  [0] [1] [2] [3] [4] [5] [6] [7] [8]
                          ▲              ▲     ▲
                     committed      current  log-end
                      offset        offset   offset
                      (lag = 8 - 3 = 5 mesaj geride)

Offset commit stratejileri:

  • Auto-commit: Belirli aralıklarla otomatik commit (enable.auto.commit=true). Basit ama mesaj kaybı riski var.

  • Manual commit: Consumer, mesajı işledikten sonra açıkça commit eder. Daha güvenli ama daha karmaşık.

Kafka Broker ve Zookeeper/KRaft

Broker: Kafka cluster'ındaki her sunucu bir broker'dır. Broker'lar veriyi depolar, producer ve consumer isteklerini karşılar.

Kafka Cluster:
┌───────────┐  ┌───────────┐  ┌───────────┐
│  Broker 1  │  │  Broker 2  │  │  Broker 3  │
│ Partition  │  │ Partition  │  │ Partition  │
│  0 (L)     │  │  1 (L)     │  │  2 (L)     │
│  1 (R)     │  │  2 (R)     │  │  0 (R)     │
└───────────┘  └───────────┘  └───────────┘
  L = Leader, R = Replica

Zookeeper (eski model): Cluster metadata yönetimi, broker keşfi, leader seçimi ve yapılandırma koordinasyonu için kullanılırdı. Kafka 2.8+ ile KRaft (Kafka Raft) modu geldi — Zookeeper'a bağımlılık kaldırıldı. KRaft, metadata yönetimini Kafka'nın kendi içinde yapar.

# Docker Compose ile Kafka (KRaft mode — Zookeeper'sız)
docker run -d --name kafka \
  -p 9092:9092 \
  -e KAFKA_NODE_ID=1 \
  -e KAFKA_PROCESS_ROLES=broker,controller \
  -e KAFKA_LISTENERS=PLAINTEXT://0.0.0.0:9092,CONTROLLER://0.0.0.0:9093 \
  -e KAFKA_CONTROLLER_QUORUM_VOTERS=1@localhost:9093 \
  apache/kafka:latest

Replication (Çoğaltma)

Kafka, veri kaybını önlemek için partition'ları birden fazla broker'a kopyalar:

  • Replication factor: Her partition'ın kaç kopyası tutulacağını belirler (genelde 3).

  • Leader: Bir partition'ın okunma/yazma işlemlerini karşılayan birincil kopya.

  • Follower (Replica): Leader'dan veriyi çoğaltan yedek kopyalar.

  • ISR (In-Sync Replicas): Leader ile senkron olan replica'lar kümesi. Leader çökerse, ISR'dan biri yeni leader seçilir.

Topic: "orders", Partition 0, Replication Factor: 3

Broker 1: Partition 0 [LEADER]   → yazma/okuma burada
Broker 2: Partition 0 [FOLLOWER] → leader'dan kopyalar
Broker 3: Partition 0 [FOLLOWER] → leader'dan kopyalar

acks ayarı ile yazma güvenilirliği kontrol edilir:

acksDavranışGüvenilirlikPerformans
0Onay beklemezEn düşükEn yüksek
1Sadece leader onaylarOrtaOrta
allTüm ISR onaylarEn yüksekEn düşük

Ordering Guarantees (Sıralama Garantileri)

Kafka'da sıralama garantileri partition seviyesindedir:

  1. Partition içi: Mesajlar kesinlikle gönderilme sırasında teslim edilir.

  2. Partition arası: Sıralama garantisi yoktur.

  3. Key-based ordering: Aynı key'e sahip mesajlar aynı partition'a gider → sıraları korunur.

// Sipariş olayları — aynı orderId'nin tüm olayları sıralı kalır
producer.send(new ProducerRecord<>("order-events", orderId, "CREATED"));
producer.send(new ProducerRecord<>("order-events", orderId, "PAID"));
producer.send(new ProducerRecord<>("order-events", orderId, "SHIPPED"));
// Aynı partition'a gider → sıra: CREATED → PAID → SHIPPED

Kafka vs RabbitMQ: Ne Zaman Hangisi?

KriterRabbitMQKafka
ModelMessage queueDistributed log
Mesaj tüketimiTüketilince silinirRetention süresi boyunca kalır
ReplayYokVar (offset'ten tekrar okuma)
ThroughputOrta (10K-50K msg/s)Çok yüksek (100K-1M+ msg/s)
RoutingZengin (exchange türleri)Basit (topic + partition)
Kullanımİş kuyrukları, RPC, routingEvent streaming, log, analytics
ProtokolAMQP, STOMP, MQTTKafka Protocol