Read Replica Lag'ini Görmezden Gelmek
Kayıt ettim, liste boş döndü

Okuma yoğun, yazma seyrek. Replica bağlamak doğru içgüdü. Yanlış olan, kaydet-yönlendir-listele zincirini de replica'ya vermek. Insert primary'de commit oldu, 800 ms sonra GET replica'dan geldi, satır yok, UI 'kaydedilemedi' gösterdi. Kaydedildi. Apply gecikti.
Lag görünmüyorsa yok sanılır
SELECT now() - pg_last_xact_replay_timestamp() AS replay_lag;
replay_lag gece 40 ms, import sırasında 12 saniye. Ortalama 200 ms ile karar vermek, kuyruğun kuyruğunu yok saymak. Alarmı 1 saniyeye kurdum. 1 saniyenin üstünde replica'dan 'kendi yazın' okunmuyor.
Yönlendirme
public sealed class PostStore(NpgsqlDataSource primary, NpgsqlDataSource replica)
{
public async Task CreateAsync(NewPost draft, CancellationToken ct)
{
await using var cmd = primary.CreateCommand(
"INSERT INTO posts (id, title, status) VALUES ($1, $2, 'draft') RETURNING id");
cmd.Parameters.AddWithValue(Guid.NewGuid());
cmd.Parameters.AddWithValue(draft.Title);
return (Guid)(await cmd.ExecuteScalarAsync(ct))!;
}
public async Task GetAsync(Guid id, bool seeOwnWrite, CancellationToken ct)
{
var source = seeOwnWrite ? primary : replica;
await using var cmd = source.CreateCommand(
"SELECT id, title, status FROM posts WHERE id = $1");
cmd.Parameters.AddWithValue(id);
await using var reader = await cmd.ExecuteReaderAsync(ct);
if (!await reader.ReadAsync(ct)) return null;
return new PostRow(reader.GetGuid(0), reader.GetString(1), reader.GetString(2));
}
}
seeOwnWrite, kaydet sonrası detay ve 'benim taslaklarım' için true. Genel keşif listesi replica'da kalır. Session sticky ile her GET'i primary'ye yapıştırmak replica'yı boş bırakır. Bayrak istek türünde, kullanıcıda değil.
Ne replica'ya gitmez
- Yazma sonrası hemen okunan detay.
- Unique ihlali gibi 'var mı' kontrolleri — replica yok der, primary var der.
- Ödeme sonrası bakiye. 1.2 sn eski bakiye, çift harcama tartışması açar.
Lag'i görmezden gelmek replica'yı 'ücretsiz okuma' sanmak. Ücretsiz değil; gecikmiş bir kopya. Kopyanın yaşı iş kuralına sığmıyorsa o okuma primary'de kalır. Sığdığı yerde replica durur. İkisini ayırmadan connection string'e replica yazmak, kaydet-ve-gör'ü kırmak.
Yorumlar
Yorumlar (0)
Yorumlar üyelere açık. Üye ol · Giriş yap