Skip to main content

> transactional_outbox_deseni_ve_debezium_cdc_olay_i̇letim_garantileri

Transactional Outbox Deseni ve Debezium CDC Olay İletim Garantileri

Aynı uygulama kodunda hem veritabanına yazıp hem de Kafka'ya mesaj göndermek neden sessiz çift yazma tutarsızlığına yol açar ve Transactional Outbox deseni En-Az-Bir-Kez (At-Least-Once) iletimi nasıl garanti eder?

Senior (L5)

ÖZET VE TEKNİK CEVAP

Olay güdümlü mimarilerde en tehlikeli tuzak, aynı fonksiyon içinde hem veritabanına yazıp hem de Kafka'ya mesaj atmaktır (`db.kaydet(siparis); kafka.gonder(siparisOlustu);`). Burada atomik hiçbir garanti yoktur: Veritabanı işlemi commit edilip hemen ardından sunucu çökerse veya Kafka zaman aşımına uğrarsa, Kafka olayı asla alamaz (sessiz veri kaybı); tersine Kafka'ya mesaj gidip veritabanı rollback olursa, diğer servisler aslında hiç var olmayan hayalet bir siparişi işler. Transactional Outbox Deseni bunu çözer: Ana veri ve fırlatılacak olay, AYNI yerel ACID veritabanı işlemi içinde bir `outbox` tablosuna yazılır. Debezium gibi bir Değişiklik Verisi Yakalama (CDC) motoru veritabanının transaction logunu (Postgres WAL) okuyarak bu olayları Kafka'ya En-Az-Bir-Kez (At-Least-Once) garantisiyle kesin olarak iletir.

Mühendislik El Kitabı & Mekanizma

1. Temel Çalışma Mekanizması

Debezium ile Transactional Outbox 4 aşamada çalışır: (1) Tek Yerel ACID İşlemi: Uygulama `BEGIN; INSERT INTO orders (...); INSERT INTO outbox_events (...); COMMIT;` çalıştırır. (2) Log Dinleme (WAL Tailing): Debezium veritabanına tabloları kilitlemeden mantıksal çözme (`pgoutput`) ile bağlanır ve doğrudan Write-Ahead Log'dan (WAL) sadece commit edilmiş değişiklikleri okur. (3) Kafka Yayını: Debezium olayları ilgili Kafka topic'lerine basar ve ancak Kafka diske yazdığında kendi CDC offset'ini ilerletir. (4) Outbox Temizliği: İşlenen outbox satırları arka planda periyodik olarak silinerek tablonun şişmesi engellenir.

2. Doğru Kullanım Senaryosu

Olay güdümlü mikroservisler, sipariş işleme boru hatları, asenkron bildirim dağıtımı ve arama motoru (Elasticsearch) veri senkronizasyonu.

3. Prodüksiyon Arıza Modları

CDC kullanmak yerine outbox tablosuna her 500 ms'de bir `SELECT * FROM outbox WHERE processed = false` sorgusu atıp veritabanını kilitlemek; PostgreSQL'de Debezium replikasyon slotunun takılması sonucu WAL dosyalarının birikerek diski %100 doldurması.

4. Teşhis ve Telemetri Sinyalleri

Müşteri siparişlerinin %0,1'inde alt servislerin olayları kaçırması; PostgreSQL'de `pg_wal` dizininde biriken dosyalar yüzünden diskin dolması; Datadog'da Debezium gecikme metriğinin (`MillisecondBehindSource`) sürekli artması.

5. Önleme ve Mimari Bariyerler

Olayları dinamik topic'lere yönlendirmek için Debezium Outbox Event Router kullanın; replikasyon slotunun diski doldurmasını önlemek için PostgreSQL'de `max_slot_wal_keep_size` sınırı koyun; tüketici (consumer) tarafında mükerrer mesajlara karşı kesin idempotency kalkanları kurun.

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

Transactional Outbox, Kafka Connect / Debezium altyapısı işletmeyi ve tüketicilerde mükerrer mesaj kontrolü yapmayı gerektirir; ancak çift yazmadan kaynaklanan sessiz veri kaybı felaketini kökten çözer.

Vaka İncelemesi (TinyCTO Örneği)

Bir ödeme ağ geçidinde her 2.000 işlemden birinde para çekilmesine rağmen anlık ağ kopması yüzünden RabbitMQ'ya mesaj gidemiyor ve müşteriye onay e-postası ulaşmıyordu. Ekip PostgreSQL WAL logunu dinleyen Debezium ile Transactional Outbox desenine geçti. 12 ayda gerçekleşen 40 milyon işlemde kaybolan olay sayısı tam olarak sıfıra indi ve sistem 15 milisaniyenin altında olay iletim gecikmesiyle çalıştı.

İnteraktif Konsept Alıştırmaları

2 Alıştırma
Q1

Dağıtık sistemlerde Çift Yazma (Dual-Write) problemi nedir?

Dağıtık işlem (2PC) olmadan yerel bir veritabanına yazıp harici bir mesaj kuyruğuna yayın yapmanın atomik olamaması; bu durumun sessiz veri kaybına veya hayalet olaylara yol açmasıdır.
Q2

Debezium veritabanı sorgu performansını düşürmeden outbox olaylarını nasıl okur?

Veritabanına sürekli `SELECT` sorguları atmak yerine, mantıksal kopyalama ile doğrudan Write-Ahead Log (WAL / Binlog) dosyasını okuyarak.

Transactional Outbox Deseni ve Debezium CDC Olay İletim Garantileri — Sıkça Sorulan Sorular

Debezium neden Tam-Olarak-Bir-Kez (Exactly-Once) yerine En-Az-Bir-Kez (At-Least-Once) iletim garantisi verir?

Debezium olayları Kafka'ya yazıp offset'ini veritabanına kaydedemeden çökerse, yeniden başladığında aynı olayları tekrar basar. Bu yüzden tüketicilerin mükerrer kontrolü (idempotency) yapması şarttır.

PostgreSQL Debezium entegrasyonlarında 'Replication Slot' nedir?

Bağlı tüketici (Debezium) verileri okuduğunu onaylayana kadar PostgreSQL'in WAL log dosyalarını diskten silmesini engelleyen güvenlik mekanizmasıdır.

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

Temel Gerçekler & İlkeler

  • Dual-writing (DB + Kafka in code) guarantees silent data loss or ghost events during failures.
  • Transactional Outbox writes domain data and outbox events in a single local ACID transaction.
  • Debezium CDC streams committed outbox events from the database WAL with zero polling overhead.
  • Debezium provides At-Least-Once delivery; consumers must be strictly idempotent.

Yaygın Yanılgılar

  • Yanılgı: Polling the outbox table with a cron job is fine for production (Gerçek: Table polling causes heavy lock contention and latency lag at scale).
  • Yanılgı: Debezium reads uncommitted dirty database transactions (Gerçek: CDC only processes committed transactions from the WAL).

Karar Kılavuzu & Önceliklendirme

Adopt the Transactional Outbox pattern with Debezium for all asynchronous microservice eventing. Set PostgreSQL `max_slot_wal_keep_size` and monitor replication slot lag in Datadog.

Doğrulanmış Kaynaklar & Referanslar