Connection Pooling Nedir? Veritabanı Bağlantı Havuzu
Her veritabanı sorgusunda yeni bağlantı mı açıyorsunuz? "Too many connections" hatası mı alıyorsunuz? Connection Pooling ile bağlantıları yeniden kullanın, performansı 10x artırın.
Problem
Veritabanı bağlantısı oluşturmak pahalıdır:
Bağlantı oluşturma süreci:
1. TCP handshake (~1ms)
2. SSL handshake (~5ms)
3. Auth (kullanıcı/şifre) (~2ms)
4. Sorgu (~1ms)
5. Bağlantı kapatma (~1ms)
──────────────────────────────
Toplam: ~10ms (sorgu sadece 1ms!)
Pool olmadan her istek için bu süreç tekrarlanır. 1000 eşzamanlı istek = 1000 bağlantı denemesi → veritabanı çöker.
Connection Pool Nasıl Çalışır?
Uygulama başladığında:
Pool: [conn1] [conn2] [conn3] [conn4] [conn5] (hazır)
İstek geldiğinde:
İstek 1 → pool'dan conn1 al → sorgu → conn1'i geri ver
İstek 2 → pool'dan conn2 al → sorgu → conn2'i geri ver
İstek 3 → pool'dan conn3 al → sorgu → conn3'i geri ver
Tüm bağlantılar doluysa:
İstek 6 → bekle... → bağlantı serbest kaldığında al
Node.js + PostgreSQL Pool
import { Pool } from 'pg';
const pool = new Pool({
host: 'localhost',
database: 'myapp',
user: 'admin',
password: 'secret',
min: 5, // Minimum bağlantı
max: 20, // Maximum bağlantı
idleTimeoutMillis: 30000, // Boşta kalma süresi
connectionTimeoutMillis: 5000, // Bağlantı bekleme limiti
});
// Kullanım
async function getUser(id: number) {
const client = await pool.connect();
try {
const result = await client.query('SELECT * FROM users WHERE id = $1', [id]);
return result.rows[0];
} finally {
client.release(); // Bağlantıyı pool'a geri ver (kapatma!)
}
}
// Veya kısa yol
async function getOrders() {
const { rows } = await pool.query('SELECT * FROM orders LIMIT 100');
return rows;
}
Pool Boyutu Hesaplama
Formula
Optimal pool boyutu = (çekirdek_sayısı * 2) + disk_sayısı
Örnek (4 çekirdek, 1 SSD):
(4 * 2) + 1 = 9 bağlantı
Dikkat Edilecekler
PostgreSQL max_connections: 100
5 uygulama instance'ı × pool_size her biri
Doğru: 5 × 20 = 100 ✅
Yanlış: 5 × 30 = 150 > 100 ❌ → "too many connections"
PgBouncer (Connection Pool Proxy)
Uygulama ile veritabanı arasına oturan bağımsız pool proxy'si:
┌─ PostgreSQL (max 100)
App1 (pool: 20) ─┐ │
App2 (pool: 20) ─┤─ PgBouncer ─┤
App3 (pool: 20) ─┘ │
60 uygulama bağlantısı └─ 20 DB bağlantısına düşürülür
# pgbouncer.ini
[databases]
myapp = host=127.0.0.1 dbname=myapp
[pgbouncer]
pool_mode = transaction # Her transaction için bağlantı
max_client_conn = 1000
default_pool_size = 20
Pool Modları
| Mod | Açıklama | Kullanım | |-----|----------|----------| | Session | İstemci bağlantı boyunca aynı DB bağlantısı | Prepared statements | | Transaction | Her transaction için farklı bağlantı | Genel kullanım | | Statement | Her sorgu için farklı bağlantı | Basit sorgular |
Diğer Pool Araçları
| Araç | Dil/Platform | Öne Çıkan | |------|-------------|-----------| | HikariCP | Java | En hızlı Java pool | | PgBouncer | PostgreSQL | Harici pool proxy | | ProxySQL | MySQL | MySQL load balancer + pool | | Prisma | Node.js | ORM ile entegre pool | | SQLAlchemy | Python | QueuePool, NullPool |
Best Practices
- Pool boyutunu gereğinden büyük yapmayın — Fazla bağlantı = fazla bellek
- Bağlantıyı her zaman geri verin —
finallybloğundarelease()çağırın - Health check — Bozuk bağlantıları tespit edip çıkarın
- Connection leak tespiti — Geri verilmeyen bağlantıları izleyin
- Serverless dikkat — Lambda'da pool boyutunu düşük tutun
- Monitoring — Aktif, boşta ve bekleyen bağlantı sayılarını izleyin
Sonuç
Connection Pooling, veritabanı performansının en düşük maliyetli optimizasyonudur. Doğru pool boyutuyla istek sürelerini düşürür, veritabanı yükünü azaltır ve "too many connections" hatalarını önlersiniz.
Connection pooling ve veritabanı optimizasyonunu LabLudus platformunda öğrenin.