Redis'in Temel Çalışma Mantığı
Redis, sık dönen sorguların sonucunu RAM’de tutar. Bir kullanıcı ürün listesini açtığında MySQL ya da PostgreSQL arka planda SELECT çalıştırır; veri diskte okunur, işlenir, ekrana döner. Aynı listeyi binlerce kişi aynı anda açtığında yük büyür. Redis burada sonucu doğrudan bellekten verir; ikinci istekte veritabanına uğramayız.
Kelime karşılığı "Remote Dictionary Server" olan Redis, anahtar-değer mantığıyla çalışır. Bir veriye anahtarla ulaşırız; değer metin, sayı, liste, hash ya da set olabilir. Biz projelerimizde çoğu zaman JSON’u string olarak saklıyoruz; PHP tarafında tekrar diziye çevirmek tek satır sürüyor.
Veritabanı Sorgusu ile Bellek Sorgusu Arasındaki Fark
Bir e-ticaret sitesinde 50 bin ürün içeren kategori listesini filtrelemek için yazdığımız sorgu vardı. İndeksler düzgün kurulsa bile bu sorgu ortalama 180 milisaniye sürdü. Aynı sonuç Redis’e taşındığında süre 2 milisaniyenin altına indi. Ekranda fark edilmesi zor, sunucu tarafında ise çok net.
| İşlem | Kaynak | Ortalama Süre | 1000 Eşzamanlı İstek Altında |
|---|---|---|---|
| Kategori listesi sorgusu | MySQL (disk) | 180 ms | Veritabanı CPU %90 üstünde |
| Aynı liste, cache'ten | Redis (RAM) | 1,8 ms | Veritabanına hiç istek gitmiyor |
| Ürün detay sayfası | PostgreSQL (disk) | 45 ms | Bağlantı havuzu doluyor |
| Aynı ürün, cache'ten | Redis (RAM) | 0,9 ms | Bağlantı havuzu boş |
Tablo hızdan çok başka bir şeyi gösteriyor: yük nereye biniyor. Trafik arttığında darboğaz çoğu zaman sorgunun kendisi değil, bağlantı sayısı ve disk I/O oluyor. Redis bu baskıyı alıyor; veritabanını büyütmeden daha fazla isteği çevirebiliyoruz.
Hangi Senaryolarda Cache Gerçekten İşe Yarıyor
Yüksek Trafikli Listeleme ve Kategori Sayfaları
Haber sitelerinde anasayfa, e-ticarette kategori sayfası, emlak platformlarında ilan listesi... Aynı içerik farklı kullanıcılar tarafından benzer parametrelerle tekrar tekrar açılıyor. İçerik her istekte değişmiyorsa cache net avantaj sağlıyor. Biz bu sayfalarda TTL’i çoğunlukla 60 saniye ile 10 dakika arasında tutuyoruz; veri seyrek değişiyorsa süreyi uzatıyoruz.
Arama ve Filtreleme Sorguları
"iphone 15", "kadın ayakkabı 38 numara" gibi aramalar gün içinde defalarca geliyor. Aynı sorguyu yeniden çalıştırmak yerine sonucunu cache’e almak, arama motorunun ve veritabanının yükünü azaltıyor. Elasticsearch kullandığımız yapılarda da bu rahatlama belirgin oluyor.
Oturum, Sepet ve Rate Limiting Verileri
Oturum bilgisi, sepet içeriği, API istek sayacı... Bunlar zaten geçici veri. RAM’de durmaları daha doğal; diskte kalıcı olmaları gerekmiyor. Bir kullanıcı sepetine üç ürün eklediğinde o üç kaydın sabit diske taşınması bize gereksiz iş yükü çıkarıyor.
Cache-Aside Yaklaşımı: Projelerde Kurduğumuz Akış
En sık kullandığımız model cache-aside. Önce Redis’e bakıyoruz; veri varsa oradan dönüyoruz. Yoksa veritabanına gidiyor, sonucu Redis’e yazıyor, sonra kullanıcıya gönderiyoruz. PHP tarafında phpredis ile akış sade kalıyor:
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$cacheKey = "kategori:elektronik:sayfa:1";
$veri = $redis->get($cacheKey);
if ($veri === false) {
// Cache boş, veritabanından çekiyoruz
$sonuc = $pdo->query("SELECT * FROM urunler WHERE kategori_id = 3 LIMIT 20")->fetchAll();
$veri = json_encode($sonuc);
$redis->setex($cacheKey, 300, $veri); // 300 saniye yaşam süresi
} else {
$sonuc = json_decode($veri, true);
}
setex veriyi yazarken süreyi de ekliyor. Süre bitince Redis kaydı kendi siliyor; ekstra temizlik kodu yazmıyoruz.
Cache Stratejilerinin Karşılaştırması
Biz saha projelerinde cache-aside dışında write-through ve write-behind modellerine de rastlıyoruz. Seçim, okuma-yazma dengesine göre değişiyor. Tek doğru yok.
| Strateji | Nasıl Çalışır | Artısı | Eksisi |
|---|---|---|---|
| Cache-Aside | Veri istendiğinde cache'e bakılır, yoksa DB'den çekilip cache'e yazılır | Basit kurulum, sadece okunan veri cache'lenir | İlk istek her zaman yavaş (cache miss) |
| Write-Through | Her yazma işleminde veri hem DB'ye hem cache'e aynı anda yazılır | Cache her zaman güncel, cache miss az | Yazma işlemi yavaşlar, kullanılmayan veri de cache'de tutulur |
| Write-Behind | Veri önce cache'e yazılır, DB'ye yazma işlemi arka planda gecikmeli yapılır | Yazma çok hızlı | Sunucu çökerse yazılmamış veri kaybolabilir |
Çoğu e-ticaret ve içerik yönetim projesinde cache-aside kullanıyoruz. Çünkü okuma sayısı yazmadan fazla oluyor. Write-behind ise bizde daha çok log ve metrik gibi kaybı tolere edilebilen işlerde yer buluyor.
Cache Anahtarı (Key) Tasarımı
Redis’te her veri bir anahtara bağlıdır; anahtar düzeni büyüyen projede işin yarısıdır. Rastgele isim yerine namespace kullanmak hata ayıklamayı da toplu silmeyi de kolaylaştırıyor. Biz genellikle şu biçimi tercih ediyoruz:
modul:kaynak:parametre— örnek:urun:liste:kategori3:sayfa1kullanici:{id}:sepet— kullanıcıya özel veriler için id doğrudan anahtarın içindearama:{md5(sorgu)}— dinamik arama sorgularında parametre kombinasyonu hash'lenerek kısaltılıyor
Mesela bir kategori güncellendiğinde urun:liste:kategori3:* desenine uyan anahtarları topluca silmek istiyoruz. Bunun için KEYS yerine SCAN kullanıyoruz; KEYS tüm kümede tur atıp sunucuyu zorlayabiliyor, SCAN ise parça parça ilerliyor.
TTL Süresi ve Veri Bayatlama Sorunu
TTL, yani verinin cache’te kalma süresi, her proje için aynı olmuyor. Süre çok kısa olursa cache’in katkısı düşüyor; çok uzun olursa kullanıcı eski veri görmeye başlıyor. Fiyat ve stok için 30-60 saniye aralığı bizde iyi çalıştı. Kategori ve menü gibi daha sakin veri için ise 1-6 saat aralığı işe yaradı.
| Veri Türü | Önerilen TTL | Neden |
|---|---|---|
| Ürün stok/fiyat | 30-60 saniye | Sipariş anında yanlış fiyat gösterme riskini sınırlar |
| Kategori listesi | 5-15 dakika | İçerik nadiren değişir, trafik yükünü azaltır |
| Menü / statik sayfa | 1-6 saat | Değişiklik çok seyrek, uzun TTL sorun yaratmaz |
| Oturum verisi | Kullanıcı oturum süresiyle eşit | Oturum bitince veri de anlamını kaybeder |
| Arama sonucu | 1-5 dakika | Popüler sorgular sık tekrarlanır, kısa TTL yeterli |
Cache Geçersiz Kılma (Invalidation)
TTL’ye güvenmek her zaman yetmiyor. Panelden ürün fiyatı değiştiğinde müşterinin 5 dakika eski fiyatı görmesini göze alamayız. Bu yüzden yazma işleminden sonra ilgili anahtarı manuel siliyoruz:
// Ürün güncellendiğinde
$pdo->query("UPDATE urunler SET fiyat = 299 WHERE id = 42");
$redis->del("urun:detay:42");
$redis->del("urun:liste:kategori3:sayfa1");
Büyük yapılarda tek tek anahtar silmek yerine etiketleme kullanıyoruz. Bir kategoriye bağlı cache anahtarlarını aynı set içinde tutuyoruz; kategori değişince o set’in içindekileri döngüyle temizliyoruz. Takip etmesi daha kolay oluyor.
Bellek Yönetimi ve Eviction Politikaları
Redis’in belleği sınırsız değil; RAM dolunca neyin silineceğini maxmemory-policy belirliyor. Yanlış ayar, önemli veriyi erkenden silip önemsizi içeride tutabiliyor.
| Politika | Davranış | Uygun Olduğu Durum |
|---|---|---|
| allkeys-lru | En uzun süre kullanılmayan anahtarı siler | Genel amaçlı sorgu cache'i (bizim en çok tercih ettiğimiz) |
| allkeys-lfu | En az erişilen anahtarı siler | Erişim sıklığı belirgin farklıysa (popüler ürün vs nadir ürün) |
| volatile-lru | Sadece TTL'i olan anahtarlar arasında LRU uygular | TTL'siz kalıcı veri de aynı instance'da tutuluyorsa |
| noeviction | Bellek dolunca yeni yazma isteklerine hata döner | Redis kalıcı veri deposu olarak kullanılıyorsa |
Biz sorgu cache’i için çoğunlukla allkeys-lru kullanıyoruz. Çünkü veri kaybolsa da veritabanı arkada duruyor. Oturum ve sepet gibi daha hassas verilerde ayrı instance açıp noeviction ile çalıştırıyoruz.
Redis ile Memcached Karşılaştırması
Cache denince Memcached de masaya geliyor. İkisi RAM üzerinde çalışıyor; hedefleri aynı değil.
| Özellik | Redis | Memcached |
|---|---|---|
| Veri tipleri | String, list, hash, set, sorted set | Sadece string |
| Kalıcılık (persistence) | RDB ve AOF ile diske yazılabilir | Yok, sunucu kapanınca veri tamamen silinir |
| Çoğaltma (replication) | Master-replica ve Sentinel desteği var | Yerleşik replication yok |
| Çoklu iş parçacığı | Ana veri işleme tek thread, I/O multi-thread | Multi-thread |
| Kullanım alanı | Cache + oturum + kuyruk + sayaç | Sadece basit key-value cache |
Basit bir cache gerekiyorsa Memcached yeterli olabiliyor. Biz çoğu projede aynı Redis’i cache, oturum ve kuyruk için birlikte kullandığımızdan, tercihimiz genelde Redis oluyor.
Cache Stampede Sorunu ve Kilitleme Çözümü
Çok istek alan bir anahtarın TTL’i dolduğunda aynı anda binlerce istek veritabanına yüklenebilir. Cache boş kalırsa herkes aynı kapıya dayanıyor. Biz bu durumu cache stampede diye izliyoruz. Kısa süreli bir kilit mekanizmasıyla engelliyoruz:
$lockKey = "lock:urun:liste:kategori3";
$veri = $redis->get($cacheKey);
if ($veri === false) {
if ($redis->set($lockKey, 1, ['NX', 'EX' => 5])) {
// Kilidi biz aldık, veritabanına gidip cache'i biz dolduruyoruz
$sonuc = $pdo->query("SELECT ...")->fetchAll();
$redis->setex($cacheKey, 300, json_encode($sonuc));
$redis->del($lockKey);
} else {
// Kilit başka bir istekte, kısa süre bekleyip cache'i tekrar okuyoruz
usleep(50000);
$veri = $redis->get($cacheKey);
$sonuc = json_decode($veri, true);
}
}
NX anahtarın yalnızca yoksa yazılmasını sağlıyor. Böylece binlerce isteğin arasından biri kilidi alıyor, diğerleri kısa bir beklemeden sonra dolan cache’i okuyor.
PHP Projelerinde Kurulum ve Bağlantı Yönetimi
PHP tarafında Redis’e bağlanmak için iki yaygın seçenek var: phpredis eklentisi ve Predis kütüphanesi. Yüksek trafikte biz phpredis’i kullanıyoruz; kurulum doğrudan sunucuya yapılıyor ve performansı daha iyi oluyor:
sudo apt-get install php-redis
sudo systemctl restart php-fpm
Her istekte yeni bağlantı açmak yerine kalıcı bağlantı kullanmak da fark yaratıyor:
$redis = new Redis();
$redis->pconnect('127.0.0.1', 6379, 2.5);
pconnect sayesinde PHP-FPM worker yeniden kullanıldığında bağlantı açık kalıyor. TCP el sıkışması her seferinde tekrar yaşanmıyor.
İzleme ve Performans Ölçümü
Kurulumun işe yarayıp yaramadığını ölçmeden bırakmıyoruz. Redis’in INFO çıktısı hit rate hesabı için gerekli sayıları veriyor:
redis-cli INFO stats | grep keyspace
# keyspace_hits:184320
# keyspace_misses:6210
Hit rate şu formülle bulunuyor: hits / (hits + misses). Sağlıklı bir cache katmanında oran genellikle %90 üstüne çıkıyor. %70 altına düşüyorsa TTL kısa kalmış olabilir ya da anahtar yapısı gereğinden fazla dağılmıştır.
| Metrik | Komut | Ne Anlatır |
|---|---|---|
| Hit rate | INFO stats | Cache'in ne kadar işe yaradığını gösterir |
| used_memory | INFO memory | Redis'in kullandığı toplam RAM miktarı |
| connected_clients | INFO clients | Aktif bağlantı sayısı, sızıntı (leak) tespitinde işe yarar |
| evicted_keys | INFO stats | Bellek dolduğu için silinen anahtar sayısı |
Redis'i Yanlış Kullanmanın Getirdiği Riskler
Redis’i her veri için açmak doğru değil. Sık değişen finansal veriyi uzun TTL ile cache’lemek kullanıcıya yanlış bakiye gösterebilir. Sadece TTL’e güvenip invalidation kurmamak da güncelleme sonrası kısa süreli tutarsızlık üretir. Tüm veritabanını Redis’e taşımaya çalışmak ise başka bir hata; Redis hız katmanı olarak iyi çalışır, ana depo olarak değil.
Bir de büyük JSON nesneleri var. Bellek takibini yapmadan 50 bin satırlık raporu tek anahtar altında saklarsak sunucu zorlanır. Biz bu durumda sayfalama yapıp her sayfayı ayrı anahtarda tutuyoruz; daha dengeli oluyor.
Ne Zaman Redis Kullanmayı Tercih Etmiyoruz
Trafiği düşük, günde birkaç yüz ziyaretçisi olan bir kurumsal sitede Redis çoğu zaman gereksiz karmaşıklık ekliyor. Veritabanı zaten milisaniyeler içinde dönüyor. Bir başka sınır da şu: Her istekte parametre neredeyse tamamen değişiyorsa cache isabet oranı düşüyor, yazma-okuma maliyeti artıyor. Biz önce indekslere bakıyoruz, sorgu planını inceliyoruz, tekrar eden okuma var mı ölçüyoruz. Tekrar varsa cache ekliyoruz; yoksa veritabanını toparlamak daha doğru oluyor.
Redis Persistence: RDB ve AOF ile Veri Kalıcılığı
Redis’i geçici cache olarak kullansak da sunucu yeniden başladığında belleğin sıfırlanması bazı projelerde ilk dakikaları ağırlaştırıyor. 500 bin ürünlük bir kategori cache’i boşalınca ilk istekler doğrudan veritabanına düşüyor. Biz bu yüzden ihtiyaç varsa persistence açıyoruz.
RDB, belirli aralıklarla anlık görüntü alıyor. save 900 1 gibi bir ayar 900 saniyede en az 1 değişiklik varsa diske yazıyor. Hızlıdır; ama son kayda kadar yapılan değişiklikler uçabilir. AOF ise her yazma komutunu sırayla dosyaya ekliyor. Sunucu açılınca bu komutlar tekrar çalışıyor. Veri kaybı daha düşük; disk yükü daha yüksek.
Cache amaçlı örneklerde biz çoğu zaman persistence’ı kapatıyoruz. Oturum ya da rate limiting gibi daha kritik yapılarda ise AOF’u everysec ile açık tutuyoruz. Her saniye diske yazıyor; performans kaybı kontrollü kalıyor.
Redis Cluster ve Sentinel ile Yüksek Erişilebilirlik
Tek Redis sunucusu çöktüğünde cache katmanı da düşer. Küçük projelerde bu kabul edilebilir olabilir. Günlük 200 bin isteği geçen yapılarda ise tek nokta arızası gelir kaybına dönüşüyor. Biz burada Sentinel ve Cluster seçeneklerine bakıyoruz.
Sentinel yapısında birkaç Redis sunucusu birbirini izliyor. Master çökerse yedek sunucu yeni master oluyor, bağlantı bilgisi uygulamaya aktarılıyor. Geçiş çoğu kez 10-30 saniye sürüyor. O arada yazma tarafında kısa kopmalar olabiliyor; okuma tarafı daha rahat devam ediyor.
Cluster tarafında veri 16384 hash slot’a dağıtılıyor. 3 düğümlü bir cluster kurduğumuzda her düğüm yaklaşık 5461 slot alıyor. Bir düğüm düşerse sadece kendi slot aralığı etkileniyor; sistemin tamamı gitmiyor. Orta ölçekli işlerde Sentinel, daha büyük veri kümelerinde Cluster bizim için daha mantıklı.
Pub/Sub Mekanizmasıyla Otomatik Cache Temizleme
Birden fazla sunucunun aynı Redis’e bağlandığı projelerde, bir sunucuda güncellenen verinin diğerlerine de yansıması gerekiyor. Dört web sunucusu olan bir sistemde ürün fiyatı değiştiğinde yalnızca bir sunucunun değil, diğerlerinin de kendi yerel önbelleğini temizlemesi lazım. Redis’in Pub/Sub yapısı bu yüzden iş görüyor.
Güncelleme yapan sunucu PUBLISH cache_invalidate product:145 komutunu gönderiyor. Diğer sunucular SUBSCRIBE cache_invalidate ile kanalı dinliyor, mesaj gelince ilgili anahtarı siliyor. Biz bunu özellikle uygulama seviyesinde ikinci bir yerel cache kullandığımız projelerde kuruyoruz. Tek Redis yetse de iki katman olunca senkronizasyon gerekiyor.
Burada bir sınır var: mesaj kalıcı değil. Dinlemeyen sunucu mesajı kaçırıyor. Bu yüzden kritik senkronizasyonda Pub/Sub’ı TTL tabanlı yedeklemeyle birlikte kullanıyoruz.
Lua Script ile Atomik İşlemler ve Race Condition Önleme
Redis komutları tek başına atomik çalışıyor; ama birden fazla komut arka arkaya çalıştığında araya başka istek girebiliyor. Stok kontrolünde önce GET stock:145 yapıp sonra uygulama tarafında azaltıp SET ile geri yazarsak iki istek birbirinin üstüne basabiliyor. Sonuç bozuluyor.
Bu noktada Lua script kullanıyoruz. EVAL ile gönderilen script tek blok halinde çalışıyor; araya başka komut girmiyor. Stok düşürmeyi güvenli hale getiren basit örnek şöyle:
local stock = tonumber(redis.call('GET', KEYS[1]))
if stock > 0 then
redis.call('DECR', KEYS[1])
return stock - 1
else
return -1
end
Bu yöntemi sınırlı sayıda ürünün satışa çıktığı kampanyalarda kullanıyoruz. Bir projede saniyede 300 isteğin aynı stok anahtarına yazdığı durumda, script olmadan stok sapıyordu. Script’ten sonra tutarsızlık kalmadı.
String Dışındaki Veri Tipleri: Hash, List, Set, Sorted Set
Redis’i yalnızca string cache gibi kullanmak, güçlü tarafını yarım bırakmak demek. Biz ihtiyaç çıktıkça başka veri tiplerini de devreye alıyoruz.
| Veri Tipi | Kullanım Alanı | Örnek Komut |
|---|---|---|
| Hash | Bir kullanıcının tüm profil alanlarını tek anahtar altında tutmak | HSET user:145 name "Ahmet" city "İzmir" |
| List | Bildirim kuyruğu, son işlem geçmişi gibi sıralı veri | LPUSH notifications:145 "Siparişiniz kargoya verildi" |
| Set | Bir kullanıcının takip ettiği kategoriler gibi tekil değer grupları | SADD user:145:categories "elektronik" |
| Sorted Set | En çok satan ürünler, liderlik tabloları gibi puanlı sıralamalar | ZADD bestsellers 120 "product:88" |
Sorted Set, liderlik tablosu ya da en çok görüntülenen ürün listesinde veritabanına göre ciddi rahatlık sağlıyor. 10 bin ürünü ORDER BY ile her sayfada yeniden sıralamak yerine puanı ZADD ile güncelliyoruz. ZREVRANGE ile okumak daha hafif kalıyor.
Hash’i de özellikle kullanıcı oturumlarında seviyoruz. Tek bir string yerine alanları ayrı tutunca sadece değişen kısmı güncelliyoruz; tüm nesneyi baştan yazmıyoruz. Kısa, temiz, yeterli.
Güvenlik: Redis'i Dışarıya Açık Bırakmanın Riskleri
Redis varsayılan kurulumda kimlik doğrulama olmadan çalışabiliyor. 6379 portu dışarı açıksa biri bağlanır, veriyi okur, siler, değiştirir. İnternete açık yanlış yapılandırılmış Redis sunucularında fidye notu bırakılan vakalar bizde de sık karşılaştığımız örnekler arasında.
Biz Redis’i üç temel kural ile ayağa kaldırıyoruz:
- Bağlanma adresi sınırlama:
bind 127.0.0.1ayarıyla Redis'in sadece kendi sunucusundan veya iç ağdan erişilebilir hale gelmesini sağlıyoruz. - Şifre zorunluluğu:
requirepassyönergesiyle güçlü bir parola tanımlıyoruz, uygulama tarafında bu parolayı ortam değişkeninde saklıyoruz. - Tehlikeli komutları kapatma:
FLUSHALLveCONFIGgibi tüm veriyi silebilen veya yapılandırmayı değiştirebilen komutlarırename-commandile devre dışı bırakıyoruz.
AWS ya da DigitalOcean üzerinde çalışıyorsa, güvenlik grubunu da kapalı tutuyoruz. İç ağ dışında erişim yok. Bu katmanlar olmadan kurulan Redis, güvenlik açısından açık bir veritabanından çok farklı davranmıyor.
Maliyet ve Barındırma: Self-Hosted ile Managed Redis Karşılaştırması
Redis’i kendi sunucumuzda mı tutacağız, yoksa yönetilen bir hizmet mi alacağız; karar bütçeye ve ekibin operasyon gücüne bağlı. Her projede aynı cevap çıkmıyor.
| Kriter | Self-Hosted Redis | Managed Redis |
|---|---|---|
| Maliyet | Sadece sunucu maliyeti, aylık 5-15 dolar civarı küçük VPS'lerde | Sunucu maliyetinin üzerine hizmet ücreti eklenir, benzer kapasite için 30-60 dolar civarı |
| Yedekleme | Manuel kurulum ve takip gerekir | Otomatik yedekleme ve nokta-zaman geri yükleme sunulur |
| Ölçeklendirme | Cluster kurulumu ekip tarafından yapılır | Panel üzerinden tek tıkla düğüm ekleme |
| Güvenlik güncellemeleri | Ekip sorumluluğunda | Sağlayıcı tarafından otomatik uygulanır |
| İzleme (monitoring) | Ayrıca araç kurulması gerekir | Panelde hazır grafik ve uyarılar bulunur |
Küçük ve orta ölçekli projelerde self-hosted Redis’i sık seçiyoruz; kurulum hızlı, maliyet düşük. Ama günlük yüz binlerce isteğin geldiği, kesinti toleransı düşük kurumsal yapılarda managed hizmet daha rahat oluyor. Yedekleme ve failover’ı biz kurmak zorunda kalmıyoruz.
Sıkça sorulan sorular
- Redis veritabanı sorgularını RAM’e nasıl taşır?
- Redis, sık kullanılan sorgu sonuçlarını RAM’de tutar. Cache-aside akışında önce Redis kontrol edilir. Veri varsa doğrudan gönderilir. Veri yoksa sorgu veritabanında çalışır. Sonuç Redis’e yazılır ve kullanıcıya iletilir. Biz örnek akışlarda 300 saniyelik TTL kullanıyoruz.
- Redis sorgu hızını ne kadar artırır?
- 50 bin ürünlü kategori sorgusu MySQL üzerinde ortalama 180 milisaniye sürdü. Aynı sonuç Redis’ten 1,8 milisaniyenin altında geldi. Ürün detayında PostgreSQL süresi 45 milisaniyeydi. Redis sonucu 0,9 milisaniyede döndürdü. Ölçümler 1000 eşzamanlı istek altında yapıldı.
- Hangi veritabanı sorguları Redis cache için uygundur?
- Tekrarlanan kategori, ürün listesi, arama ve ürün detay sorguları Redis için uygundur. İçerik her istekte değişmiyorsa cache avantajı artar. Biz kategori listelerinde genellikle 5-15 dakika TTL kullanıyoruz. Arama sonuçlarında 1-5 dakika yeterli olur. Fiyat ve stok için 30-60 saniye tercih ediyoruz.
- Redis cache’te eski veriler nasıl temizlenir?
- TTL süresi dolunca Redis kaydı kendiliğinden siler. Fiyat veya stok değişikliklerinde yalnızca TTL beklemek yeterli değildir. Biz yazma işleminden sonra ilgili anahtarları manuel siliyoruz. Kategoriye bağlı kayıtları set içinde tutup topluca temizleyebiliyoruz. Böylece kullanıcı eski fiyatı daha kısa süre görür.
- Redis mi Memcached mi, hangisi sorgu cache’i için daha uygun?
- Redis; string, liste, hash, set ve sıralı set veri türlerini destekler. Memcached yalnızca string saklar. Redis, RDB ve AOF ile diske yazılabilir. Memcached sunucu kapanınca veriyi tamamen kaybeder. Basit anahtar-değer cache’i için Memcached yeterli olabilir. Oturum, kuyruk ve sayaçlarda Redis daha geniş kullanım sunar.
Kaynakça
- Redis Documentation - Key Eviction — Redis'in RAM dolduğunda uyguladığı allkeys-lru, volatile-lru gibi bellek tahliye ve maxmemory politikalarının resmî çalışma mekanizmasına dayanak oluşturur.
- Microsoft Learn - Cache-Aside Pattern — Yazıda aktarılan veritabanı ile bellek arasındaki Cache-Aside veri okuma ve yazma mimarisinin standart tanımına ve akış ilkelerine dayanak oluşturur.
- Redis Documentation - Distributed Locks with Redis — Cache stampede sorununu çözmek için kullanılan SET NX/EX komutlarıyla dağıtık kilit mekanizmasının teknik mantığını doğrular.
- phpredis Extension Documentation — PHP projelerinde Redis bağlantısı için kullanılan pconnect fonksiyonu ve bağlantı yönetimi yöntemlerinin resmî kütüphane dokümantasyonudur.
- Redis Command Reference - INFO — Performans izleme bölümünde geçen keyspace_hits ve keyspace_misses istatistiklerinin çalışma yapısını ve hit rate hesaplama metriklerini belgeler.



