Apache Flink ile Akış İşleme: Olay Zamanı, Pencere ve Durum
Beceri rehberi

Apache Flink ile Akış İşleme: Olay Zamanı, Pencere ve Durum

Hazırlayan: Mindset Institute EditörlüğüGüncellendi: 6 dk okuma

Flink, sürekli akan veriyi olay zamanına göre pencereleyip durum tutarak işleyen bir akış işleme motorudur. Rehber, bir akış işinin DataStream API ile nasıl kurulacağını, watermark ve gecikmiş veriyi, durum ve hata toleransını örneklerle anlatır.

Bir bakışta

  1. Akış işi, kaynak, dönüşümler ve çıkıştan oluşan bir DataStream programıdır. Veri sonsuz kabul edilir; iş durdurulana kadar yeni olayları işlemeye devam eder.
  2. Doğru sonuç için olay zamanı kullanılır. İşlem zamanı hızlıdır ama gecikme ve kesintilerde sonuç değişir; olay zamanı veriye bağlı olduğundan tutarlıdır.
  3. Watermark, olay zamanının ilerlediğini bildirir. Pencereler watermark ilerleyince kapanır; gecikmiş veri için ek süre ya da yan çıkış tanımlanır.
  4. Durum, işlemcinin olaylar arasında hatırladığı bilgidir. Anahtara göre tutulan durum, sayaç, liste ya da harita biçiminde olur ve hata sonrası geri yüklenir.
  5. Checkpoint, hata sonrası tutarlı geri dönüşü mümkün kılar. Durum ve kaynak konumu birlikte kaydedilir, böylece iş kesintisiz sürmüş gibi sonuç verir.

Flink ne işe yarar, akış işi nasıl görünür?

Toplu işleme, verinin belirli aralıklarla toplanıp bir seferde işlenmesidir. Akış işlemede ise veri geldikçe işlenir ve sonuç sürekli güncellenir. Dolandırıcılık tespiti, canlı panolar, sensör izleme ve olay tabanlı uyarılar bunun örnekleridir. Flink bu işlerde durum tutabilen, olay zamanını anlayan ve hataya dayanıklı bir motor olarak kullanılır.

Bir Flink akış işi genellikle üç parçadan oluşur: bir kaynak, bir dizi dönüşüm ve bir çıkış. Kaynak Kafka gibi bir mesaj sisteminden ya da dosyadan olayları okur. Dönüşümler olayları süzer, zenginleştirir, anahtara göre gruplar ve pencereler. Çıkış sonucu bir veritabanına, başka bir akışa ya da dosyaya yazar.

Programı DataStream API ile yazarsınız. API, her adımı bir akış üzerindeki dönüşüm olarak ifade eder ve Flink bu tanımı paralel olarak çalışan bir iş grafına çevirir. Kısa bir iskelet mantığı gösterir:

DataStream<Olay> akis = env.fromSource(kaynak, zamanStratejisi, "olaylar"); akis.keyBy(olay -> olay.kullaniciKimligi) .window(TumblingEventTimeWindows.of(pencereSuresi)) .aggregate(toplamlayici) .sinkTo(cikis);

Burada kullanıcıya göre gruplanan olaylar belirli bir süre penceresinde toplanır ve sonuç çıkışa gönderilir. Bu üç satırda akış işlemenin dört temel kavramı bulunur: anahtarlama, zaman, pencere ve toplulaştırma.

Şekil 1

Olay zamanı, gecikmelerde bile aynı sonucu verir

Zaman semantiği seçimi

İşlem zamanıOlay zamanı
Ölçüİşlemi yapan makinenin saatiOlayın kaynağında gerçekleştiği an
Sonucun kararlılığıGelişme hızı ve kesintilere göre değişirVeriye bağlıdır, tekrar çalıştırmada aynıdır
GecikmeDüşük, beklemek gerekmezGeç gelen veri için beklemek gerekir
Gerekli mekanizmaYokWatermark ve zaman damgası
Tipik kullanımBasit, hız öncelikli izlemeDoğruluk gerektiren raporlama ve analiz
Kaynak: Apache Flink dokümantasyonu: Timely Stream ProcessingMindset Institute

Olay zamanı, watermark ve gecikmiş veri

Gerçek dünyada olaylar sıra dışı ve geç gelir: mobil cihaz bağlantısı kesilir, ağ gecikir, bir kaynak diğerinden yavaştır. İşlem zamanıyla çalışırsanız, aynı veriyi farklı hızda gönderdiğinizde farklı sonuç alırsınız. Olay zamanı bu sorunu çözer; her olayın taşıdığı zaman damgasına göre işlem yapılır.

Ancak sistem bir pencerenin ne zaman kapanacağını nasıl bilir? Cevap watermark'tır. Watermark, belirli bir zamana kadarki olayların geldiğini beyan eden ilerleme işaretidir ve akışla birlikte akar. Bir operatör watermark aldığında olay zamanı saatini ilerletir ve o zamana kadar olan pencereleri sonlandırır. Birden çok girdisi olan operatör, girdilerin en küçük watermark değerini esas alır; yani en geride kalan kaynak ilerlemeyi belirler.

Watermark'ı üretmek için bir WatermarkStrategy tanımlanır. En yaygın yaklaşım, sıra dışılık için bir sınır belirleyen forBoundedOutOfOrderness stratejisidir; olay zaman damgası withTimestampAssigner ile çıkarılır. Strateji doğrudan kaynağa verilebilir ve bu önerilen yoldur, çünkü kaynak bölüm bilgisinden yararlanır.

Sessiz kalan bir kaynak tüm watermark'ı geride tutabilir. withIdleness bir girdiyi belirli süre sessiz kalırsa boşta sayar ve diğer girdilerin ilerlemesini bloke etmemesini sağlar.

Watermark'tan sonra gelen olaylar gecikmiş sayılır. Pencerelerde bunlar için allowedLateness ile ek süre verilebilir; bu durumda pencere açık kalır ve gecikmiş olay gelirse sonuç güncellenir. Varsayılan ek süre sıfırdır ve gecikmiş olaylar atılır. sideOutputLateData ise gecikmiş olayları kaybetmek yerine ayrı bir yan akışa yönlendirir; böylece sonradan incelenebilir.

Pencereleme: akışı sınırlı parçalara bölmek

Sonsuz bir akış üzerinde toplam ya da ortalama hesaplamak için akış sınırlı parçalara bölünür. Flink'te bu parçalara pencere denir ve dört temel tür vardır.

  • Sabit (tumbling) pencere: Sabit uzunlukta, çakışmayan aralıklar. Her olay yalnızca bir pencereye girer. Dakikalık toplam gibi raporlar için uygundur.
  • Kayan (sliding) pencere: Sabit uzunlukta ama belirli bir kayma aralığıyla başlayan pencereler; birbiriyle çakışır. Hareketli ortalama gibi hesaplar için kullanılır.
  • Oturum (session) penceresi: Etkinlik boşluğuna göre oluşur; belirli bir süre olay gelmezse oturum kapanır. Kullanıcı oturumları için idealdir.
  • Genel (global) pencere: Aynı anahtarı taşıyan tüm olayları tek pencerede toplar ve çalışması için özel bir tetikleyici gerektirir.

Anahtarlı akışta window ile, anahtarsız akışta windowAll ile pencere tanımlanır. windowAll tüm işi tek göreve toplar, bu da paralelliği bire indirir; büyük veride darboğaz olur. Bu yüzden mümkünse önce keyBy ile akışı bölmek gerekir.

Pencere içindeki hesap için üç işlev ailesi vardır. ReduceFunction ve AggregateFunction olayları geldikçe birleştirir; bellek kullanımı düşük kalır. ProcessWindowFunction ise pencerenin tüm olaylarını ve üst bilgisini alır; esnektir ama daha pahalıdır. İkisini birleştirmek mümkündür: önce artımlı toplulaştırma, sonra pencere bilgisiyle zenginleştirme.

Seçimi hesap belirler: basit toplam ve sayaç için artımlı işlev, pencere sınırlarını rapora yazmak gibi ihtiyaçlar için process işlevi tercih edilir.

Durum yönetimi

Pencereleme de durum kullanır, ancak birçok iş penceresiz bir hafıza gerektirir: son görülen değer, toplam sayaç, kullanıcı başına bir liste. Flink bu hafızayı durum olarak yönetir ve anahtarlı akışta her anahtar için ayrı tutar.

Anahtarlı durumun türleri bellidir. ValueState anahtar başına tek bir değer tutar. ListState bir liste tutar. MapState anahtar-değer eşlemesi tutar. ReducingState ve AggregatingState ise eklenen her öğeyi bir işlevle tek bir değerde birleştirir. Her durum bir tanımlayıcıyla adlandırılır ve işlevin açılış aşamasında çalışma bağlamından alınır; bu, yalnızca zengin işlevlerde mümkündür.

Durumun sonsuza kadar büyümemesi için süre sınırı tanımlanır. StateTtlConfig ile durum girdisine yaşam süresi verilir; ne zaman yenileneceği ve süresi dolmuş değerin görünüp görünmeyeceği ayarlanır. Bunu yapmayan işler, kullanıcı ya da cihaz sayısı arttıkça belleği doldurur. Süre kısıtının yalnızca işlem zamanını desteklediği not edilmelidir.

Durum aynı zamanda sonuçların tutarlılığını sağlar. Hata olursa Flink, durumu en son tutarlı noktadan geri yükler ve kaynağı da o noktaya sarar; bu mekanizmanın adı checkpoint'tir ve bir sonraki bölümün konusudur.

Hata toleransı ve checkpoint

Uzun süre çalışan bir akış işi bir gün mutlaka hata ile karşılaşır: bir makine düşer, ağ kopar, bir görev çöker. Flink checkpoint mekanizmasıyla bu durumu yönetir. Checkpoint, operatörlerin durumunun ve kaynak konumunun tutarlı bir anlık görüntüsüdür. Hata sonrası iş son checkpoint'ten geri yüklenir, kaynak o konumdan yeniden okur ve sonuçlar hatasız çalışmış gibi oluşur.

Checkpoint varsayılan olarak kapalıdır. enableCheckpointing çağrısı ile bir aralıkla açılır. Garanti seviyesi seçilebilir: tam bir kez (exactly-once) varsayılandır ve çoğu iş için tercih edilir; en az bir kez (at-least-once) ise tutarlı olarak çok düşük gecikme gerektiren işler için bir seçenektir. Geri yükleme için kaynağın yeniden okunabilir olması, durumun da kalıcı bir depoda saklanması gerekir; bu yüzden üretimde dayanıklı bir dosya sistemi önerilir.

Checkpoint sıklığı bir dengedir. Sık alınan checkpoint, kurtarma sonrası yeniden işlenecek veriyi azaltır ama çalışma sırasında ek yük getirir. Seyrek alınanlarda ise tersi geçerlidir. Aralık, kabul edilebilir kurtarma süresi ve durum büyüklüğüne göre seçilir.

Çıkış tarafı da tutarlılığı etkiler. Tam bir kez sonuç, yalnızca Flink'in kendi içinde değil, yazılan sistemin bunu desteklemesine de bağlıdır. Çıkış idempotent ise yeniden yazma sorun çıkarmaz.

Şekil 2

Akış işi kaynaktan çıkışa belirli bir sırayla ilerler

Tipik bir Flink hattı

  1. Kaynağı okuOlaylar zaman stratejisiyle okunur.
  2. AnahtarlakeyBy ile akış anahtara göre bölünür.
  3. PencereleOlay zamanına göre pencere atanır.
  4. Durumu güncelleToplam ve sayaçlar anahtarlı durumda tutulur.
  5. Çıkışa yazSonuç hedef sisteme yazılır, checkpoint ile korunur.
Kaynak: sayfa içeriğiMindset Institute

Sık hatalar ve öğrenme yolu

Akış işlemede sık görülen hatalar şunlardır: tüm olay türleri için tek bir zaman davranışı varsaymak, watermark sınırını rastgele seçmek, gecikmiş olayları sessizce atmak, durumu sınırsız büyütmek, windowAll ile paralelliği kaybetmek, çıkışın tekrar yazmaya dayanıklı olup olmadığını düşünmemek.

Öğrenme yolu şöyle ilerler. Önce basit bir kaynak ve süzgeçle akışın mantığı kavranır. Sonra anahtarlama ve pencereli toplulaştırma yapılır. Ardından olay zamanı ve watermark kurulur, gecikmiş veri için yan çıkış denenir. Sonra anahtarlı durum ve süre sınırı eklenir. En son checkpoint, kurtarma testi ve izleme gelir.

Her aşamada küçük bir sorun çözülür. Örneğin kullanıcı başına belirli bir süre içindeki tıklama sayısını hesaplayan, gecikmiş olayı yan akışa gönderen ve hata sonrası aynı sonucu veren bir iş, ana kavramların hepsini bir arada sınar.

Flink SQL ve Table API, aynı motoru bildirimsel biçimde kullanma imkânı sunar. Basit toplulaştırmalar için SQL hızlı bir yoldur; ayrıntılı durum ve zaman kontrolü gerektiğinde DataStream API'ye dönülür.

Bu beceriyi Mindset programında nerede çalışırsınız?

Apache Flink ile Gerçek Zamanlı Akış İşleme programı; Flink mimarisi ve çalışma modeli, DataStream API ile dönüşümler, zaman semantiği ve pencereleme, durum yönetimi ve hata toleransı, Flink SQL ve Table API ile performans, izleme ve bitirme projesi başlıklarını içerir. Gerçek zamanlı veri hatları kurmak isteyen veri mühendisleri ve yazılım geliştiriciler için tasarlanmıştır.

İlgili Mindset programı

Apache Flink ile Gerçek Zamanlı Akış İşleme

Sık sorulanlar

Sık sorulan sorular

Flink ile Spark Structured Streaming arasındaki fark nedir?

Her ikisi de akış verisini işleyebilen motorlardır. Flink'te olay zamanı, durum ve hata toleransı DataStream API'nin merkezindedir. Seçim; gecikme beklentisine, durum karmaşıklığına ve ekibin mevcut ekosistemine göre yapılır.

Watermark sınırını nasıl seçerim?

Sınır, verinizin sıra dışılık davranışına bağlıdır. Çok küçük seçilirse gecikmiş olaylar atılır, çok büyük seçilirse sonuçlar geç çıkar. Gerçek verinin gecikme dağılımını ölçüp makul bir sınır belirleyin, aşırı gecikenler için allowedLateness ve yan çıkış kullanın. Sınırı daha sonra gözlemleyerek ayarlayın.

Hangi pencere türünü seçmeliyim?

Sabit aralıklı raporlar için sabit pencere, hareketli ortalama gibi çakışan hesaplar için kayan pencere, kullanıcı etkinliği oturumları için oturum penceresi kullanılır. Genel pencere yalnızca özel tetikleyiciyle çalışır. Seçimi, sonucun ne zaman ve hangi aralıkta üretilmesini istediğiniz belirler.

Durum büyüyünce ne yapılır?

Önce durumun gerçekten gerekli olup olmadığına bakılır. Sonra süre sınırı tanımlanır ki eskiyen girdiler temizlensin. Büyüme sürerse durum arka ucu ve bellek ayarları gözden geçirilir. Anahtar sayısının sınırsız artması bir tasarım sorunudur; anahtar tasarımı yeniden düşünülmelidir.

Flink SQL mi DataStream API mi?

Basit süzme, birleştirme ve pencereli toplulaştırma için SQL daha hızlı ve okunurdur. Özel durum yönetimi, zamanlayıcılar ve ince zaman kontrolü gerektiğinde DataStream API gerekir. Pratikte ikisi birlikte kullanılabilir; ekip ihtiyaca göre uygun olanı seçer.

Apache Flink ile Gerçek Zamanlı Akış İşleme