System Design

Ölçek için Güçsüz (Idempotent) ETL Boru Hatları Tasarlama

Petabayt ölçeğinde veri boru hatları yalnızca aktarım hızıyla ilgili değildir; hayatta kalmayla ilgilidir. Dağıtık sistemlerde arızalar istisna değil; normdur. Ağ bölünmeleri, düğüm arızaları ve kaynak tükenmesi kaçınılmazdır. ETL boru hattınız her iş çalıştırmasının benzersiz ve durumdan bağımsız olduğunu varsayarsa, sonunda mükerrerler, veri kaybı veya tutarsız durumlar üreten bir sistem inşa etmiş olursunuz. Hata toleranslı toplu işlemenin amacı, bireysel adımların kaç kez yeniden denendiğinden bağımsız olarak verilerin son durumunun doğru olmasını sağlamaktır.

Idempotency'nin (Güçsüzlüğün) Gerekliliği

Idempotency, güvenilir toplu işlemenin temel taşıdır. Bir işlem, birden fazla kez uygulandığında tek seferlik uygulamayla aynı etkiye sahipse idempotenttir. ETL bağlamında bu, belirli bir veri bölümü işlendiğinde, başarısız olduğunda ve yeniden denendiğinde, sonucun tek başarılı çalıştırma ile aynı olması gerektiği anlamına gelir.

Idempotency olmadan, basit bir ağ zaman aşımı, çift sayılan finansal işlemlere veya mükerrer müşteri kayıtlarına yol açabilir. Bunu başarmak için, benzersiz anahtarlara dayalı deterministik "upsert" veya "replace" (değiştir) anlambilimine doğru, basit "insert" (ekle) işlemlerinden uzaklaşırız.

Checkpointing Stratejileri

Idempotency "neyi" ele alırken, checkpointing "nerede"yi ele alır. Checkpointing, uzun süreli bir işin baştan başlatmadan belirli bir zaman noktasından duraklatıp devam etmesine olanak tanır. Petabayt ölçeğinde sistemlerde tüm veri kümelerini yeniden işlemek maliyet açısından kabul edilemezdir.

Etkili checkpointing, tamamlanan görevler hakkında meta verileri kalıcı hale getirmeyi gerektirir. Bu meta veriler genellikle yüksek kullanılabilirliğe ve düşük gecikmeye sahip bir anahtar-değer deposunda veya ACID işlemlerini destekleyen bir veritabanında saklanır. Boru hattı, bu checkpoint deposunu ilerleme için doğru kaynağı olarak ele almalıdır.

Uygulama Desenleri

Aşağıda, Python'da idempotent ve checkpoint'li bir işleme adımının basitleştirilmiş bir deseni yer almaktadır. Bu işlev, görev yeniden denendiğinde, verilerin zaten taahhüt edilip edilmediğini önce kontrol etmesini sağlar.

import hashlib
from sqlalchemy import create_engine, text

engine = create_engine("postgresql://user:pass@host:5432/db")

def process_batch(batch_id: str, data_payload: bytes) -> bool:
    """
    Bir veri partisini idempotent olarak işler.
    İşlenmişse True, zaten yapılmışsa False döner.
    """
    # Partinin deterministik bir parmak izini üret
    content_hash = hashlib.sha256(data_payload).hexdigest()
    
    with engine.begin() as conn:
        # Bu belirli batch_id + hash'in zaten işlenip işlenmediğini kontrol et
        check_query = text("SELECT 1 FROM checkpoints WHERE batch_id = :id AND hash = :hash")
        existing = conn.execute(check_query, {"id": batch_id, "hash": content_hash}).first()
        
        if existing:
            # Idempotency koruması: Zaten başarılıysa hiçbir şey yapma
            print(f"Batch {batch_id} zaten işlendi. Atlanıyor.")
            return False
        
        # Gerçek ETL mantığını gerçekleştir (burada basitleştirildi)
        # Üretimde, bu hedef göl/ambarına yazmayı içerir
        execute_etl_logic(data_payload)
        
        # Checkpoint'i yalnızca başarılı ETL'den sonra taahhüt et
        insert_query = text("INSERT INTO checkpoints (batch_id, hash) VALUES (:id, :hash)")
        conn.execute(insert_query, {"id": batch_id, "hash": content_hash})
        
    return True

Kısmi Arızaların Yönetimi

Dağıtık mimarilerde kısmi arızalar yaygındır. Bir shard başarılı olurken diğeri başarısız olabilir. Bunu ele almak için, boru hatları ince taneli bir granülerlik ile tasarlanmalıdır. "A Tablosu"nu işlemek yerine, "A Tablosu, 2023-10-01 Bölümü"nü işleyin. Bu, zamanlayıcının yalnızca başarısız olan bölümü yeniden denemesine ve idempotency'den yararlanarak verilerin geri kalanının dokunulmamış kalmasını sağlamasına olanak tanır.

Sonuç

Hata toleranslı sistemler tasarlamak, "bunu nasıl çalıştırırım?" zihniyetinden "başarısız olduğumda nasıl hayatta kalırım?" zihniyetine bir geçiş gerektirir. Katı idempotency garantilerini ince taneli checkpointing ile birleştirerek, yalnızca dayanıklı değil, aynı zamanda kendini iyileştirici boru hatları inşa edersiniz. Bu yaklaşım, manuel müdahalenin maliyetinin uygulanabilir bir kurtarma stratejisi olarak çok yüksek olduğu petabayt ölçeğinde veri bütünlüğünü sağlar.

Share: