# CQRS'i ne zaman uygulamalı ve okuma/yazma modellerini nasıl senkronlamalıyım?

> Raporlamayı bir read-replica'ya taşıyın, tam CQRS'e ancak sorgu şekilleri tek şemaya sığmadığında geçin ve okuma modelini outbox event'leriyle besleyin.

- Soruldu: 2026-06-06
- Yanıtlandı: 2026-06-09
- Soran: Rüzgar
- Etiketler: veritabani, mimari, elasticsearch
- Kaynak: https://www.muhammetsafak.com.tr/sor-bakalim/cqrs-ne-zaman-uygulanir-ve-okuma-yazma-senkronizasyonu/
- Dil: tr-TR
- Yazar: Muhammet Şafak

---
**Soru:** Uygulamamızda yazma operasyonları çok az (günde ~5.000 kayıt) ama okuma ve karmaşık raporlama çok yoğun (saniyede ~2.000 sorgu). İlişkisel DB raporlama sorguları yüzünden kilitleniyor. Yazma modelini (PostgreSQL) ve okuma modelini (Elasticsearch veya optimize Read-Replica SQL) tamamen ayırmak (CQRS) istiyoruz.

İki model arası senkronizasyonu event-driven, gecikmesiz ve güvenilir nasıl sağlarım?


Kısa cevap: Günde 5.000 yazma karşısında saniyede 2.000 okuma — bu asimetri gerçekten CQRS'e oynayan bir vaka. Ama en ucuz sürümle başla; doğrudan tam CQRS'e atlama.

Sorun net: ağır raporlama sorguları yazma yolunu da kilitliyor. Çoğu zaman bunu çözmek için tam bir mimari ayrışmaya gerek yok.

1. **Önce read-replica ekle.** PostgreSQL'e bir veya birkaç read-replica koy ve tüm raporlama sorgularını oraya yönlendir. Yazma primary'de kalır, okuma replica'da; kilitlenme çoğu zaman sadece bununla biter. Bunu denemeden CQRS karmaşıklığını üstlenme.
2. **Tam CQRS'i ne zaman hak eder anla.** Ayrı bir okuma modeli (Elasticsearch ya da denormalize SQL) ancak sorgu şekilleri tek bir şemanın ikisini birden iyi servis edemeyeceği kadar ayrıştığında değer. Full-text arama, ağır agregasyon gibi ihtiyaçlar replica'nın da yetmediği noktada okuma modelini ayırmaya değer kılar.
3. **Modelleri event-driven senkronla.** Yazma tarafı her değişiklikte event üretsin; bir projector bu event'leri tüketip okuma modelini güncellesin. Güvenilirlik için **outbox pattern** kullan: event'i iş verisiyle aynı transaction içinde bir outbox tablosuna yaz, ayrı bir süreç onu yayınlasın — böylece "DB commit oldu ama event kayboldu" durumu olmaz.
4. **Eventual consistency'yi kabul et, dual-write yapma.** Okuma modeli yazmadan milisaniye-saniye geride kalır; UI'ı buna göre tasarla (örn. "kaydedildi" anında, listede biraz sonra görünür). Asla uygulamadan iki store'a birden yazma (dual-write) — kaçınılmaz olarak birbirinden kayar (drift). Okuma modelini daima yazma tarafının event'lerinden besle.

**Sonuç:** Önce replica, raporlamayı oraya taşı. Tam CQRS'i yalnızca sorgu ihtiyaçları gerçekten ayrıştığında, outbox-tabanlı projeksiyonlarla kur — ve eklediğin karmaşıklığı bir maliyet olarak gör. "PostgreSQL bana yeter mi?" sorusunun cevabı çoğu yükte hâlâ evet; CQRS'e geçmeden önce onu sonuna kadar zorla.

## İlgili Yazılar

- [PostgreSQL Her Şeye Yeter mi?](https://sade.dev/tr/journal/postgresql-her-seye-yeter-mi) — sade.dev
- [Esnek ürün nitelikleri için NoSQL mu, PostgreSQL mi seçmeliyim?](https://www.muhammetsafak.com.tr/sor-bakalim/esnek-urun-nitelikleri-icin-nosql-mu-postgresql-mi/) — Sor Bakalım
- [Elasticsearch'te 'search-as-you-type' performansını edge n-gram ile nasıl optimize ederim?](https://www.muhammetsafak.com.tr/sor-bakalim/elasticsearch-anlik-arama-edge-ngram-ile-optimizasyon/) — Sor Bakalım
- [Multi-tenant SaaS'ta veritabanı izolasyonu: ayrı DB mi, şema mı, tenant_id mi?](https://www.muhammetsafak.com.tr/sor-bakalim/multi-tenant-saas-veritabani-izolasyon-stratejisi/) — Sor Bakalım
