Gereksinimler ve Ön Hazırlık
Uygulamaya başlamadan önce sisteminizde gerekli araçların kurulu olduğundan emin olmalısınız. Redis, verileri RAM üzerinde tuttuğu için disk tabanlı veritabanlarına göre çok daha hızlıdır.
- Node.js (LTS sürümü, 2026 itibarıyla 22.x veya üzeri önerilir).
- Redis Server (Yerel makinede veya Docker konteynerinde).
- NPM (Node Package Manager) veya Yarn.
- Temel Express.js bilgisi.
Redis'i yerel ortamınızda Docker ile hızlıca başlatmak için aşağıdaki komutu terminalinizde çalıştırabilirsiniz:
docker run --name redis-cache -p 6379:6379 -d redis
Bu komut, 6379 portunda bir Redis örneği başlatır ve uygulamanızın bu port üzerinden Redis ile haberleşmesini sağlar.
Redis İstemcisini Node.js Projesine Dahil Etme
Node.js uygulamalarında Redis ile iletişim kurmak için redis kütüphanesini kullanacağız. Bu kütüphane, Redis komutlarını asenkron (Promise tabanlı) bir şekilde çalıştırmamıza olanak tanır.
npm install redis
Kurulum tamamlandıktan sonra, Redis bağlantısını yöneten bir modül oluşturalım. Bu, uygulamanızın her yerinde bağlantı açıp kapatmak yerine merkezi bir yönetim sağlar.
const redis = require('redis');
const client = redis.createClient({
url: 'redis://localhost:6379'
});
client.on('error', (err) => console.log('Redis Bağlantı Hatası:', err));
async function connectRedis() {
await client.connect();
console.log('Redis sunucusuna başarıyla bağlandı.');
}
connectRedis();
module.exports = client;
Burada createClient fonksiyonu ile bağlantı yapılandırmasını tanımladık. client.connect() ile bağlantıyı başlattık. Hata yönetimi için on('error') dinleyicisini eklemek, uygulamanın çökmesini engellemek adına kritiktir.
Önbellekleme Stratejisi: Cache-Aside Modeli
Önbellekleme sistemlerinde en yaygın kullanılan yöntem Cache-Aside (Kenara Bırak) modelidir. Bu modelde uygulama, önce veriyi Redis'te arar. Eğer veri varsa (Cache Hit), doğrudan döner. Eğer yoksa (Cache Miss), veritabanından veriyi alır, Redis'e yazar ve kullanıcıya döner.
async function getUserData(userId) {
const cacheKey = `user:${userId}`;
// 1. Redis'te kontrol et
const cachedData = await client.get(cacheKey);
if (cachedData) {
return JSON.parse(cachedData);
}
// 2. Redis'te yoksa veritabanından çek (Örnek fonksiyon)
const userData = await database.findUserById(userId);
// 3. Redis'e kaydet (1 saatlik TTL - Time To Live)
await client.setEx(cacheKey, 3600, JSON.stringify(userData));
return userData;
}
Yukarıdaki kodda setEx metodu kullanılmıştır. Bu metod, veriyi kaydederken aynı zamanda bir yaşam süresi (TTL) belirler. 3600 saniye sonra bu veri Redis'ten otomatik silinir, böylece veritabanı güncellendiğinde eski verinin kalması engellenir.
Önbellekleme Yöntemlerinin Karşılaştırılması
| Yöntem | Avantaj | Dezavantaj |
|---|---|---|
| Cache-Aside | Basit, veritabanı ile uyumlu | İlk sorguda gecikme (Cache Miss) |
| Write-Through | Veri her zaman tutarlı | Yazma işlemlerinde yavaşlama |
| Refresh-Ahead | Sıfır gecikme | Karmaşık yapı, gereksiz kaynak kullanımı |
Veri Tutarlılığı ve TTL Yönetimi
Önbellekleme sistemindeki en büyük zorluk, veritabanındaki veri değiştiğinde önbellekteki verinin güncel kalmasıdır. Buna Cache Invalidation denir. Veri güncellendiğinde, ilgili anahtarı Redis'ten silmek en güvenli yoldur.
async function updateUserData(userId, newData) {
// 1. Veritabanını güncelle
await database.updateUser(userId, newData);
// 2. Redis'teki eski veriyi geçersiz kıl (sil)
await client.del(`user:${userId}`);
}
Bu yaklaşım, veritabanı ve önbellek arasındaki tutarsızlığı minimize eder. Silme işlemi, bir sonraki okuma isteğinde verinin veritabanından tekrar çekilip güncel haliyle önbelleğe alınmasını sağlar.
Güvenlik Uyarısı: Redis sunucunuzu asla dış dünyaya (public internet) doğrudan açmayın. Redis varsayılan olarak kimlik doğrulama gerektirmeyebilir; üretim ortamında mutlaka güçlü bir parola (requirepass) kullanın ve sadece uygulama sunucunuzun IP adresinden erişime izin verin.
Performans Testi ve Debug İpuçları
Sisteminizi kurduktan sonra performans artışını ölçmek için console.time ve console.timeEnd komutlarını kullanabilirsiniz. Ayrıca Redis tarafında MONITOR komutu ile gelen sorguları anlık izleyebilirsiniz.
console.time('SorguSuresi');
const data = await getUserData(123);
console.timeEnd('SorguSuresi');
Eğer SorguSuresi ilk istekte 200ms, ikinci istekte 5ms çıkıyorsa, önbellekleme sisteminiz başarıyla çalışıyor demektir.
Sıkça Sorulan Sorular
Redis ve Memcached arasındaki fark nedir?
Redis, sadece basit anahtar-değer çiftlerini değil; liste, set, hash ve sıralı set gibi karmaşık veri yapılarını da destekler. Ayrıca Redis'in veriyi diske kalıcı olarak yazma özelliği vardır, bu da onu sadece önbellek değil, bir veritabanı olarak da kullanabilmenizi sağlar.
Önbellek ne zaman temizlenmelidir?
Veri güncellendiğinde (update/delete) veya verinin geçerlilik süresi (TTL) dolduğunda temizlenmelidir. Çok sık değişen veriler için kısa TTL süreleri, nadir değişen veriler için uzun TTL süreleri tercih edilmelidir.
Redis sunucusu çökerse ne olur?
Uygulamanızda hata yönetimi (try-catch) bloğu kullanıyorsanız, Redis'e ulaşılamadığında veritabanına doğrudan sorgu atarak uygulamanın çalışmaya devam etmesini sağlayabilirsiniz.
JSON verisi Redis'te nasıl saklanır?
Redis verileri string olarak saklar. Bu nedenle nesnelerinizi JSON.stringify() ile stringe çevirip kaydetmeli, okurken JSON.parse() ile tekrar nesneye dönüştürmelisiniz.
Üretim ortamında Redis için ne kadar RAM gerekir?
Bu, önbelleğe alacağınız verinin boyutuna bağlıdır. Redis, RAM tabanlı olduğu için verilerin toplam boyutunun, sunucunuzdaki boş RAM miktarından az olması gerekir. Redis'in "eviction" (eski veriyi silme) politikalarını (LRU - Least Recently Used) yapılandırarak sınırlı RAM ile büyük veri setlerini yönetebilirsiniz.
Redis İle İleri Seviye Veri Yapıları ve Kullanım Senaryoları
Redis sadece basit anahtar-değer (key-value) çiftlerini saklamakla kalmaz; karmaşık veri yapılarını kullanarak uygulamanızın performansını daha da yukarı çekmenize olanak tanır. Özellikle Hash ve Sorted Set yapıları, önbellekleme stratejilerinde verimliliği artırır.
Hash Yapısı ile Nesne Bazlı Önbellekleme
Büyük JSON nesnelerini tek bir string olarak saklamak yerine, Redis Hash yapısını kullanmak, nesnenin sadece belirli alanlarını güncellemeniz gerektiğinde tüm veriyi tekrar serialize etme zorunluluğunu ortadan kaldırır.
// Bir kullanıcı profilini Hash olarak kaydetme
const redis = require('redis');
const client = redis.createClient();
async function cacheUserProfile(userId, userData) {
// HSET komutu ile nesne alanlarını ayrı ayrı saklayabiliriz
await client.hSet(`user:${userId}`, {
name: userData.name,
email: userData.email,
lastLogin: Date.now().toString()
});
// TTL belirleyerek verinin ömrünü yönetin
await client.expire(`user:${userId}`, 3600);
}
Sorted Set ile "En Çok Okunanlar" Listesi
Uygulamanızda en popüler ürünleri veya son erişilen içerikleri takip etmek istiyorsanız, Sorted Set (ZSET) yapısı idealdir. Her öğeye bir skor atayarak verileri otomatik olarak sıralı tutabilirsiniz.
// Bir içeriğin görüntülenme sayısını artırma
async function incrementViewCount(articleId) {
// ZINCRBY ile skor (görüntülenme) artırılır
await client.zIncrBy('popular_articles', 1, articleId);
}
// En popüler 5 içeriği getirme
async function getTopArticles() {
// ZREVRANGE ile en yüksek skorlu öğeleri alıyoruz
const topArticles = await client.zRange('popular_articles', 0, 4, {
REV: true
});
return topArticles;
}
Üretim Ortamında Redis İzleme ve Hata Yönetimi
Redis'in sağlıklı çalıştığından emin olmak için sadece kod yazmak yeterli değildir; çalışma zamanı metriklerini izlemek ve bağlantı hatalarını yönetmek kritik öneme sahiptir.
Bağlantı Dayanıklılığı (Resilience)
Redis sunucusu geçici olarak erişilemez olduğunda uygulamanızın çökmesini engellemek için "Circuit Breaker" mantığı veya basit bir hata yakalama mekanizması kullanmalısınız.
client.on('error', (err) => {
console.error('Redis Bağlantı Hatası:', err);
});
async function getCachedData(key) {
try {
return await client.get(key);
} catch (error) {
console.warn('Redis erişilemiyor, veritabanına yönlendiriliyor...');
// Redis devre dışıysa doğrudan veritabanı sorgusuna düş
return await fetchFromDatabase(key);
}
}
Performans İzleme İpuçları
- Slowlog Kullanımı:
SLOWLOG GETkomutu ile Redis tarafında çok uzun süren sorguları tespit edin. - Memory Eviction:
INFO memorykomutu ile Redis'in bellek kullanımını takip edin. Eğer bellek doluyorsamaxmemory-policyayarını (örneğin:allkeys-lru) gözden geçirin. - Bağlantı Havuzu: Node.js tarafında bağlantılarınızı sürekli açıp kapatmak yerine, bağlantı havuzu (connection pooling) mantığıyla çalışan kütüphaneleri tercih edin.
Not: Üretim ortamında Redis bağlantılarını her zaman bir ortam değişkeni üzerinden yönetin ve REDIS_URL gibi hassas bilgileri asla kod içerisinde hard-coded olarak bırakmayın.
Sonuç
Node.js uygulamalarınızda Redis kullanarak önbellekleme yapmak, veritabanı yükünü azaltmanın ve kullanıcı deneyimini iyileştirmenin en etkili yoludur. Bu rehberde, Cache-Aside modelini, verinin nasıl geçersiz kılınacağını ve Redis ile nasıl güvenli bir bağlantı kurulacağını öğrendiniz. Bir sonraki adım olarak, Redis'in Pub/Sub mekanizmasını inceleyerek gerçek zamanlı bildirim sistemleri üzerine çalışabilir veya Redis Cluster yapısı ile uygulamanızı yatayda nasıl ölçekleyeceğinizi araştırabilirsiniz.
Sorumluluk Reddi: Bu makalede paylaşılan kod örnekleri eğitim amaçlıdır. Üretim ortamına geçmeden önce Redis yapılandırmanızı, ağ güvenliğinizi ve veri gizliliği politikalarınızı (KVKK/GDPR) gözden geçiriniz. Uygulamanızın güvenlik açıklarından geliştirici sorumludur.


Yorumlar (0)
Yorum Yaz