Veritabanı Performansı & Kaynak Yönetimi 3 dk okuma 21 okunma

Connection Pooling ve Performans İyileştirmeleri

Connection pooling, veritabanı bağlantılarını yeniden kullanarak her istekte yeni bağlantı açma maliyetini ortadan kaldırır ve uygulama ölçeklenebilirliğini artırır. Ancak yanlış yapılandırılmış havuzlar; bağlantı sızıntısı, havuz tükenmesi (pool starvation) ve timeout sorunlarına yol açar. Bu yazıda .NET'te pooling mekanizması, doğru boyutlandırma, bağlantı yaşam döngüsü ve performans ipuçları ele alınır.

Connection Pooling ve Performans İyileştirmeleri

Connection Pooling ve Performans İyileştirmeleri

Veritabanı bağlantısı açmak, TCP el sıkışması, kimlik doğrulama ve bellek tahsisi gibi maliyetli işlemleri beraberinde getirir. Her istekte bu maliyeti ödemek, yüksek trafikli uygulamalarda performansı ciddi şekilde düşürür. Connection pooling (bağlantı havuzu), açılan bağlantıları kapatmak yerine havuza geri göndererek yeniden kullanılmalarını sağlar; böylece bağlantı kurulum maliyeti yalnızca ilk seferde ödenir.


1. Connection Pooling Nasıl Çalışır?

Bir uygulama Open() çağrısı yaptığında, .NET önce ilgili connection string için bir havuz olup olmadığını kontrol eder. Havuzda boş bir bağlantı varsa, doğrudan o verilir; yoksa yeni bir fiziksel bağlantı açılır. Uygulama Close() veya Dispose() çağırdığında ise bağlantı gerçekten kapatılmaz, havuza geri döner .

Temel Kavramlar:

Kavram Açıklama
Min Pool Size Havuzda her zaman tutulan minimum bağlantı sayısı
Max Pool Size Havuzun büyüyebileceği maksimum bağlantı sayısı (varsayılan: 100)
Connection Timeout Havuzdan bağlantı beklerken geçecek maksimum süre (varsayılan: 15 saniye)
Connection Lifetime Bir bağlantının havuzda kalabileceği maksimum süre

Kritik Kural: Havuzlar connection string bazında oluşturulur. Aynı veritabanına farklı connection string'lerle bağlanmak, ayrı havuzlar oluşturur ve kaynak israfına yol açar.


2. Havuz Tükenmesi (Pool Starvation): En Sık Karşılaşılan Sorun

Havuzdaki tüm bağlantılar kullanımdayken yeni bir talep geldiğinde, uygulama bağlantı boşalana kadar bekler. Bekleme süresi Connection Timeout değerini aşarsa şu hata alınır:

"Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool."

Nedenleri:

  • Bağlantı sızıntısı (leak): Dispose() veya Close() çağrılmamış bağlantılar havuza dönmez.

  • Uzun süren sorgular: Bir bağlantı saatlerce meşgul kalıyorsa, diğer istekler bekler.

  • Yetersiz havuz boyutu: Eşzamanlı istek sayısı Max Pool Size'ı aşıyorsa.

  • Aşırı büyük Max Pool Size: Görünüşte çözüm gibi görünse de, veritabanı sunucusunun bağlantı limitini aşarak yeni sorunlara yol açar.

Çözüm Öncelikleri:

  1. Bağlantıların her zaman using bloğu içinde açılması (en kritik adım).

  2. Uzun süren sorguların optimize edilmesi.

  3. Havuz boyutunun, eşzamanlı istek sayısına ve veritabanı kapasitesine göre ayarlanması.


3. .NET'te Doğru Kullanım

Doğru Kullanım (using ile):

csharp

public async Task<Order> GetOrderAsync(int id)
{
    await using var connection = new SqlConnection(_connectionString);
    await connection.OpenAsync();
    // Sorgu çalıştır...
    return order;
} // Bağlantı otomatik olarak havuza döner

Yanlış Kullanım (sızıntı):

csharp

var connection = new SqlConnection(_connectionString);
await connection.OpenAsync();
// Dispose çağrılmazsa bağlantı havuza dönmez!

EF Core'da Pooling:
EF Core, DbContext yaşam döngüsünü DI ile yönetir; Scoped olarak kaydedilen context, her istek sonunda otomatik dispose edilir ve bağlantı havuza döner. Ancak DbContextPool kullanmak, context nesnesinin kendisini de yeniden kullanarak ek kazanç sağlar :

csharp

builder.Services.AddDbContextPool<AppDbContext>(options =>
    options.UseSqlServer(connectionString));

4. Performans İyileştirme İpuçları

İpucu Açıklama
Min Pool Size ayarlayın Trafik ani artışlarında havuzun hazır bağlantıya sahip olmasını sağlar; ilk isteklerdeki gecikmeyi azaltır.
Max Pool Size'ı abartmayın Veritabanı sunucusunun kapasitesini aşan havuz, bağlantı hatalarına ve kaynak tükenmesine yol açar.
Bağlantıları kısa tutun Bağlantıyı aç, sorguyu çalıştır, kapat. Uzun süre açık tutmak, diğer isteklerin erişimini engeller.
Connection Lifetime kullanın Yük dengeleme (load balancing) ortamlarında, bağlantıların belirli süre sonra yenilenmesini sağlar.
Async API'leri kullanın OpenAsync, ExecuteReaderAsync gibi asenkron metotlar, thread'i bloke etmeden bağlantı yönetimini sağlar.

5. İzleme ve Tanılama

Havuzun sağlığını izlemek için .NET'te çeşitli sayaçlar mevcuttur:

Sayaç Anlamı
Pooled Connections Havuzdaki toplam bağlantı sayısı
Active Connections Şu anda kullanımda olan bağlantı sayısı
Free Connections Havuzda boş bekleyen bağlantı sayısı
Connection Timeouts Zaman aşımına uğrayan bağlantı talepleri

Bu metrikler, dotnet-counters veya Application Insights gibi araçlarla izlenebilir. Aktif bağlantı sayısı sürekli Max Pool Size'a yakınsa, havuz tükenmesi riski vardır.


6. En İyi Pratikler

Pratik Açıklama
Her zaman using kullanın Bağlantıların istisna durumunda bile havuza dönmesini garanti eder.
Connection string'i standartlaştırın Aynı veritabanına farklı string'lerle bağlanmak, ayrı havuzlar oluşturur.
Bağlantı süresini kısa tutun "Aç, kullan, kapat" prensibi; uzun süreli bağlantılar havuzu tüketir.
Timeout değerlerini gözden geçirin Varsayılan 15 saniye çoğu senaryo için uygundur; ancak yavaş veritabanlarında artırılabilir.
Havuz metriklerini izleyin Aktif/boş bağlantı oranı, tükenme riskinin erken göstergesidir.

Sonuç

Connection pooling, veritabanı performansının görünmez kahramanıdır: doğru yapılandırıldığında, bağlantı maliyetini ortadan kaldırır ve uygulamanın ölçeklenebilirliğini artırır. Ancak yanlış kullanıldığında, havuz tükenmesi ve timeout hatalarıyla uygulamayı çökertir. En kritik kural, bağlantıların her zaman using bloğu içinde açılması ve kısa süreli tutulmasıdır. Havuz boyutunu veritabanı kapasitesine göre ayarlamak ve metrikleri izlemek, sorunları kullanıcılar fark etmeden önce tespit etmenizi sağlar. Unutmayın: En iyi bağlantı, ihtiyaç duyulduğunda hazır olan; en kötü bağlantı ise asla havuza dönmeyendir.

Tüm yazılar Soru ya da yorumun mu var? Yaz