---
title: "Read/Write Splitting: Okuma ve Yazma Yükünü Ayırmak"
description: "Veritabanını büyütmeden önce: okuma trafiğini replica'lara taşımak, replication lag'in yarattığı tuzaklar ve ne zaman gerçekten gerektiği."
url: https://sade.dev/tr/notes/read-write-splitting/
lang: tr
author: "Muhammet Şafak"
published: 2026-08-22
updated: 2026-09-06
section: Note
tags: ["postgresql","database","scaling","performance"]
summary: "Read replica okumayı ölçekler, yazma kapasitesine hiçbir şey katmaz; bu yüzden takas bedava değildir, bedeli replication lag'dir. Laravel'in sticky seçeneği read-after-write'ı yalnızca tek bir istek içinde onarır; iki istek arasında kullanıcı az önce güncellediği profili hâlâ bayat görür. Önce indeks disiplini: replica çoğu zaman tek bir CREATE INDEX'in çözeceği şeyi pahalıya satın almaktır."
---

# Read/Write Splitting: Okuma ve Yazma Yükünü Ayırmak

> Read replica okumayı ölçekler, yazma kapasitesine hiçbir şey katmaz; bu yüzden takas bedava değildir, bedeli replication lag'dir. Laravel'in sticky seçeneği read-after-write'ı yalnızca tek bir istek içinde onarır; iki istek arasında kullanıcı az önce güncellediği profili hâlâ bayat görür. Önce indeks disiplini: replica çoğu zaman tek bir CREATE INDEX'in çözeceği şeyi pahalıya satın almaktır.

Primary veritabanının CPU'su sürekli tavandaydı. İlginç olan şuydu: yazma oranı düşüktü. Yükün neredeyse tamamı okumaydı — rapor sayfaları, listeleme endpoint'leri, arama. Tek bir primary, kendisine hiç ihtiyaç duymayan bir sürü okumayı taşımaya çalışıyordu.

Okuma ve yazma yükünü ayırmak — read/write splitting — bu tablonun bilinen çözümü. Ama doğru zamanda ve doğru tuzakların farkında uygulanmazsa, çözdüğünden çok problem getirir.

## Çoğu yük okuma ağırlıklıdır

Trafiğin ne kadarının okuma olduğu iş yüküne bağlıdır: standart OLTP benchmark'larının ölçümünde TPC-E %90,69 okumadır, TPC-C ise %65,71'de kalır — yani kendi oranınızı varsaymak yerine ölçün. Her sipariş bir kez yazılır, ama onlarca kez okunur: listede, detayda, raporda, panelde. Bu asimetri, read/write splitting'i cazip kılan şeydir — çünkü ölçeklemeniz gereken taraf bellidir.

## Önce: bu gerçekten bir kapasite sorunu mu?

Replica eklemeden önce durun. Primary'nin dolu olması her zaman "kapasite bitti" demek değildir. Çoğu zaman tek bir eksik indeks, primary'yi olduğundan kat kat meşgul gösterir.

Bir replica eklemek — yeni bir sunucu, replication kurulumu, lag izleme — aslında bir `CREATE INDEX`'in çözeceği bir problemi pahalıya satın almak olabilir. [Veri yoğunluklu sistemlerin kırılma noktaları](/tr/systems/veri-yogunluklu-sistemler-kirilma-noktalari) yazısındaki sıra nettir: önce indeks disiplini, sonra replica. Bu sırayı atlamayın.

Sorgularınızı `EXPLAIN ANALYZE` ile ölçün. Primary, doğru indekslenmiş sorgular altında gerçekten doyuyorsa — işte o zaman replica.

## Replica okumayı ölçekler, yazmayı değil

Net olalım: bir read replica, yazma kapasitenize **hiçbir şey** katmaz. Aynı yazmalar her replica'da yeniden oynanır. Replica okuma yükü problemini çözer; yazma yükü probleminiz varsa replica yanlış araçtır.

## Laravel'de kurulum

Laravel, okuma/yazma bağlantı ayrımını doğal destekler:

```php
// config/database.php
'pgsql' => [
    'driver' => 'pgsql',
    'read'   => ['host' => ['10.0.0.2']],   // replica
    'write'  => ['host' => ['10.0.0.1']],   // primary
    'sticky' => true,
    // ...ortak ayarlar
],
```

`SELECT`'ler replica'ya, `INSERT/UPDATE/DELETE`'ler primary'ye gider. Replica'nın kendi bağlantı havuzu olur — primary'ninkinden ayrı; [pgBouncer](/tr/notes/pgbouncer-auth-query) kullanıyorsanız ikisi ayrı havuzdur.

## Replication lag: asıl fatura

Replica, primary'nin birkaç milisaniye — yük altında birkaç saniye — gerisindedir. Bu gecikme, read/write splitting'in gerçek bedelidir ve adı **read-after-write** problemidir.

`sticky => true` bunu kısmen çözer: bir istek içinde yazma yaptıysanız, aynı istekteki sonraki okumalar primary'ye gider. Ama `sticky` yalnızca **tek bir istek** sınırında çalışır.

Sınırın dışı hâlâ açıktır: kullanıcı profilini günceller (istek 1, primary'ye yazıldı), sonraki sayfaya geçer (istek 2, replica'dan okur) ve henüz replica'da oynanmamış eski profilini görür. Kullanıcı kendi yazdığı veriyi bayat görür. Bu bir bug gibi görünür ama aslında mimarinin kabul ettiği bir ödündür — bilerek kabul edilmesi gereken bir ödün.

## Sorgu sınıflandırma disiplini

Read/write splitting'i kurmak, her okumanın şu soruya cevap vermesini gerektirir: **bu sorgu bayat veri okuyabilir mi?**

- **Replica'dan okunabilir:** listeler, raporlar, arama sonuçları, paneller. Birkaç saniye gecikme önemsiz.
- **Primary'den okunmalı:** hesap bakiyesi, stok adedi, yetki kontrolü, bir yazma kararının dayandığı her okuma.

Bu sınıflandırma artık mimarinin bir parçasıdır ve dokümante edilmesi gerekir. Yeni gelen bir geliştiricinin "bu sorgu nereden okumalı" sorusuna bakacak bir yeri olmalı — yoksa sınıflandırma sessizce çürür.

## Ne zaman gerçekten gerekir?

Read/write splitting şu üç koşul birlikte sağlandığında doğru hamledir:

1. İndeks disiplini tamamlanmış; sorgular doğru indeksli ve hâlâ primary doyuyor.
2. Yük ölçülmüş biçimde okuma ağırlıklı.
3. Bayat-okuma sınıflandırmasını yapıp dokümante edecek disiplin var.

Bunlardan biri eksikse, replica'yı ertelemek daha ucuzdur.

---

Read/write splitting, dikey büyümeden ucuz bir ölçek hamlesidir — ama bedava değildir. Bedeli replication lag'dir ve onu görmezden gelmek, kullanıcıya kendi verisini eski göstermekle ödenir.

Okumayı ayırmadan önce, hangi okumanın bayatlığa dayanabileceğini bilin.

## Sık sorulanlar

**Read replica eklemek yazma kapasitesini arttırır mı?**

Hayır. Aynı yazmalar her replica'da yeniden oynanır; replica yazma throughput'una hiçbir şey katmaz. Okuma yükü problemini çözer; problem yazma tarafındaysa replica yanlış araçtır.

**sticky seçeneği neyi çözer, neyi çözmez?**

sticky açıkken aynı istek içinde yazmadan sonra gelen okumalar primary'ye gider; kullanıcı tek bir istek içinde kendi yazdığını bayat okumaz. İstekler arasında ise hiçbir şey yapmaz: sonraki sayfa hâlâ yazmayı henüz oynamamış bir replica'dan okuyabilir.


## Kaynaklar

- [Log-Shipping Standby Servers: streaming replication and hot standby](https://www.postgresql.org/docs/current/warm-standby.html) — PostgreSQL
- [TPC-E vs. TPC-C: Characterizing the New TPC-E Benchmark via an I/O Comparison Study](https://www.cs.cmu.edu/~chensm/papers/TPCE-sigmod-record10.pdf) — ACM SIGMOD Record 39(3), 2010
- [Database: Read and Write Connections](https://laravel.com/docs/12.x/database#read-and-write-connections) — Laravel
