.NET ve PostgreSQL ile Azure’da Cache’i Ciddiye Almak
Bir uygulama yavaşsa, kullanıcı bunu anında fark ediyor. Hatta bazen sorun kodda bile olmuyor; veri kaynağı uzakta kalıyor, sorgu ağırlaşıyor, ağ da biraz dalgalanıyor… işte tam o anda cache devreye giriyor ve oyun değişiyor. Ben bu tabloyu yıllardır hem hosting — itiraz edebilirsiniz tabi — tarafında hem de Azure projelerinde defalarca gördüm. Mesela de kurumsal tarafta, “sadece bir cache ekleyelim” cümlesi kağıt üstünde kolay dürüyor ama iş pratiğe gelince olay biraz karışıyor.
Geçen yıl, 2025 Mart’ında İstanbul’da bir finans müşterisinde benzer bir yapı konuşuyorduk. Uygulama.NET üstünde çalışıyordu, birkaç dış servis çağrısı vardı ve bazı ekranlar gereksiz yere 2-3 saniye sürüyordu. Aslında veri azdı… ama erişim pahalıydı. Tam burada distributed caching fikri devreye girdi. Sonuç fena değildi; özellikle tekrar eden okumalarda baya rahatlama öldü.
Bu yazıda, Microsoft’un.NET ve Azure PostgreSQL ile anlattığı yaklaşımı kendi deneyimimle harmanlayarak anlatacağım. Kuru kuruya “şunu kurun, bunu ekleyin” demeyeceğim. Nerede işe yarıyor, nerede biraz abartı kaçıyor — açık konuşayım — önü da söyleyeceğim.
Cache Neden Bu Kadar Önemli?
Cache dediğimiz şey aslında mutfakta tezgah üstüne koyduğunuz sık kullandığınız malzeme gibi. Her seferinde dolaptan çıkarmıyorsunuz; elinizin altında dürüyor. Yazılım tarafında da sık kullanılan veriyi yakında tutunca sistem nefes alıyor. Kullanıcı beklemiyor, backend gereksiz yorulmuyor.
Şimdi gelelim işin aslına: her şeyi cache’lemek doğru değil. Ben 2019’da Ankara’da bir e-ticaret projesinde bunu biraz fazla hevesle yapmıştım; ürün stokları için agresif cache kullanınca güncellik problemi yaşadık. O zaman anladım ki hız güzel şey ama doğrulukla kavga etmeye başladığında işler çamura yatıyor.
Kurumsal müşterilerde en sık gördüğüm senaryo şu: verinin yüzde 20’si trafiğin yüzde 80’ını oluşturuyor. Yanı bazı lookup işlemleri, profil bilgileri ya da referans veriler sürekli dönüyor. Bunları cache’e almak baya iş görüyor. Ama sipariş durumu gibi saniyesi saniyesine değişen veride dikkatli olmak lazım.
Kısa bir not düşeyim buraya.
.NET tarafında neden HybridCache?
.NET dünyasında HybridCache yaklaşımı hoşuma gidiyor çünkü iki katmanı birlikte kullanabiliyorsunuz: bellek içi hızlı katman ve kalıcı dağıtık katman. Tek başına memory cache güzel ama tek makinede kalır; pod ölürse gider. Sadece dağıtık cache işe dayanıklıdır ama biraz daha yavaştır — dürüst olayım, biraz hayal kırıklığı —. Hybrid yaklaşım ikisinin ortasını buluyor (şaşırtıcı ama gerçek)
2024 Kasım ayında Logosoft’ta bir kamu müşterisinde bunu konuşurken ekip önce “neden direkt Redis değil?” diye sordu. Haklılar aslında. Ama burada amaç sadece hız değil; aynı zamanda sadelik de var işin içinde (ve bakım maliyeti). Küçük ekiplerde sade mimarı çoğu zaman daha sağlıklı oluyor.
Bir dakika — bununla bitmedi.
Azure Database for PostgreSQL burada ne yapıyor?
PostgreSQL’i distributed cache için kullanmak ilk bakışta alışılmadık gelebilir ama bazı senaryolarda gayet mantıklı (şaşırtıcı ama gerçek). En çok da zaten PostgreSQL kullanan kurumlarda ayrı bir cache altyapısı açmadan ilerlemek operasyonu kolaylaştırıyor. Yeni servis demek yeni izleme, yeni güvenlik ayarı, yeni yedekleme derdi demek — hani kim ister? Bu konuyla ilgili Microsoft Discovery ile Ar-Ge’de Yeni Oyun: Agentic Yapılar yazımıza da göz atmanızı tavsiye ederim.
Bir şey dikkatimi çekti: Büyük enterprise yapılarda işe tablo biraz farklı olurdu doğrusu: çok yüksek TPS varsa Redis hâlâ daha doğal tercih olabilir. Çünkü bellek tabanlı sistemler gecikme açısından daha rahat nefes alır. Ama orta ölçekli kurumsal yapılarda Postgres ile başlamanın avantajı var; mevcut yetkinlikten faydalanıyorsunuz.
Bunu biraz açayım.
Mimaride Neler Değişiyor?
Garip gelecek ama, Klasik yaklaşımda uygulama her istekte veritabanına gider… sonra tekrar gider… sonra yine gider. Bir noktadan sonra database “beni niye bu kadar zorluyorsun?” der gibi bakar adeta. Cache eklediğinizde uygulama önce yakın belleğe bakar, yoksa dağıtık katmana iner, en son kaynak sisteme döner.
Ben bu modeli ilk kez 2020’de Bursa’daki bir lojistik firmasının portalında denemiştim. O dönemde rapor ekranları bir düşüneyim… çok ağırdı çünkü aynı filtre kombinasyonları defalarca çalışıyordu. Cache sonrası CPU kullanımı düştü, SQL bağlantıları rahatladı ve ekip sabah kahvesini daha sakın içmeye başladı diyeyim… Bu konuyla ilgili Apple Watch’ta Token Taşıma: Entra External ID’de Yeni Dönem yazımıza da göz atmanızı tavsiye ederim.
E tabi her şey güllük gülistanlık değil: invalidation konusu can sıkıcı olabilir. Veri güncellendiğinde cache’i nasıl temizleyeceksiniz? TTL mi vereceksiniz? Event mi dinleyeceksiniz? Yoksa manuel mi yöneteceksiniz? İşte asıl tasarım burada başlıyor. Bu konuyla ilgili VSIX İçin SDK-Style Proje Desteği: Build Süresi %75 Azalıyor yazımıza da göz atmanızı tavsiye ederim. Run Dialog Yenilendi: Hız, Sadelik ve Güç Bir Arada yazımızda bu konuya da değinmiştik.
| Yaklaşım | Artı Tarafı | Ekşi Tarafı |
|---|---|---|
| Sadece Memory Cache | Aşırı hızlı | Sunucu değişince veri uçar |
| Sadece Distributed Cache | Daha dayanıklı | Bellek kadar hızlı değil |
| HybridCache + Postgres | Denge iyi | Tasarım biraz dikkat istiyor |
Küçük startup vs enterprise
Bak şimdi, Küçük startup iseniz ben olsam önce basit başlarım: iyi tanımlanmış TTL değerleriyle cache kurarım ve ölçerim. Çünkü erken aşamada aşırı mühendislik bazen gereksiz yük getirir. İşletme tarafındaki ihtiyaç netleşmeden devasa mimarı çizmek pek akıllıca olmaz (ben de ilk duyduğumda şaşırmıştım)
Büyük kurumsal tarafta işe observability şart oluyor. Loglama yoksa neyi hızlandırdığınızı bile anlamazsınız. Burada structured logging ve metrikler önemli… hatta bazen cache hit ratio tek başına karar vermeye yeterli oluyor! azure konusundaki yazımız yazımızda bu konuya da değinmiştik.
.NET Console Uygulamasını Host Tabanlı Hâle Getirmek
.NET Generic Host bence bu işin gizli kahramanı gibi çalışıyor. Konfigürasyon, dependency injection, logging, background service… hepsi tek çatı altında toplanınca konsol uygulaması oyuncak olmaktan çıkıp ciddi bir servise dönüşüyor. Bunu AZ-104. AZ-305 sınavlarına hazırlanırken de çok düşünmüştüm; çünkü mimarı olarak temiz ayrılmış parçalar uzun vadede hayat kurtarıyor.
using Microsoft.Extensions.Hosting;
var builder = Host.CreateDefaultBuilder(args);
builder.ConfigureAppConfiguration((hostingContext, config) =>
{
// Ek ayarlar buraya
});
builder.ConfigureServices((hostingContext, services) =>
{
// Servis kayıtları
});
builder.ConfigureLogging(logging =>
{
// Log ayarları
});
var app = builder.Build();
await app.RunAsync();
Bunun güzel tarafı şu: küçük projede de iş görüyor, büyük projede de büyüyebiliyor.Yani bugün demo olan yapı yarın worker service’e dönebilir.Ama şunu da söyleyeyim,ilk denediğimde config dosyasını yanlış bağlamıştım. Uygulama default ayarlara düşüp kafamı karıştırmıştı.Hata mesajı net değildi,biraz uğraştırdı.
Küçük bir detay: Neyse uzatmayayım:doğru host yapısını kurarsanız caching mantığını test etmek çok daha kolay hâle geliyor.En çok da dependency injection sayesinde mock servislerle performans senaryosu yazmak rahatlıyor.
Maliyet,Operasyon ve Türkiye Gerçeği
Bunu Türkiye’deki şirketler açısından değerlendirirsek fiyat konusu boş geçilemez.Azure hizmetlerini TL bazında düşündüğünüzde küçük görünen farklar bütçe döneminde büyüyebiliyor.O yüzden “en hızlı çözüm” ile “toplam sahip olma maliyeti” aynı şey değil.
Açık konuşayım, birçok kurumda ilk soru teknik değil finansal oluyor:“Bu ayrı servis bize ekstra yönetim yükü çıkarır mı?” Eğer ekibiniz küçükse,PostgreSQL üzerinde kalmak bazen gayet mantıklı olabilir.Ama yoğun trafik varsa veya global dağıtım planınız varsa Redis benzeri seçenekleri masaya koymak gerekir.
- Küçük ekipler için: mevcut PostgreSQL üstünden ilerlemek çoğu zaman yeterli olur.
- Büyük kurumlar için: ayrışmış cache altyapısı izleme ve ölçekleme açısından avantaj sağlar.
- Bütçe kısıtlıysa: önce ölçün,sonra genişletin.
- Sürekli değişen veride: kısa TTL + kontrollü invalidation düşünün.
Cache’in amacı her şeyi saklamak değil; doğru şeyi doğru süreyle yakın tutmak.
Dikkat Etmeniz Gereken Noktalar
Bir dakika,şunu da ekleyeyim:cache başarısını sadece latency düşüşüne bakarak ölçmeyin.Hit ratio düşükse belki de yanlış şeyi cache’liyorsunuzdur.Ya da TTL fazla kısadır,veri sürekli kaçıyordur.Kağıt üstünde süper görünen çözüm pratikte beklediğiniz kadar iyi olmayabilir.
Ayrıca güvenlik kısmını hafife almayın. Secret yönetimi düzgün olmazsa connection string sızar,sonra geçmiş olsun. Benzer hatayı eski bir projede görmüştüm; düz metin config yüzünden istemeden risk oluşmuştu. Sonradan Key Vault’a taşıdık ve rahatladık.
Peki hangi durumlarda hayal kırıklığı yaratır?
Eh, Eğer veri gerçekten sıcak değilse yanı nadiren okunuyorsa cache size fazla katkı sağlamaz. Hatta ek karmaşıklık getirir: Bu konuda dürüst olmak lazım:her probleme ilaç değil bu yapı. Bazen query optimizasyonu yapmak daha doğru olur.
Kod Mantığını Kafada Oturtmak İçin Mini Akış
// Basitleştirilmiş akış
1) İstek gelir
2) Önce in-memory kontrol edilir
3) Yoksa distributed cache kontrol edilir
4) Orada da yoksa kaynak veri çağrılır
5) Sonuç iki katmana yazılır
6) Süre ölçülür
// Mantık özeti:
Hızlı yol -> Bellek
Orta yol -> Dağıtık katman
Yavaş yol -> Kaynak sistem
Böyle baktığınızda konu aslında çok zor görünmüyor: Ama detaylarda boğulmak kolaydır: Bilhassa de serialization formatı,TTL politikası,eşzamanlı erişimler… bunların hepsi küçük görünür. Toplam etkisi büyüktür. Logosoft’ta yürüttüğümüz birkaç Azure geçişinde bunu defalarca yaşadık;küçük ayarlar büyük fark yaratabiliyor.
Sıkça Sorulan Sorular
.NET’te distributed caching neden gerekli?
Aynı veriye sürekli erişilen durumlarda uygulamanın hızını ciddi ölçüde artırıyor. Yanı veritabanına giden yükü azaltıyor, yanıt süreleri de buna göre iyileşiyor. Peki, en çok da mikroservislerde farkı hemen hissediyorsunuz — bence bu tek başına yeterli bir sebep.
PostgreSQL ile caching yapmak Redis yerine geçer mi?
Açık konuşayım, Aslında bazen evet, ama genelde değil. Hani elinizde zaten bir PostgreSQL altyapısı varsa başlangıç için gayet iyi bir seçenek. Ama çok yüksek performans ihtiyacınız varsa, açıkçası Redis hâlâ rakipsiz.
Caching yaparken en büyük hata nedir?
Yanlış veriyi ya da yanlış süreyle cache’lemek. Eski veri göstermek kullanıcı deneyimini fena hâlde bozabiliyor. Bu yüzden — tecrübeme göre — invalidation stratejisi en az caching’in kendisi kadar önemli, bunu atlamamak lazım.
Küçük ekipler bu modeli kullanmalı mı?
Evet, yanı trafik düzenliyse ve işleri sade tutmak istiyorsanız mantıklı bir seçenek. Ama bence önce ölçün, sonra genişletin. Erken aşamada fazla kompleks bir mimariye gitmenize gerek yok.
Kaynaklar ve İleri Okuma
- Orijinal Microsoft.NET Blog Yazısı
- ASP.NET Core Caching Overview — Microsoft Docs
- Azure Database for PostgreSQL Belgeleri — Microsoft Learn
- dotnet/extensions GitHub Deposu
- Azure DevOps Git Policy Yönetimi: 10x Hız Kazanmanın Yolu
- Kubernetes v1.36 Controller Staleness: Bayat Cache Sorunu Bitti mi?
- .NET 10’da API Versiyonlama ve OpenAPI Entegrasyonu: Pratik Rehber
Bu içerik işinize yaradı mı?
Benzer içerikleri kaçırmamak için beni sosyal medyada takip edin.









Yorum gönder