Message Queues vs Streams — Kuyruklar ve Stream'ler Arasındaki Temel Farklar ve Mimariler
1. GİRİŞ
Dağıtık sistemler ve mikroservis uygulamaları geliştikçe sistemler arası iletişimde iki ana paradigma öne çıkmıştır: message queues (mesaj kuyrukları) ve streams (olay akışları). Birçok mühendis "kuyruk mu yoksa stream mi" sorusuyla karşı karşıya kalır; doğru cevap ise uygulamanın gereksinimlerine, teslim garantilerine, ordering ihtiyaçlarına ve operasyonel hedeflere bağlıdır. Bu makale, kuyruklar ve stream'lerin konseptlerini, teknik farklarını, tipik kullanım desenlerini, üretimde karşılaşılan zorlukları ve en iyi uygulamaları derinlemesine inceler.
Bu konu neden bugün önemli?
- Gerçek zamanlı veri işleme, event sourcing ve mikroservis entegrasyonları yaygınlaştı.
- Bulut sağlayıcılarının managed stream ve queuing hizmetleri (Kafka, Pulsar, SQS, RabbitMQ, Event Hubs) ile mimari kararlar daha görünür hale geldi.
- Performans, veri tutarlılığı, maliyet ve operasyonel karmaşıklığın dengelenmesi gerekliliği arttı.
Kimler için önemli?
- Yazılım mimarları ve backend mühendisleri
- Data mühendisleri ve gerçek zamanlı akış işleme ekipleri
- SRE/Platform mühendisleri ve teknik liderler
Hangi problemleri çözüyor?
- Asenkron işlem ve iş parçacığı ayırma
- Olay tabanlı entegrasyon, event sourcing ve replay imkânı
- Backpressure, burst yönetimi ve pipeline çağıldırma
2. KAVRAMSAL TEMELLER
2.1 Message Queue (Kuyruk) nedir?
Message queue, üreticinin (producer) gönderdiği mesajları bir kuyruğa koyan ve tüketicilerin (consumer) bu mesajları sırayla işleyebildiği bir modeldir. Kuyruk modelleri genelde point‑to‑point iletişim için uygundur: bir mesaj bir veya belirli tüketici grupları tarafından işlenir. Küruklar basit iş dağıtımı, retry ve dead‑letter mekanizmaları ile klasik asenkron görevleri çözmede etkilidir.
2.2 Stream (Akış) nedir?
Stream, zaman içinde sürekli üretilen olayların (event) tutulduğu, append‑only (sadece ekleme) bir log modeline dayanır. Stream'ler genelde publish‑subscribe desenine uygundur; aynı olay birçok tüketici tarafından farklı zamanlarda okunabilir. Stream'lerin en önemli özelliği replay yeteneği: tüketiciler geçmişe dönüp eski mesajları tekrar okuyabilir ve state'i yeniden inşa edebilir.
2.3 Temel terminoloji
- Producer: Mesaj/olay üreten taraf.
- Consumer / Subscriber: Mesajları işleyen taraf.
- Broker: Mesajları saklayan ve dağıtan altyapı (Kafka, RabbitMQ, Pulsar, SQS, Event Hubs).
- Partition: Stream'lerde veri paralelliğini sağlayan segment; ordering partition düzeyindedir.
- Offset / Cursor: Bir tüketicinin stream'de okuduğu pozisyon.
- Retention: Mesajların tutulma süresi veya saklama politikası.
3. NASIL ÇALIŞIR? — TEKNİK KARŞILAŞTIRMA
3.1 Veri modeli ve saklama
Kuyruklar genellikle mesajları kısa süreli saklar (ör. işler işlenene kadar). Mesaj tüketildikten sonra tipik olarak kuyruktan silinir. Stream'ler ise append‑only bir logdur; mesajlar retention politikası süresince saklanır ve birçok tüketici tarafından tekrar okunabilir. Bu fark, replay, audit ve event sourcing gibi senaryolardaki temel ayrımı oluşturur.
3.2 Ordering ve paralellik
Kuyruklarda ordering genelde kuyruk mantığıyla sağlanır — tüketici sırayla mesaj alır. Stream'lerde ordering partition bazlıdır: aynı partition içindeki mesajların sırası korunur, farklı partition'lar paralel işlenir. Bu nedenle partition key seçimi stream performansı ve ordering garantisi açısından kritik bir tasarım kararıdır.
3.3 Delivery semantics (teslim garantileri)
Hem kuyruklar hem de stream'ler farklı teslim garantileri sunabilir: at‑most‑once (en fazla bir defa), at‑least‑once (en az bir defa) veya exactly‑once (tam bir defa). Ancak exactly‑once pratikte karmaşık ve maliyetlidir; stream platformları (Kafka Streams, Flink) veya transactional outbox pattern kombinasyonları ile sınırlı senaryolarda uygulanabilir. Kuyruk tabanlı broker'lar genelde at‑least‑once ile çalışır, duplicate handling uygulamaya bırakılır.
3.4 Replay ve state reconstruction
Stream'ler replay özelliği ile öne çıkar: consumer'lar geçmişe dönük offset'i çekip yeniden işlem yapabilir. Bu özellik event sourcing, debugging, reprocessing ve analytics için çok değerlidir. Kuyruklarda genellikle böyle bir replay mekanizması yoktur veya sınırlıdır (dead‑letter veya dead‑letter topic çözümleri hariç).
3.5 Time semantics ve windowing
Stream processing ekosistemi, event time, processing time ve windowing kavramları ile zaman bazlı hesaplamaları (sliding windows, tumbling windows) destekler. Bu sayede gerçek zamanlı metrikler, aggregasyon ve anomalie detection yapılabilir. Kuyruk çözümleri bu tür ileri zaman bazlı analizler için doğrudan uygun değildir; ek stream processing katmanları gerektirir.
3.6 Retention, compaction ve storage
Stream platformları retention ve compaction (ör. Kafka log compaction) ile son state'i saklayabilir. Compaction, key‑based son değeri saklayarak state store yerine geçebilir. Kuyruk sistemleri genelde short‑lived message retention uygular ve mesaj tüketilince kaybolur.
4. GERÇEK DÜNYA KULLANIMLARI
4.1 Kuyruk kullanım örnekleri
- Background job processing (thumbnail generation, e‑mail send)
- Task queue / worker pool (delayed retry, dead‑letter handling)
- Synchronous systems decoupling: request → enqueue → async processing
- Short‑lived messages with strict delivery and retry semantics
4.2 Stream kullanım örnekleri
- Event sourcing ve CQRS — sistem state'inin olaylarla yeniden inşası
- Real‑time analytics, monitoring ve alerting (kullanıcı davranış analizi)
- CDC (Change Data Capture) pipelines: veritabanı değişikliklerinden akış oluşturma
- Complex stream processing: windowed aggregations, joins, enrichment
4.3 Araçlar ve platformlar
Kuyruk dünyasında RabbitMQ, AWS SQS, Azure Service Bus yaygındır. Stream dünyasında Apache Kafka, Apache Pulsar, AWS Kinesis, Azure Event Hubs öne çıkar. Her bir teknolojinin operasyonel gereksinimleri farklıdır: Kafka storage‑heavy ve I/O intensive iken SQS gibi managed kuyruklar operasyonel bakım yükünü azaltır.
5. AVANTAJLAR VE SINIRLAMALAR
Kuyrukların avantajları
- Basitlik: task queuing ve worker model için tasarlanmıştır
- Retry ve dead‑letter mekanizmaları konusunda olgun çözümler
- Managed çözümlerle operasyonel maliyet düşük olabilir
Kuyrukların sınırlamaları
- Replay ve geçmişe dönük analiz genelde sınırlı
- Event sourcing ve stream processing için doğal bir yapı sunmaz
Stream'lerin avantajları
- Replay ve event sourcing desteği — geçmişi yeniden oynatma
- Zaman bazlı işleme, windowing, stateful stream processing imkânı
- Yüksek throughput ve düşük gecikme için optimize edilebilir
Stream'lerin sınırlamaları
- Operasyonel karmaşıklık: disk I/O, retention, rebalancing yönetimi
- Exactly‑once semantics uygulamak zor ve maliyetlidir
- Partitioning ve hot‑key problemleri mimari hatalara yol açabilir
6. ALTERNATİFLER VE KARŞILAŞTIRMA
| Yaklaşım | Avantaj | Dezavantaj |
|---|---|---|
| Message Queue (RabbitMQ, SQS) | Basit task queue, retry & DLQ, düşük işletimsel başlangıç maliyeti | Replay & historical analysis sınırlı |
| Stream (Kafka, Pulsar) | Replay, event sourcing, yüksek throughput, stream processing | Operasyonel karmaşıklık, storage maliyeti |
| Hybrid (outbox + stream) | Veritabanı tutarlılığı + stream replay (outbox pattern), transactional publish | Ek bileşenler ve gecikmeler, tasarım karmaşıklığı |
7. EN İYİ PRATİKLER
Production kullanımı
- İhtiyacı doğru tanımlayın: replay ve audit gerekiyorsa stream; sadece iş kuyruğu gerekiyorsa queue seçin.
- Mesaj boyutunu sınırlayın; payload büyükse nesneleri object store'a koyun ve referans gönderin.
- Consumer idempotency ve deduplication uygulayın; at‑least‑once garantilerinde duplicate bekleyin.
- Monitoring: consumer lag, partition distribution, throughput, broker disk ve I/O metriklerini izleyin.
Performans optimizasyonu
- Batching ve pipelining ile throughput'u artırın; küçük mesajlarda overhead'ı minimize edin.
- Partition key design: hot key'leri tespit edip çözün (hashing, key salting veya re‑partitioning).
- Retention ve compaction politikalarını iş gereksinimlerine göre optimize edin; storage maliyetlerini yönetin.
Güvenlik
- TLS ile encryption in transit, broker access için IAM veya ACL bazlı authentication uygulayın.
- Audit log ve topic/queue seviyesinde authorization ile yetkilendirmeyi kesinleştirin.
Observability
- Lag, consumer throughput, broker under‑replication, disk usage ve GC/OS metrikleri için alert'ler kurun.
- Trace'leri uçtan uca korelasyonlayın: produce → broker → consume işlemlerini takip edin.
8. SIK YAPILAN HATALAR
- Replay gereksinimi olmadan stream kullanmak — maliyet ve karmaşıklık artar.
- Partition key seçiminde iş yükünü yanlış analiz etmek — hot partition oluşumu.
- Idempotency ihmal etmek — duplicate mesajlar iş mantığını bozabilir.
- Monitoring eksikliği — consumer lag veya under‑replication geç fark edilir.
9. GELECEK TRENDLER
- Serverless streaming: Managed, otomatik ölçeklenen stream hizmetleri ve stream processing FaaS kombinasyonları artacak.
- Exactly‑once pragmatism: Exactly‑once semantics'in daha erişilebilir ve performans dostu implementasyonları ortaya çıkacak.
- Hybrid event platforms: Stream ve queue özelliklerini birleştiren hibrit platformlar (event mesh, unified event platform) yaygınlaşacak.
- AI‑assisted routing: Telemetry'ye dayalı dinamik partitioning ve mesaj yönlendirme optimizasyonları geliştirilecek.
EK BÖLÜMLER
Sık Sorulan Sorular (FAQ)
- 1. Kuyruk mu yoksa stream mi kullanmalıyım?
Kısa cevap: replay, audit, event sourcing veya real‑time analytics gerekiyorsa stream; basit task queue ve worker modeli gerekiyorsa queue tercih edin. Karar iş gereksinimleri, SLA ve operasyonel yetkinliklere göre verilmelidir.
- 2. Exactly‑once nasıl sağlanır?
Exactly‑once pratikte transactional outbox pattern, idempotent consumer ve stream platformlarının transactional API'leri (ör. Kafka transactions) kombinasyonu ile kısıtlı senaryolarda uygulanabilir.
- 3. Mesajı kaç kez retry etmeliyim?
Retry stratejisi iş mantığına göre değişir: exponential backoff, jitter ve dead‑letter queue kombinasyonu yaygındır. Kritik işlemlerde retry sınırı ve inceleme süreçleri belirlenmelidir.
- 4. Replay maliyetleri nedir?
Replay storage I/O maliyeti, consumer processing time ve downstream etkileri olabilir. Reprocess öncesi canary veya staging ortamında test yapmak iyi pratiktir.
- 5. Kafka mı RabbitMQ mu?
Kullanım senaryonuza bağlı: yüksek throughput stream processing ve replay gerekiyorsa Kafka; karmaşık routing ve klasik task queue için RabbitMQ daha uygundur.
- 6. Outbox pattern nedir?
Outbox pattern, veritabanı transaction'ı içinde bir outbox tablosuna mesaj yazıp daha sonra bu outbox'u okuyup broker'a publish ederek atomic publish garantisi sağlar. Bu pattern distributed transaction ihtiyacını azaltır.
- 7. Hot partition nasıl çözülür?
Hot partition'ı çözmek için key salting, daha iyi partition key seçimi, dynamic partitioning veya hot key için dedicated topic/queue stratejileri kullanılabilir.
- 8. Managed hizmetler mi yoksa self‑hosted mi?
Managed hizmetler operasyonel yükü azaltır; ancak özellik, maliyet ve vendor lock‑in faktörleri değerlendirilmelidir. Büyük scale ve özelleştirme ihtiyacı varsa self‑hosted tercih edilebilir.
Anahtar Kavramlar
- Replay
- Stream'deki geçmiş mesajların tekrar okunup işlenmesi.
- Offset
- İçerikteki konum pointer'ı; consumer'ın pozisyonunu belirtir.
- Partition
- Verinin paralelleştirildiği segment; ordering partition içinde korunur.
- Outbox pattern
- Veritabanı transaction'ı içinde mesaj saklama ve sonra broker'a publish etme tekniği.
- Exactly‑once
- Her mesajın tam bir kez işlendiği garanti—pragmatik implementasyon karmaşıktır.
Öğrenme Yol Haritası
- 0–1 ay: Messaging temelleri: queue vs pub/sub, basit producer/consumer uygulamaları (RabbitMQ veya SQS) geliştirin.
- 1–3 ay: Kafka veya Pulsar gibi stream platformlarını kurup, partitioning, retention, consumer groups ve offset management deneyimi edinin.
- 3–6 ay: Stream processing (Kafka Streams, Flink), windowing, event time ve stateful processing üzerine projeler yapın.
- 6–12 ay: Outbox pattern, CDC pipelines, multi‑region replication ve production operational tuning konularında deneyim kazanın.