- İdempotent pipeline ne demek, neden gerekir?
- Tasarımın temeli: çalışma zamanını değil veri aralığını girdi yapmak
- Yazma stratejisi: üzerine yaz, birleştir ya da yalnız ekle
- Doğal anahtar ve kopya savunması
- Yan etkili adımlar ve dış sistemler
- Backfill ve yeniden çalıştırma pratiği
- Tasarımın doğrulanması: testler ve gözlem
- Mindset programlarında bu beceri nerede çalışılır?
- Sık sorulan sorular
Tekrar Çalıştırılabilir Veri Pipeline'ı Tasarlama Rehberi
Veri pipeline'ı kopya ve eksik satır üretmeden tekrar çalıştırmak için partition bazlı yazma, MERGE, doğal anahtar ve backfill yöntemleri.
İdempotent pipeline ne demek, neden gerekir?
Bir pipeline'ın idempotent olması, aynı girdiyle kaç kez çalıştırılırsa çalıştırılsın hedef tabloda aynı sonucu bırakması demektir. İlk çalıştırmada yüklenen günün verisi, aynı gün için yeniden tetiklenince çoğalmaz, bozulmaz, eksilmez. Bu özellik lüks değil, zorunluluktur; çünkü gerçek hayatta görevler yarıda kesilir, ağ koparır, zamanlayıcı aynı işi yinelenen biçimde başlatır, kaynak sistem geç veri gönderir ve ekip geçmiş günleri yeniden yüklemek ister.
İdempotent olmayan bir pipeline'da her hata bir operasyon sorununa dönüşür: yarım kalan yükleme sonrası tablo elle temizlenir, hangi satırın kopya olduğu araştırılır, raporlar yanlış toplam gösterir. İdempotent tasarımda ise çözüm tek cümledir: görevi yeniden çalıştır. Bu yüzden tasarım kararlarının çoğu şu soruya iner: bu görev yarın bir daha çalışsa hedefte ne değişir?
Burada şu kavramları ayırmak gerekir. Tekrar çalıştırılabilirlik görevin kendisiyle ilgilidir. Veri tutarlılığı ise kaynağın ve hedefin birlikte davranışıyla ilgilidir. Pipeline'ı idempotent yapmak ikincisini otomatik çözmez, ama tutarlılık sorunlarını yeniden çalıştırarak düzeltilebilir hale getirir. Burada konu API çağrıları değil, toplu veri yüklemedir.
Tasarımın temeli: çalışma zamanını değil veri aralığını girdi yapmak
İdempotent tasarımın en sık ihlal edilen kuralı, görevin "şu an" saatini kullanmasıdır. Sorgu içinde güncel zamanı çağıran bir görev, dün çalışınca bir sonuç, bugün yeniden çalışınca başka bir sonuç üretir. Doğru yaklaşım, her çalıştırmaya işlenecek veri aralığını dışarıdan parametre olarak vermektir. Airflow'da bunun karşılığı mantıksal tarih ve veri aralığı değişkenleridir: resmî şablon başvurusunda ds değişkeni DAG çalışmasının mantıksal tarihini YYYY-AA-GG biçiminde verir, data_interval_start ve data_interval_end ise aralığın başını ve sonunu taşır.
Örneğin bir görev şu sorguyu parametreli çalıştırır:
SELECT * FROM siparisler WHERE olusturma_tarihi >= '{{ data_interval_start }}' AND olusturma_tarihi < '{{ data_interval_end }}'
Aynı mantıksal tarih için görev yeniden tetiklendiğinde sorgu birebir aynı aralığı okur. Aralığın başı dahil, sonu hariç tutulur; böylece gece yarısına denk gelen satır ya tekrar tekrar ya hiç okunmaz sorunu doğmaz. Aralık sınırlarını tek bir yerde tanımlamak ve tüm görevlerin aynı tanımı kullanmasını sağlamak, ilerideki hataların büyük bölümünü önler.
Yazma stratejisi: üzerine yaz, birleştir ya da yalnız ekle
Hedefe yazma biçimi idempotency'nin gerçek sınandığı yerdir. Yaygın stratejiler şunlardır ve hangisinin seçileceği verinin doğasına bağlıdır.
- Partition üzerine yazma: Hedef tablo tarihe göre bölümlenmişse, görev yalnız kendi aralığına ait bölümü silip yeniden yazar ya da bölümü atomik olarak değiştirir. Olay ve log verisi gibi değişmeyen kayıtlar için en sade yöntemdir. Yeniden çalıştırma, bölümü aynı içerikle yeniden kurar.
- Birleştirme (MERGE ya da upsert): Kayıtlar sonradan güncellenebiliyorsa, doğal anahtara göre eşleşen satır güncellenir, eşleşmeyen eklenir. PostgreSQL'de bu INSERT ... ON CONFLICT DO UPDATE ile, birçok ambar ürününde MERGE ifadesiyle yapılır. Anahtar kararlı ve benzersiz olmalıdır; yoksa birleştirme sessizce kopya üretir.
- Yalnız ekleme (append): Her çalıştırma sona satır ekler. Tek başına idempotent değildir. Kullanılacaksa girdi, yinelenen kayıtları ayıklayan bir sonraki katmanla ya da çalıştırma kimliğine göre silip yeniden yazan bir adımla birlikte tasarlanmalıdır.
Silme ve ekleme adımları aynı işlemde (transaction) yapılmalıdır. Silme başarılı olup ekleme çökerse bölüm boş kalır; yeniden çalıştırma bunu düzeltir ama arada okuyan rapor eksik veri görür. Hedef sistem atomik bölüm değişimi sunuyorsa önce geçici tabloya yazıp sonra değiştirmek daha güvenlidir.
Doğal anahtar ve kopya savunması
Birleştirme tabanlı yüklemede her şey anahtara bağlıdır. Rastgele üretilen kimlik (örneğin yükleme sırasında atanan otomatik sayı) doğal anahtar değildir; aynı kaynak satır her yüklemede farklı kimlik alırsa yeniden çalıştırma kopya yaratır. Anahtarı kaynağın kendisinden türetin: sipariş numarası, olay kimliği ya da gerekiyorsa birkaç alanın birleşimi. Anahtar kaynakta güvenilir değilse alanların özetinden (hash) bir kimlik üretmek kabul edilebilir bir çözümdür.
Hedef tabloda anahtar üzerine benzersizlik kısıtı koymak, tasarımın ucuz ama etkili bir güvenlik ağıdır. Kısıt, yanlış yazılmış bir yükleme mantığını sessiz veri bozulması yerine yüksek sesli bir hataya çevirir. Ambar ürünlerinde kısıt zorlanmıyorsa aynı etkiyi kopya sayan bir kalite testiyle alın ve test başarısız olduğunda pipeline'ı durdurun.
Kaynakta silinen kayıtlar ayrı bir konudur. Yalnız yeni ve güncel satırları taşıyan bir pipeline silinmeyi göremez. Kaynak yumuşak silme (silindi bayrağı) sunuyorsa bayrağı da taşıyın; sunmuyorsa tam anlık görüntü karşılaştırması ya da değişiklik yakalama (CDC) gerekir.
Yan etkili adımlar ve dış sistemler
Yalnız tabloya yazan görevler idempotent yapılabilir; asıl zorluk dış dünyaya dokunan adımlardadır. E-posta göndermek, ödeme tetiklemek, başka bir sisteme API çağrısı yapmak yeniden çalıştırmada tekrar gerçekleşir. Bunun için şu yaklaşımlar kullanılır: işlemi hedef sistemde idempotency anahtarıyla işaretlemek ya da gönderilmiş işlemlerin kaydını tutup yalnız gönderilmemişleri işlemek. Kayıt tablosu da aynı işlemde güncellenmelidir.
Dosya tabanlı akışlarda çıktı dosyasının adı çalışma aralığından türetilmelidir. Rastgele ya da zaman damgalı bir ad, yeniden çalıştırmada fazladan bir dosya bırakır ve alt akış hepsini birden okur. Aralığa bağlı sabit ad, yeniden çalıştırmanın dosyanın üzerine yazmasını sağlar. Ara katmanlarda (staging) de aynı kural geçerlidir: çalışmanın ürettiği geçici tablo çalışmanın başında temizlenmeli, sonunda ya da hata durumunda artık bırakmamalıdır.
Backfill ve yeniden çalıştırma pratiği
İdempotent tasarımın karşılığını backfill sırasında alırsınız. Bir kaynak hatası düzeltildiğinde ya da yeni bir sütun eklendiğinde geçmiş aralıkları yeniden işlemek gerekir. Airflow gibi bir orkestratörde bu, geçmiş tarih aralığı için görevlerin temizlenip yeniden tetiklenmesidir. Görevler idempotent ise bu işlem rutindir; değilse her backfill bir kriz toplantısına dönüşür.
Güvenli bir yeniden çalıştırma sırası şöyledir: önce sorunlu aralığı ve etkilenen tabloları belirleyin. Sonra aralığı küçük bir örnekte deneyin ve satır sayısı ile toplam tutarı çalıştırma öncesi ve sonrası karşılaştırın. Ardından aralığı tam çalıştırın. Son olarak kalite testlerini koşturun. Alt akış raporlarının yeniden hesaplanması gerekiyorsa bunu da aynı mantıkla tetikleyin.
Sık yapılan hatalar şunlardır: görevin içinde güncel zamanı kullanmak, sonuç tablosuna yalnız ekleme yapıp sonra kopya temizlemeyi unutmak, silme ile yazmayı ayrı işlemlere bölmek, bölüm sınırını saat dilimi farkını düşünmeden belirlemek ve ara tabloyu çalışmalar arasında paylaşmak. Saat dilimi için tek kural koyun: depolama ve aralık hesabı tek bir saat diliminde (çoğunlukla UTC) yapılır, gösterim katmanı dönüştürür.
Tasarımın doğrulanması: testler ve gözlem
Bir pipeline'ın idempotent olduğunu varsaymayın, sınayın. En ucuz test şudur: aynı aralığı art arda çalıştırın ve hedefin özetini (satır sayısı, anahtar sayısı, tutarların toplamı) karşılaştırın; sonuçlar aynı olmalıdır. Bu testi otomatikleştirip geliştirme ortamında her değişiklikte koşturabilirsiniz. Ek olarak çalıştırmanın ortasında görevi öldürüp yeniden başlatmak, atomiklik varsayımlarını ortaya çıkarır.
Üretimde gözlem aynı derecede önemlidir. Her çalıştırmanın okuduğu ve yazdığı satır sayısını kaydedin; aynı aralığın çalıştırmaları arasında beklenmedik fark varsa uyarı üretin. Kopya sayan ve tazelik kontrol eden kalite testleri pipeline'ın parçası olmalıdır. Bu yaklaşım veri kalitesi ve gözlemlenebilirlik çalışmasıyla doğrudan kesişir.
Mindset programlarında bu beceri nerede çalışılır?
Bu beceri veri mühendisleri ve analitik mühendisleri için çekirdek yetkinliktir; ekibinde yükleme hatalarıyla boğuşan veri ekipleri ya da raporların tutarsızlığından şikâyet eden iş birimleri için de doğrudan karşılık bulur. Mindset kataloğunda Veri Mühendisliği Temelleri programının Veri Pipeline Tasarımı, Veri Kalitesi ve Gözlemlenebilirlik modülleri bu çerçeveyi kurar. Airflow ile Veri Pipeline'ları programında ise Zamanlama, Bağımlılık ve Tetikleyiciler ile DAG Tasarımı modülleri, mantıksal tarih parametreleriyle çalışan görevlerin pratiğine dayanır. Kurumsal ekipler, kendi pipeline'larından seçilen bir yükleme akışını atölye materyali olarak getirip idempotent hale çevirebilir.
İlgili Mindset programı
Veri Mühendisliği Temelleri
Sık sorulan sorular
Idempotent ile atomik işlem aynı şey mi?
Hayır. Atomiklik, bir işlemin ya tamamen gerçekleşmesi ya da hiç gerçekleşmemesidir. İdempotency ise aynı işlemin tekrarının sonucu değiştirmemesidir. Birbirini tamamlarlar: silme ve ekleme adımlarını aynı işlemde yapmak atomikliği sağlar, bölüm aralığına bağlı yazma da yeniden çalıştırmayı güvenli kılar. İdempotent bir görev atomik değilse yarım kalan çalışma arada eksik veri gösterebilir.
Her pipeline'ı idempotent yapmak zorunda mıyım?
Pratikte evet, özellikle üretimdeki ve zamanlanmış pipeline'larda. Tek seferlik, çıktısı atılabilir bir aktarım için bu çaba gereksiz olabilir. Ancak bugün tek seferlik görünen iş, yarın zamanlanıp tekrar eden işe dönüşür. Başlangıçtan idempotent yazmak, sonradan düzeltmeye göre daha ucuzdur ve operasyon yükünü belirgin biçimde azaltır.
Kaynak veri geç gelirse idempotent yapı bunu çözer mi?
Kısmen. Geç gelen kayıtları yakalamak için görevin okuma aralığını geriye doğru genişletmek ya da düzenli aralıklarla geçmiş bölümleri yeniden işlemek gerekir. Görev idempotent olduğu için aynı bölümün tekrar işlenmesi zararsızdır. Önemli olan, olay zamanı ile yükleme zamanını ayrı alanlarda tutmak ve hangi gecikmeye tolerans gösterdiğinizi açıkça belirlemektir.
Silme ve yeniden yazma yerine MERGE mi kullanmalıyım?
Veri değişmeyen olay kayıtlarından oluşuyorsa bölümü silip yeniden yazmak daha basit ve hızlıdır. Kayıtlar sonradan güncelleniyorsa ve bölüm sınırı belirsizse MERGE ya da upsert uygundur. MERGE güvenilir bir doğal anahtar ister. Anahtarınız yoksa önce anahtar tanımlamaya, ardından yazma stratejisini seçmeye başlayın.
Orkestratör olmadan da idempotent pipeline kurulur mu?
Evet. İdempotency bir araç özelliği değil tasarım ilkesidir. Basit bir zamanlanmış betik de aralığı parametre alıp bölümü yeniden yazarak idempotent olabilir. Orkestratör, mantıksal tarih parametresi, yeniden deneme ve backfill gibi yetenekleri hazır sunduğu için süreci kolaylaştırır; ama doğru yazma stratejisini sizin seçmeniz gerekir.