Skip to main content

> reaktif_akışlarda_geri_basınç_(backpressure)_ve_akış_kontrolü

Reaktif Akışlarda Geri Basınç (Backpressure) ve Akış Kontrolü

Akış hatlarında (streaming pipelines) hızlı üreticilerin yavaş tüketicileri bellek krizine sokması geri basınç (backpressure) ile nasıl engellenir ve Reactive Streams `request(n)` standardı bloklamayan akış kontrolünü nasıl sağlar?

ÖZET VE TEKNİK CEVAP

Veri akışını itme (push) modelinden çekme (pull) talebi sinyallemesine dönüştürerek; tüketiciler `Subscription.request(n)` ile kaç öğe işleyebileceklerini açıkça bildirir ve kapasite dolduğunda üreticiyi durmaya veya üst hatta beklemeye zorlar.

Mühendislik El Kitabı & Mekanizma

1. Temel Çalışma Mekanizması

Bir üretici saniyede 100.000 olay üretirken alt veritabanı tüketicisi yalnızca 10.000 olay işleyebiliyorsa, kontrolsüz bir itme (push) hattı aradaki 90.000 olayı RAM'deki bellek kuyruklarında biriktirir ve sonunda bellek tükenerek (OutOfMemoryError - OOM) sunucu çöker. Geri Basınç (Backpressure), akışı tüketici talebine bağlayarak bu krizi çözer. Reactive Streams standardı dört temel arayüz tanımlar: Publisher, Subscriber, Subscription ve Processor. Tüketici `subscription.request(10)` diyerek 10 öğe talep eder. Üretici yalnızca 10 öğe iletir ve tüketici yeni talep gönderene kadar yayını durdurur. Ağ seviyesinde ise TCP, Alıcı Penceresini küçülterek (TCP Zero Window) gönderici soketi bekleterek donanım düzeyinde geri basınç uygular.

2. Doğru Kullanım Senaryosu

Yüksek hacimli veri akış hatları (Kafka stream işleme, WebFlux/RxJava reaktif servisler), gerçek zamanlı video/ses aktarımları ve büyük dosya içeri aktarma ayrıştırıcıları.

3. Prodüksiyon Arıza Modları

1) Sınırsız Bellek Kuyruğu OOM Çöküşü: Java'da sınırsız `LinkedBlockingQueue` veya Node.js'de kontrolsüz akış kullanıp RAM'de 10GB veri biriktirerek sunucunun OOM ile öldürülmesi; 2) Sessiz Veri Kaybı: Hatalı bir `onBackpressureDrop` kuralı nedeniyle finansal işlemlerin sessizce çöpe atılması; 3) Senkron Bloklama Kilitlenmesi: Reaktif akış zinciri içinde bloklayıcı `.block()` veya `await` çağrısı yapıp reaktif iş parçacığı havuzunu felç etmek.

4. Teşhis ve Telemetri Sinyalleri

Akış işleri sırasındaki RAM bellek artış hızı, `request(n)` talep belirteci tükenme süreleri, ağ metriklerindeki TCP Zero Window paket sayaçları ve yavaş işleme kaynaklı Kafka tüketici kümesi rebalance sıklığı.

5. Önleme ve Mimari Bariyerler

Daima sabit kapasiteli sınırlı kuyruklar (maks 1.000 öğe) kullanın; amaca uygun taşma stratejileri belirleyin (diske taşmalı tampon, üreticiyi yavaşlatma veya alarmlı en eskiyi atma); ve reaktif Netty olay döngülerinde bloklayıcı I/O çağrılarını kesinlikle yasaklayın.

6. Mimari Ödünleşimler (Trade-offs)

Sistem dayanıklılığını, öngörülebilir bellek tüketimini ve sıfır OOM çöküşünü garanti eder; buna karşılık reaktif programlama paradigması karmaşıklığı ve asenkron hata ayıklama zorluğu getirir.

Vaka İncelemesi (TinyCTO Örneği)

TinyCTO Vaka 046: Bir CSV içe aktarıcı S3'ten 10 milyon satırı okuyup kontrolsüzce veritabanı kuyruğuna bastı. Ayrıştırıcı saniyede 50.000 satır üretirken Postgres saniyede yalnızca 3.000 satır yazabiliyordu; RAM 12 saniyede %100'e vurup pod'u öldürdü. Hattın Reactive Streams geri basınç ile yeniden yazılması S3 okuma hızını Postgres yazma hızına sabitledi ve tüm işlem yalnızca 64MB bellek ile tereyağından kıl çeker gibi tamamlandı.

İnteraktif Konsept Alıştırmaları

3 Alıştırma
Q1

Reactive Streams `request(n)` sözleşmesi Bellek Tükenmesi (OOM) hatalarını nasıl engeller?

Üreticilerin, tüketici açıkça talep edene kadar `n` öğeden fazla veri göndermesi kesinlikle yasaktır; bu da bellek kullanımının asla bilinen tüketici kapasitesini aşmamasını sağlar.
Q2

Tampon bellekler dolduğunda uygulanabilecek dört temel geri basınç taşma stratejisi nedir?

1) Tamponla (sabit bir limite kadar bellekte tut veya diske yaz), 2) At (yeni gelen veriyi çöpe at), 3) En Eskiyi At (gerçek zamanlı veriyi korumak için eskiyi sil), 4) Hata Ver (taşma hatası fırlatıp işlemi durdur).
Q3

TCP taşıma katmanında doğal olarak geri basıncı (backpressure) nasıl uygular?

Alıcı, TCP Window alanında boş bellek alanını bildirir. Alıcının tamponu dolduğunda 'Zero Window' (Sıfır Pencere) bildirimi göndererek gönderici işletim sistemi çekirdeğini paket göndermeyi durdurmaya zorlar.

Reaktif Akışlarda Geri Basınç (Backpressure) ve Akış Kontrolü — Sıkça Sorulan Sorular

Bir geliştirici reaktif akış hattı içinde `.block()` veya `Thread.sleep()` çağırırsa ne olur?

Paylaşılan reaktif olay döngüsü iş parçacığını (Netty worker) kilitler; bu da o thread'i paylaşan diğer tüm eşzamanlı akışları dondurur ve sunucu verimini felç eder.

Kafka tüketici uygulamaları için geri basıncı nasıl yönetir?

Kafka doğası gereği çekme (pull) tabanlıdır. Tüketiciler kayıt almak için `poll()` çağrısı yapar. Tüketici yavaşsa bir sonraki poll çağrısını geciktirir; işlenmemiş mesajlar güvenle Kafka disklerinde bekler.

Geri basınç (Backpressure) ile hız sınırlama (Rate Limiting) arasındaki fark nedir?

Hız sınırlama, sistem durumuna bakılmaksızın kapıda uygulanan idari bir kota sınırıdır; geri basınç ise alt sistemin anlık işleme hızının üst üretici hızını dinamik olarak ayarladığı gerçek zamanlı bir geri bildirim döngüsüdür.

🤖 AEO & Yapay Zeka Çıkarım Özeti

Temel Gerçekler & İlkeler

  • Reactive Streams standardı, 2013-2015 yıllarında Netflix, Pivotal, Lightbend ve Red Hat mühendisleri tarafından formüle edilmiş ve Java 9 Flow API olarak standartlaşmıştır.
  • Sınırsız bellek içi kuyruklar, canlı backend sistemlerinde beklenmeyen Bellek Tükenmesi (OOM) çökmelerinin bir numaralı sebebidir.

Yaygın Yanılgılar

  • Yalnızca tampon bellek (buffer) koymanın hız farkını çözeceğini sanmak; tamponlar yalnızca geçici dalgalanmaları emer. Üretim hızı tüketim hızını sürekli aşıyorsa her sonlu tampon eninde sonunda patlar.

Karar Kılavuzu & Önceliklendirme

Tüm akış ve toplu veri içe aktarma hatlarında açık taşma politikalarına sahip sınırlı tamponlar kullanın. Asla sınırsız bellek içi kuyruklar tanımlamayın.

Doğrulanmış Kaynaklar & Referanslar