Event Sourcing (Olay Kaynaklama): Tasarım, Uygulama ve Üretim Rehberi
1. GİRİŞ
Event Sourcing (olay kaynaklama), uygulama state'inin yalnızca son halini değil, o hale nasıl ulaşıldığını da olay (event) logları şeklinde saklayan bir veri modeli ve mimari yaklaşımdır. Bu yaklaşım, geleneksel CRUD (Create, Read, Update, Delete) modellerinin ötesinde "tarihçe odaklı" bir bakış açısı getirir: sistemde meydana gelen her değişiklik bir olay olarak kaydedilir ve uygulamanın anlık durumu bu olayların sıralı şekilde oynatılmasıyla (rehydration) elde edilir.
Bu teknoloji neden konuşuluyor?
- İzlenebilirlik, audit ve debugging ihtiyacı arttı: olay tabanlı kayıt geçmişi hata kök neden analizini kolaylaştırır.
- Event Driven Architectures (EDA), mikroservis ve gerçek‑zamanlı analiz gereksinimleri yaygınlaştı.
- Replay yeteneği, analytics ve machine learning için ham veri sağlar; geçmişe dönük yeniden hesaplama imkânı sunar.
Kimler için önemli?
- Yazılım mimarları ve backend mühendisleri
- Data mühendisleri, SRE ve güvenlik ekipleri
- Finans, e‑ticaret, telekom gibi audit ve tarihçe gereksinimi yüksek sektörler
Hangi problemleri çözüyor?
- State değişikliklerinin tam olarak nasıl gerçekleştiğinin izlenmesi
- Event sourcing ile replay ve reprocessing imkânı
- Offline reconciliation, audit trail ve time‑travel debugging sağlama
2. KAVRAMSAL TEMELLER
2.1 Olay (Event) nedir?
Olay, sistemde gerçekleşmiş bir değişikliğin semantik ifadesidir. Genelde geçmiş zamanlı bir isimlendirme kullanılır: "OrderPlaced", "PaymentCaptured", "InventoryReserved" gibi. Olay, hangi aktörün ne zaman ne yaptığını ve hangi verinin değiştiğini taşır. Olaylar immutable'dır: bir kez yazıldıktan sonra değiştirilemezler (append‑only).
2.2 Event Store (Olay Deposu)
Event Store, olayların append‑only biçimde saklandığı sistemdir. Bir event store aşağıdaki özellikleri sağlamalıdır: sıralı yazma (ordering), dayanıklı persistence, etkin replay, arşivleme/retention ve efficient projection desteği. Örnek teknolojiler: EventStoreDB, Apache Kafka (log storage), ve relationel append‑only tablolar.
2.3 Aggregate, Command, Projection
- Aggregate: Domain modelinin transactional boundary'si; komutlar aggregate'a gönderilir ve aggregate iş kurallarına göre olay üretir.
- Command: Sisteme niyet bildiren çağrı; sonuç olarak sıfır veya daha fazla event ortaya çıkabilir.
- Projection / Read Model: Olaylardan türetilen sorgulanabilir, optimize edilmiş veri yapısı (ör. SQL tablo, Elasticsearch index, denormalize edilmiş view).
2.4 CQRS (Command Query Responsibility Segregation)
CQRS, komut (write) ve sorgu (read) yollarını ayırarak farklı modeller kullanmayı savunur. Event sourcing ile birlikte kullanıldığında; aggregate'lar event üretir, event store'a yazılır ve projection'lar bu olayları dinleyip read model'leri günceller. Bu kombinasyon, write tarafındaki tutarlılık ve read tarafındaki performans arasında esneklik sağlar.
3. NASIL ÇALIŞIR?
3.1 Sistem mimarisi — high level
Tipik bir event sourcing akışı şu adımlardan oluşur: 1) Client bir command gönderir; 2) Command validation ve business logic aggregate içinde çalışır; 3) Aggregate, sonucu temsil eden event'leri üretir; 4) Event'ler event store'a append edilir; 5) Event'ler projection consumer'lara yayılarak read model'ler güncellenir; 6) Async işlem veya integration için event bus üzerinden diğer sistemlere bildirim yapılır.
3.2 Transaction boundary ve atomic append
En kritik gereksinim yazılan event'lerin atomik olarak kalıcı olmasıdır. Bir aggregate üzerine uygulanan işlemin yan etkileri (event'ler) mutlaka event store'a doğru sırada append edilmeli ve duruma göre transactional guarantees sağlanmalıdır. Birçok uygulama "transactional outbox" pattern'ı kullanır: veritabanı transaction'ı içinde outbox'a event yazılır; daha sonra outbox poller event'i broker'a gönderir. Bu pattern distributed transaction ihtiyacını ortadan kaldırır.
3.3 Snapshotting ve performans
Aggregate'ları yeniden oluşturmak için uzun event zincirlerini baştan oynatmak maliyetli olabilir. Snapshotting, belirli aralıklarda aggregate'in o anki in‑memory durumunun (snapshot) saklanmasıdır. Replay sırasında en son snapshot alınır ve ardından ondan sonraki event'ler uygulanarak aggregate hızlıca rehydrate edilir. Snapshot frekansı iş yüküne göre dengelenmelidir.
3.4 Projection'lar ve eventual consistency
Projection'lar event'leri dinleyip read model'leri günceller. Bu güncellemeler genelde asenkron olduğu için read modeller eventual consistent'olur. Bu, kullanıcı deneyimi ve sorgu tutarlılığı açısından dikkat gerektirir — bazı senaryolarda read‑after‑write garantisi için ek mekanizmalar (refresh endpoint, synchronous projection update) gerekebilir.
3.5 Schema evolution ve upcasting
Olay şemaları zamanla değişir: yeni alan eklenir, eski alanlar deprecated olur. Event versioning ve upcasting bu değişiklikleri yönetir. Upcaster'lar eski version event'i yeni forma çevirir; ya da consumer tarafında tolerant parser kullanılır (schema evolution). Ayrıca contract testing ve schema registry (Protobuf/Avro/JSON Schema) ile uyumluluk kontrolleri CI sürecine dahil edilmelidir.
4. GERÇEK DÜNYA KULLANIMLARI
4.1 Finans ve ödeme sistemleri
Finans sektörü audit, traceability ve rollback ihtiyaçları nedeniyle event sourcing'i sık kullanır. İşlem geçmişi, chargeback ve uyumluluk raporları için olay tabanlı kayıt vazgeçilmezdir.
4.2 E‑ticaret ve envanter yönetimi
Sipariş akışı, stok rezervasyonu, iade ve ödeme adımları olay olarak kaydedilerek; geçmişe dönük hataların analizi, inventory reconciliation ve replay ile müşteri deneyimi iyileştirilebilir.
4.3 İş zekâsı ve analytics
Ham olay logları analytics pipeline'larına kaynak sağlar. ETL yerine doğrudan event stream'den veri çekilerek gerçek‑zamanlı metrikler, ML feature'lar ve dashboard'lar oluşturulur.
4.4 Bilgi tabanlı ürünler (audit, compliance)
Uyumluluk gereksinimleri (finansal regülasyonlar, sağlık vb.) için tam olay geçmişinin tutulması zorunludur. Event sourcing, audit trail'i sağlamada doğal bir altyapıdır.
5. AVANTAJLAR VE SINIRLAMALAR
Avantajlar
- Tam audit trail: her değişikliğin kaydı tutulur.
- Replay yeteneği: geçmişi yeniden oynatma ve hataları düzeltme imkânı.
- Event-driven entegrasyon: diğer servisler olayları subscribe ederek reaktif davranır.
- Analitik ve ML için ham veri sağlar.
Sınırlamalar
- Operasyonel karmaşıklık: event store, projection, snapshot ve schema evolution yönetimi gerekir.
- Event schema'ları yönetimi ve geriye dönük uyumluluk zorlukları.
- GDPR ve "right to be forgotten" gibi regülasyonlar için olayların silinmesi veya maskelenmesi karmaşık olabilir.
- Event replay maliyeti: büyük event log'larının yeniden işlenmesi kaynak tüketir.
6. ALTERNATİFLER VE KARŞILAŞTIRMA
| Yaklaşım | Avantaj | Dezavantaj |
|---|---|---|
| CRUD/RDB merkezli | Basit, yaygın, geliştirme hızı yüksek | Geçmiş değişiklikleri izleme zor, replay mümkün değil |
| Event Sourcing + CQRS | Audit, replay, event driven entegrasyonlar, analytics | Operasyonel karmaşıklık, schema yönetimi, GDPR zorlukları |
| Change Data Capture (CDC) + Event Streaming | Mevcut RDB'yi bozmadan event stream oluşturma, daha kolay adopt | Semantik olayların net olmayışı, bazı domain bağlamlarının kaybolması |
7. EN İYİ PRATİKLER
Production kullanımı
- Event'leri immutable, small ve semantic olarak anlamlı tutun — "event baggage" eklemeyin.
- Schema registry, versioning ve contract testing ile producer/consumer uyumluluğunu sağlayın.
- Snapshotting stratejisi belirleyin: snapshot frekansı, format ve storage planı önceden tanımlı olsun.
- Transactional outbox pattern'ını kullanarak veri tabanı tutarlılığı ve event publish atomikliğini sağlayın.
Performans optimizasyonu
- Projection'ları paralelize edin; read model'leri hedeflenmiş olarak optimize edin.
- Replay için canary reprocess ve throttling uygulayın; büyük replay'leri parçalara bölün.
- Event store için storage ve retention planı (tiered storage, cold archive) oluşturun.
Güvenlik ve uyumluluk
- Sensitif verileri doğrudan event içinde saklamayın; referans/hashed değerler veya encrypted payload kullanın.
- GDPR yaklaşımı: event'larda PII minimal tutulmalı; silme istekleri için protect/redirect pattern'ları düşünün (compensating events veya redaction).
Observability
- Event throughput, projection lag, snapshot frequency, replay duration gibi metrikleri izleyin.
- Trace correlation id ile produce → store → projection akışını korelasyonlayın.
8. SIK YAPILAN HATALAR
- Event'leri POCO data dump olarak kullanmak — olayların semantic anlamı korunmalı.
- Snapshot veya projection olmadan uzun event stream'leri baştan oynatmaya çalışmak — performans felaketi.
- Schema evolution planı olmadan event üretmeye başlamak — breaking change riski büyük.
- GDPR ve PII konularını tasarım aşamasında göz ardı etmek — sonradan çözülmesi zor problemlere yol açar.
9. GELECEK TRENDLER
- Event Mesh ve federated event store'lar: Mikroservisler arası event routing ve governance katmanları olgunlaşacak.
- Serverless stream processing: Otomatik ölçeklenen, tüketim‑odaklı stream processing modelleri yaygınlaşacak.
- AI‑assisted schema evolution: Telemetry ve ML ile event formatlarının etkisi analiz edilip otomatik uyumluluk önerileri getirilecek.
- Privacy‑aware event stores: PII handling, selective redaction ve privacy hooks gibi özellikler native olarak sunulacak.
EK BÖLÜMLER
Sık Sorulan Sorular (FAQ)
- 1. Event Sourcing her projeye uygun mudur?
Hayır. Küçük CRUD uygulamalar veya history gereksinimi olmayan projeler için fazla karmaşıktır. Audit, replay veya event driven ihtiyaçları veri‑driven ise tercih edilir.
- 2. Event ile Domain Event arasındaki fark nedir?
Domain Event, domain dilinde anlam taşıyan olaydır ve iş kurallarını temsil eder; transport event ise bu domain event'in seri hale getirilmiş formudur. Domain event'ler semantik açıdan önemli olmalıdır.
- 3. Replay nasıl test edilir?
Replay'i staging ortamında, canary subset üzerinde test edin; idempotent projections ve throttling ile production riskini azaltın.
- 4. Event store olarak Kafka mı EventStoreDB mi?
Kafka, yüksek throughput ve stream processing ekosistemi için uygundur; EventStoreDB ise event sourcing için tasarlanmış append‑only store, güçlü projections ve transactional API'ler sunar. Karar kullanım senaryosu ve operational yetkinliğe bağlıdır.
- 5. Snapshot ne sıklıkta alınmalı?
Snapshot sıklığı aggregate'in event üretim hızına ve replay maliyetine bağlıdır. Çok event üreten aggregate'lar için daha sık snapshot alınmalı; maliyet‑fayda analizi yapın.
- 6. GDPR ile event retention nasıl yönetilir?
Event'larda PII minimal tutulmalı; redaction, encryption, tokenization veya referans bazlı saklama tercih edilmelidir. Silme talepleri için compensating events veya selective masking uygulanabilir.
- 7. Transactional outbox nedir?
Veri tabanı transaction'ı içinde outbox tablosuna event yazıp daha sonra asenkron olarak bu outbox'u publish ederek atomic publish garantisi sağlayan pattern'dir.
- 8. Event versioning nasıl uygulanmalı?
Schema registry, semantic versioning, upcaster'lar veya tolerant parsers ile versioning yönetilir. Breaking change'lerden kaçının; yeni alan eklemeleri backward compatible olmalıdır.
Anahtar Kavramlar
- Event Store
- Olayların append‑only olarak saklandığı sistem; replay ve projection için kaynak.
- Projection
- Olaylardan türetilen sorgulanabilir read model.
- Snapshot
- Aggregate'in belirli anlık durumu; rehydrate maliyetini azaltmak için kullanılır.
- Outbox Pattern
- Transactional publish için kullanılan, veritabanı tabanlı outbox yaklaşımı.
- Upcaster
- Eski version event'leri yeni schema'ya dönüştüren bileşen.
Öğrenme Yol Haritası
- 0–1 ay: Event Sourcing, CQRS ve temel domain driven design (DDD) kavramlarını öğrenin; küçük bir demo implementasyonu yapın.
- 1–3 ay: Event store (EventStoreDB veya Kafka) ile pratik yapın; projection, snapshot ve replay senaryoları uygulayın.
- 3–6 ay: Transactional outbox, CDC integration ve schema evolution pratiklerini üretim ölçeğinde deneyin.
- 6–12 ay: Büyük replay'ler, GDPR uyumluluğu, multi‑region event routing ve event mesh konularında olgunlaşın.