Ana içeriğe geç
Blog'a Dön
Tohum (Taslak)


id: "6" title: "ETL Süreçlerinde Hata Ayıklama (Debugging) Sanatı" description: "Karmaşık veri akışlarında görünmeyen hataları ortaya çıkarmak ve boru hattını gerçekten izlenebilir bir yapıya kavuşturmak." status: 'evergreen' tags: ["ETL", "Data Engineering", "Observability", "Python"] date: "2025-10-15" readTime: "8 dk" highlight: "Sessiz veri bozulmasını durdurmanın yolu; verinin geçtiği her aşamada takip edilebilir bir iz bırakmaktan geçer."

ETL sistemleri dışarıdan bakıldığında kusursuz bir makine gibi görünür; içerideyse her adımın kendi temposuyla ilerlediği, çok fazla hareketin aynı anda yaşandığı bir dünya vardır. Günün sonunda pipeline “başarılı” olarak tamamlanır ama ortaya çıkan raporlar tutmuyorsa, işte o zaman sistemin gerçekte ne kadar karanlık çalıştığını fark edersiniz. Kod çalışır, log’lar tertemizdir ama sonuç yanlıştır. Bir veri mühendisi için bundan daha rahatsız edici az şey vardır.

Bu yüzden ETL hata ayıklama işi, çoğu zaman kod yazmaktan daha fazlasını ister. Sorun, genellikle gözünüzün önünde değildir; verinin yolculuğunu görünür hâle getirmediğiniz sürece de ortaya çıkmaz. Bu yazıda, tam da böyle bir durumda süreci nasıl aydınlattığımızı ve nerede durduğunu bilmediğimiz hataların izini nasıl sürdüğümüzü anlatıyorum.

Sessiz Hataların En Tehlikeli Yanı

Bir e-ticaret şirketinin satış raporlarında bazı günlerde toplamların %5–10 düşük geldiğini fark ettik. Ufak bir fark gibi görünse de yüksek hacimli veri akışında bu oran ciddi bir sapma anlamına gelir. Üstelik pipeline her gün sorunsuz tamamlanıyordu; tek bir exception yoktu, hiçbir uyarı yoktu. Sistem dışarıdan sağlıklı görünürken içeride açık bir kopukluk vardı.

Silent data corruption, yani “sessiz veri bozulması”, veri mühendisliğinin en zorlu problemidir. Çünkü size bir şey söylemez; sadece yanlış sonuç üretir. Bununla başa çıkabilmek için önce verinin hangi aşamalardan geçtiğini, hangi dönüşümleri yaşadığını ve ne zaman el değiştirdiğini takip edebilir olmanız gerekir.

Süreci Görünür Kılmak

Çözmeye çalıştığımız esas sorun şuydu:

“Bu veriler sistemin içinde dolaşırken neyin izini bırakıyor?”

Eğer iz yoksa, hatayı bulmak tamamen sezgilerinize kalır. Bu yaklaşım tecrübe kazandırır ama sürdürülebilir değildir. Bu yüzden ETL akışının tamamına gözlemlenebilirlik katmanı yerleştirdik.

Veri Soy Ağacı (Data Lineage) Oluşturmak

Sisteme giren her kayıt, daha ilk adımdan itibaren kendi trace_id değerini aldı. Bu kimlik, veri hangi transform’dan geçerse geçsin, birleşse de ayrışsa da yanından hiç ayrılmadı. Böylece veri artık boru hattının içinde rastgele dolaşan bir varlık olmaktan çıkıp, her adımda izi takip edilebilen bir öğeye dönüştü.

def transform_order(order_data, context):
    trace_id = context.get('trace_id')

    logger.info(
        f"Processing order {order_data['id']}",
        extra={'trace_id': trace_id}
    )
    
    if order_data['amount'] < 0:
        logger.warn(
            "Negative amount detected",
            extra={'trace_id': trace_id}
        )
        send_to_dlq(order_data, trace_id)
        return None
        
    return transformed_data

Bu küçük dokunuş, sürecin her yerine ışık düşürdü. Artık kayıp nerede olmuşsa, o kırılma noktasına kadar geri yürüyebiliyorduk.

Ara Kontrol Noktaları Koymak

Sadece izlemek yetmez; bazı hatalar içeriğe bakmadan gözden kaçar. Bu yüzden pipeline’ın belirli aşamalarına küçük kalite testleri yerleştirdik. Extract sonrası, transform’ın belirli noktaları ve load öncesi… Her durakta veri, kendi sınavından geçti.

Great Expectations burada çok iş gördü. Basit ama sağlam kurallar:

  • Tutar negatif olamaz.
  • Müşteri ID’si boş olamaz.
  • Günlük satır sayısı dünkünden makul bir sapmayla değişmeli.

Bu kontroller pipeline’ı durdurmaz; sadece uyandırır. Amacı da tam olarak budur.

Dead Letter Queue ile Hataları Ayırmak

ETL akışlarında sık yapılan hata, hatalı kayıtların tüm süreci durdurmasıdır. Böyle bir mimari, gerçek hayatta sürekli tıkanır. Bizim yaklaşımımız farklıydı:
“Problemli veriyi akışın dışına alalım, geri kalan yoluna devam etsin.”

DLQ tam olarak bu noktada devreye girdi. Gereksinimleri karşılamayan her kayıt, olduğu gibi DLQ’ya gönderildi. Veriler kaybolmadı; sadece ana akıştan ayrıldı. Gerektiğinde inceleyip düzelttikten sonra tekrar işledik.

Bu yapı üç önemli kazanım sağladı:

  1. Raporlar gecikmedi.
  2. Hatalı veriler yok olmadı.
  3. Tekrar işleme (replay) imkânı doğdu.

DLQ, ETL süreçlerinde bir tür sigorta işlevi görür; yangını büyütmeden izole eder.

Kaynağı Bulduğumuz An

Tüm bu mekanizmalar devreye girdikten sonra problem kendini gösterdi. Eski bir mobil uygulama sürümü, bazı para birimlerinde ondalık ayırıcıyı yanlış formatlıyordu. ETL bu değeri parse ederken sessizce sıfıra çeviriyordu. Teknik olarak hata yoktu; ancak iş mantığı açısından tamamen sorunluydu.

Hiçbir exception yakalayamazsınız, çünkü veri “geçersiz” değildir; “yanlıştır.”

Bu olaydan sonra çıkan sonuç çok netti:

ETL sisteminiz, verinin sana her zaman doğru formatta geleceğine inanıyorsa, bu güven bir gün mutlaka sizi yüzüstü bırakır.

Veriyi gözlemlenebilir kılmak, izini sürmek ve gerekli durumlarda savunma hattı oluşturmak; ETL süreçlerinde olgun ve sürdürülebilir bir mimarinin vazgeçilmez parçalarıdır.

Bağlantı Haritası

Mühendislik
Tarih
Anlatılar
Graph Loading...