Yükleniyor...

Redis Best Practices: 15 Kapsamlı En İyi Uygulama [2026 Rehberi]

Yazar: Burak Balkı | Kategori: Full Stack Development | Okuma Süresi: 59 dk

Bu rehber, 2026 güncel Redis best practice'lerini, kurulumunu, temel ve ileri seviye kullanımını, performans optimizasyonunu ve yaygın hataları kapsar. Uygul...

# Redis Best Practices: 15 Kapsamlı En İyi Uygulama [2026 Rehberi] ## 1. Giriş: Redis ile Uygulama Performansını Zirveye Taşıyın Günümüzün rekabetçi dijital dünyasında, kullanıcı deneyimi her şeyden önemli. Bir uygulamanın milisaniyelerle ölçülen yavaşlığı bile müşteri kaybına yol açabilirken, yüksek performans ve düşük gecikme süresi kritik bir avantaj sağlıyor. İşte tam bu noktada, **Redis** devreye giriyor. Birçoğumuzun bildiği gibi, Redis, açık kaynaklı, bellek içi bir veri yapısı sunucusu olarak önbellekleme, mesajlaşma ve veritabanı işlevlerini bir araya getirerek uygulamaların hızını ve ölçeklenebilirliğini artırıyor. Ancak Redis'in tüm potansiyelini ortaya çıkarmak, sadece onu kullanmakla değil, aynı zamanda **Redis en iyi uygulamalarını** doğru bir şekilde uygulamakla mümkün. Bu kapsamlı rehberde, 2026 yılı itibarıyla geçerli olan en güncel ve etkili Redis best practice'lerini, neden önemli olduklarını ve bunları kendi projelerinize nasıl entegre edeceğinizi adım adım öğreneceksiniz. Ekibimizde, yüksek trafikli e-ticaret platformlarından gerçek zamanlı analiz sistemlerine kadar birçok farklı senaryoda Redis'i aktif olarak kullanıyoruz. Son projemizde, bu rehberde ele alacağımız bazı yaklaşımları uygulayarak API yanıt sürelerinde %40'ın üzerinde iyileşme kaydettik. Bu deneyimler ışığında, sizlere sadece teorik bilgileri değil, aynı zamanda üretim ortamında kanıtlanmış pratik çözümleri sunmayı hedefliyorum. Bu rehber, Redis'i sadece bir önbellek aracı olarak değil, aynı zamanda güçlü bir veri platformu olarak görmenizi sağlayacak ve 2026'nın en güncel standartlarına uygun, güvenli ve performanslı uygulamalar geliştirmenize yardımcı olacak. ## 2. Redis Nedir? **Redis**, Remote Dictionary Server kelimelerinin kısaltması olup, açık kaynaklı, bellek içi bir veri yapısı depolama aracıdır. Genellikle önbellekleme, mesaj kuyrukları ve gerçek zamanlı analizler için kullanılan, anahtar-değer tabanlı, hızlı ve esnek bir NoSQL veritabanıdır. Redis, stringler, hash'ler, listeler, setler, sıralı setler, bit dizileri, HyperLogLog'lar, akışlar ve coğrafi indeksler gibi çeşitli zengin veri yapılarını destekler. Bu sayede geliştiricilere yüksek performanslı ve ölçeklenebilir uygulamalar inşa etme imkanı sunar. Redis, verileri RAM üzerinde tuttuğu için milisaniyeler düzeyinde düşük gecikme süreleri ve yüksek işlem hacmi sunar. Bu özelliği, özellikle sık erişilen verilerin hızlı bir şekilde sunulması gereken önbellekleme senaryolarında onu vazgeçilmez kılar. Aynı zamanda, disk tabanlı veritabanlarının getirdiği I/O yükünü azaltarak genel sistem performansını artırır. Redis, tek bir sunucuda çalışabildiği gibi, dağıtık sistemlerde master-replica replikasyonu ve kümeleme (clustering) gibi özelliklerle yüksek erişilebilirlik ve yatay ölçeklenebilirlik de sağlar. Geliştiriciler, Redis'i oturum yönetimi, tam sayfa önbellekleme, mesajlaşma (pub/sub), anlık bildirimler, oyun liderlik tabloları ve gerçek zamanlı veri akışları gibi birçok farklı kullanım senaryosunda tercih ederler. ## 3. Neden Redis Kullanmalısınız? Redis, modern yazılım mimarilerinde vazgeçilmez bir bileşen haline gelmiştir. Onu tercih etmeniz için birçok somut fayda ve problem çözme yeteneği bulunmaktadır: * **Yüksek Performans ve Düşük Gecikme:** Redis, verileri bellekte tuttuğu için disk I/O operasyonlarının getirdiği gecikmeleri ortadan kaldırır. Bu sayede veri okuma ve yazma işlemleri milisaniyeler içinde gerçekleşir. Bu, özellikle web uygulamalarında sayfa yükleme sürelerini hızlandırarak kullanıcı deneyimini önemli ölçüde iyileştirir. Örneğin, bir e-ticaret sitesinde ürün kataloglarının Redis'te önbelleklenmesi, veritabanı sorgu yükünü %70'e kadar azaltabilir ve sayfa yanıt süresini 500 ms'den 50 ms'ye düşürebilir. * **Ölçeklenebilirlik:** Redis, master-replica replikasyonu ve Redis Cluster gibi özelliklerle yatay ölçeklenebilirlik sunar. Bu, uygulamanızın trafiği arttıkça Redis altyapınızı kolayca genişletebileceğiniz anlamına gelir. Veritabanı sunucularınızdaki yükü azaltarak, ana veritabanınızın daha az yoğunlukla çalışmasını sağlar ve bu da onun daha verimli olmasını temin eder. * **Çok Yönlü Veri Yapıları:** Sadece basit anahtar-değer depolamanın ötesinde, Redis stringler, hash'ler, listeler, setler, sıralı setler gibi zengin veri yapıları sunar. Bu yapılar, geliştiricilere karmaşık uygulama mantıklarını daha verimli bir şekilde uygulamaları için esneklik sağlar. Örneğin, sıralı setler ile anlık liderlik tabloları oluşturmak veya listeler ile kuyruk sistemleri kurmak oldukça kolaydır. * **Geliştirici Dostu ve Zengin Ekosistem:** Redis, birçok programlama dili için kapsamlı istemci kütüphaneleri sunar. Python, Node.js, Java, Go, PHP, C# gibi dillerde Redis ile çalışmak oldukça basittir. Ayrıca, RediSearch, RedisJSON, RedisGraph gibi modüllerle yetenekleri daha da genişletilebilir. Aktif ve büyük bir topluluğa sahip olması, sorun giderme ve yeni özellikler konusunda sürekli destek anlamına gelir. * **Çeşitli Kullanım Senaryoları:** Redis, önbellekleme dışındaki birçok alanda da kullanılır: oturum yönetimi, gerçek zamanlı analizler, mesajlaşma (pub/sub), anlık bildirimler, oyun skor tabloları, coğrafi konum tabanlı hizmetler, dağıtık kilitler ve oran sınırlama (rate limiting) gibi birçok alanda etkili çözümler sunar. Redis, özellikle yüksek trafikli, gerçek zamanlı veri işleme gerektiren ve düşük gecikme süresi beklenen uygulamalar için idealdir. Ancak, büyük ve karmaşık ilişkisel veri setlerinin kalıcı olarak depolanması gereken senaryolarda tek başına birincil veritabanı olarak kullanılmamalıdır; bu durumlarda genellikle PostgreSQL veya MySQL gibi ilişkisel veritabanları ile birlikte tamamlayıcı bir rol üstlenir. ## 4. Redis vs Alternatifler (2026 Karşılaştırması) Redis, bellek içi veri depolama ve önbellekleme alanında güçlü bir oyuncu olsa da, piyasada farklı ihtiyaçlara yönelik alternatifler de bulunmaktadır. 2026 yılı itibarıyla en yaygın alternatifleri ve Redis ile aralarındaki temel farkları inceleyelim: | Özellik | Redis | Memcached | Apache Kafka | PostgreSQL (RDBMS) | | :------------------ | :------------------------------------ | :------------------------------------ | :------------------------------------ | :---------------------------------- | | **Performans** | Çok yüksek (bellek içi, zengin veri yapıları, atomik işlemler) | Çok yüksek (bellek içi, basit anahtar-değer) | Yüksek (mesaj akışı, yüksek hacimli olay işleme) | Orta (disk tabanlı, ilişkisel sorgular) | | **Veri Yapıları** | String, Hash, List, Set, Sorted Set, Stream, Geo, Bitmaps, JSON | Sadece String (basit anahtar-değer) | Olaylar (immutable log) | İlişkisel Tablolar, JSONB, Diziler | | **Kalıcılık** | İsteğe bağlı (RDB/AOF) | Yok (sadece bellek içi) | Yüksek (disk tabanlı loglar) | Yüksek (ACID uyumlu, disk tabanlı) | | **Öğrenme Eğrisi** | Orta (çok yönlü API, veri yapıları) | Düşük (basit API) | Yüksek (dağıtık sistem, kavramlar) | Orta (SQL, şema tasarımı) | | **Ekosistem** | Çok zengin (modüller, istemciler, araçlar) | Orta (temel istemciler) | Çok zengin (Connect, Streams, ksqlDB) | Çok zengin (ORMs, araçlar, uzantılar) | | **Topluluk** | Çok aktif ve büyük | Aktif ama daha küçük | Çok aktif ve büyük | Çok aktif ve büyük | | **Kurumsal Destek** | Redis Labs (Redis Enterprise) | Yok (açık kaynak, topluluk) | Confluent, Aiven | EnterpriseDB, çeşitli firmalar | | **Kullanım Alanı** | Önbellekleme, Pub/Sub, Oturum Yönetimi, Liderlik Tabloları, Gerçek Zamanlı Analiz, Mesaj Kuyrukları, Dağıtık Kilitler | Önbellekleme, Oturum Yönetimi | Olay Akışı, Mesaj Kuyrukları, Log Toplama, Gerçek Zamanlı Veri İşleme | Birincil Veritabanı, İlişkisel Veri Depolama, İş Mantığı | Bu tabloya göre, Redis'in Memcached'den en büyük farkı, zengin veri yapıları ve isteğe bağlı kalıcılık sunmasıdır. Kafka ise tamamen farklı bir kullanım senaryosu olan olay akışı ve mesajlaşma platformudur, ancak Redis'in Pub/Sub özelliği ile bazı mesajlaşma ihtiyaçlarını karşılayabilir. PostgreSQL gibi ilişkisel veritabanları ise kalıcı ve ilişkisel veri depolama için tasarlanmıştır, Redis'in önbellekleme ve anlık veri işleme yeteneklerini tamamlayıcı olarak kullanılır. Seçim, projenizin spesifik ihtiyaçlarına, veri modeline ve performans beklentilerine göre yapılmalıdır. Genellikle bu araçlar birbirinin alternatifi olmaktan çok, farklı katmanlarda birbirini tamamlayıcı roller üstlenirler. ## 5. Kurulum ve İlk Adımlar (2026) Redis'i 2026 yılında çeşitli platformlara kurmak oldukça basittir. En yaygın kurulum yöntemlerini ve ilk adımları aşağıda bulabilirsiniz. ### 5.1 Docker ile Kurulum (Önerilen) Geliştirme ve üretim ortamları için en esnek ve kolay yöntem Docker kullanmaktır. Bu sayede Redis'i sisteminizden izole bir şekilde çalıştırabilirsiniz. 1. **Docker İmajını Çekme:** ```bash docker pull redis:7.4.0-alpine ``` > **Pro Tip:** `alpine` tabanlı imajlar daha küçük boyutlu ve hafiftir, bu da kaynak tüketimini azaltır. 2. **Redis Konteynerini Çalıştırma:** ```bash docker run --name my-redis -p 6379:6379 -d redis:7.4.0-alpine redis-server --appendonly yes ``` Bu komut, `my-redis` adında bir Redis konteyneri oluşturur, 6379 portunu host makinenize bağlar ve Redis'i `AOF` (Append Only File) kalıcılık modu açık olarak başlatır. `redis-server --appendonly yes` komutu, Redis'in varsayılan kalıcılık ayarlarını geçersiz kılarak AOF'yi etkinleştirir. 3. **Redis CLI ile Bağlanma:** ```bash docker exec -it my-redis redis-cli ``` Bu komutla çalışan Redis konteynerine bağlanabilir ve Redis komutlarını çalıştırabilirsiniz. ### 5.2 Linux Üzerine Kurulum (Ubuntu/Debian) 1. **Güncelleme ve Bağımlılıkları Kurma:** ```bash sudo apt update sudo apt install lsb-release curl gpg ``` 2. **Redis Resmi Deposu Ekleme:** Redis'in en güncel kararlı sürümünü (2026 itibarıyla 7.4.x veya daha yenisi) almak için resmi depoyu eklemek en iyisidir. ```bash curl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/redis.list ``` 3. **Redis Sunucusunu Kurma:** ```bash sudo apt update sudo apt install redis ``` 4. **Redis Servisini Başlatma ve Kontrol Etme:** ```bash sudo systemctl enable redis-server sudo systemctl start redis-server sudo systemctl status redis-server ``` ### 5.3 Redis CLI ile Test Etme Kurulumun ardından Redis CLI (Komut Satırı Arayüzü) kullanarak Redis sunucunuzla etkileşime geçebilirsiniz. ```bash redis-cli 127.0.0.1:6379> PING PONG 127.0.0.1:6379> SET mykey "Hello Redis 2026!" OK 127.0.0.1:6379> GET mykey "Hello Redis 2026!" ``` Bu adımlarla Redis sunucunuzu başarıyla kurmuş ve temel komutlarla test etmiş olursunuz. Artık uygulamalarınızda Redis'i kullanmaya hazırsınız. ## 6. Temel Kullanım ve Örnekler Redis'in gücü, sunduğu çeşitli veri yapılarının pratik kullanım senaryolarında yatar. İşte en yaygın kullanım alanlarından bazıları ve kod örnekleri: ### 6.1 Önbellekleme (Caching) Veritabanı yükünü azaltmak ve yanıt sürelerini iyileştirmek için en sık kullanılan Redis senaryosudur. Bir Node.js (Express) uygulamasında önbellekleme örneği: **Problem:** Sık erişilen veritabanı sorguları sunucuya ve veritabanına yük bindiriyor. **Çözüm:** Veritabanından gelen verileri Redis'te belirli bir süre (TTL - Time To Live) ile önbellekleme. ```javascript // app.js (Node.js Express Uygulaması) const express = require('express'); const redis = require('redis'); const axios = require('axios'); // Örnek bir API çağrısı için const app = express(); const PORT = process.env.PORT || 3000; // Redis istemcisini 2026 güncel sürümüne uygun olarak oluşturun const redisClient = redis.createClient({ url: 'redis://localhost:6379' }); redisClient.on('error', (err) => console.log('Redis Client Error', err)); (async () => { await redisClient.connect(); console.log('Redis\'e başarıyla bağlandı.'); })(); // Örnek bir veri kaynağı (dış API veya veritabanı) async function fetchUserDataFromDB(userId) { // Gerçek bir senaryoda burada veritabanı sorgusu olurdu. // Simülasyon için 2 saniye gecikme ekleyelim. return new Promise(resolve => { setTimeout(() => { console.log(`Veri tabanından ${userId} için veri çekiliyor...`); resolve({ id: userId, name: `Kullanıcı ${userId}`, email: `user${userId}@example.com`, createdAt: '2026-04-24' }); }, 2000); }); } app.get('/users/:id', async (req, res) => { const userId = req.params.id; const cacheKey = `user:${userId}`; try { // 1. Redis'ten veriyi kontrol et const cachedUser = await redisClient.get(cacheKey); if (cachedUser) { console.log('Redis önbelleğinden servis ediliyor.'); return res.json(JSON.parse(cachedUser)); } // 2. Redis'te yoksa, veritabanından çek const userData = await fetchUserDataFromDB(userId); // 3. Veriyi Redis'e kaydet ve 60 saniye sonra sona erecek şekilde ayarla (TTL) await redisClient.setEx(cacheKey, 60, JSON.stringify(userData)); console.log('Veritabanından çekildi ve Redis\'e kaydedildi.'); res.json(userData); } catch (error) { console.error('Hata:', error); res.status(500).send('Sunucu hatası.'); } }); app.listen(PORT, () => { console.log(`Sunucu ${PORT} portunda çalışıyor.`); }); ``` ### 6.2 Yayınlama/Abone Olma (Pub/Sub) Mesajlaşma Gerçek zamanlı uygulamalar, sohbet odaları veya anlık bildirim sistemleri için idealdir. **Problem:** Uygulama bileşenleri arasında düşük gecikmeli, ayrık iletişim kurmak gerekiyor. **Çözüm:** Redis Pub/Sub mekanizması ile mesajları kanallar üzerinden yayınlama ve abone olma. ```javascript // publisher.js const redis = require('redis'); const publisher = redis.createClient({ url: 'redis://localhost:6379' }); publisher.on('error', (err) => console.log('Redis Publisher Error', err)); (async () => { await publisher.connect(); console.log('Publisher Redis\'e bağlandı.'); let messageCount = 0; setInterval(async () => { const message = `Merhaba Redis Dünyası! Mesaj: ${++messageCount} - ${new Date().toISOString()}`; await publisher.publish('chat_channel', message); console.log(`'chat_channel' kanalına yayınlandı: ${message}`); }, 3000); })(); ``` ```javascript // subscriber.js const redis = require('redis'); const subscriber = redis.createClient({ url: 'redis://localhost:6379' }); subscriber.on('error', (err) => console.log('Redis Subscriber Error', err)); (async () => { await subscriber.connect(); console.log('Subscriber Redis\'e bağlandı.'); await subscriber.subscribe('chat_channel', (message) => { console.log(`'chat_channel' kanalından mesaj alındı: ${message}`); }); console.log('\'chat_channel\' kanalına abone olundu. Mesaj bekleniyor...'); })(); ``` ### 6.3 Oturum Yönetimi (Session Management) Web uygulamalarında kullanıcı oturumlarını sunucu tarafında yönetmek için Redis'i kullanmak, ölçeklenebilirlik ve performans sağlar. **Problem:** Dağıtık bir uygulama ortamında kullanıcı oturumlarını tutarlı ve ölçeklenebilir bir şekilde yönetmek zor. **Çözüm:** Oturum verilerini Redis'te depolamak ve her istekle Redis'ten çekmek. ```javascript // app.js (Express ile oturum yönetimi) const express = require('express'); const session = require('express-session'); const RedisStore = require('connect-redis').default; // connect-redis 7.x ve üzeri için const redis = require('redis'); const app = express(); const PORT = process.env.PORT || 3000; // Redis istemcisini oluşturun const redisClient = redis.createClient({ url: 'redis://localhost:6379' }); redisClient.on('error', (err) => console.log('Redis Client Error', err)); (async () => { await redisClient.connect(); console.log('Redis\'e başarıyla bağlandı.'); })(); // RedisStore'u yapılandırın const redisStore = new RedisStore({ client: redisClient, prefix: 'session:', ttl: 3600 // Oturum süresi 1 saat (saniye cinsinden) }); // Express oturum middleware'ini yapılandırın app.use(session({ store: redisStore, secret: 'cokgizlibirgizli_2026', resave: false, saveUninitialized: false, cookie: { secure: process.env.NODE_ENV === 'production', httpOnly: true, maxAge: 1000 * 60 * 60 // 1 saat } })); app.get('/', (req, res) => { if (req.session.views) { req.session.views++; res.send(`Sayfayı ${req.session.views} kez ziyaret ettiniz. Oturum ID: ${req.session.id}`); } else { req.session.views = 1; res.send(`Hoş geldiniz! Burayı ilk kez ziyaret ediyorsunuz. Oturum ID: ${req.session.id}`); } }); app.get('/login', (req, res) => { req.session.user = { id: 1, username: 'burakbalki' }; res.send('Giriş başarılı! Kullanıcı oturumu oluşturuldu.'); }); app.get('/profile', (req, res) => { if (req.session.user) { res.json({ message: 'Profil bilgileri', user: req.session.user }); } else { res.status(401).send('Giriş yapmalısınız.'); } }); app.listen(PORT, () => { console.log(`Sunucu ${PORT} portunda çalışıyor.`); }); ``` ### 6.4 Oran Sınırlama (Rate Limiting) API kötüye kullanımını önlemek ve sunucu kaynaklarını korumak için önemlidir. **Problem:** Bir API uç noktasının belirli bir zaman diliminde çok fazla istek almasını engellemek. **Çözüm:** Redis'in `INCR` ve `EXPIRE` komutlarını kullanarak her kullanıcı/IP için istek sayısını takip etmek. ```javascript // app.js (Express ile basit oran sınırlama) const express = require('express'); const redis = require('redis'); const app = express(); const PORT = process.env.PORT || 3000; const redisClient = redis.createClient({ url: 'redis://localhost:6379' }); redisClient.on('error', (err) => console.log('Redis Client Error', err)); (async () => { await redisClient.connect(); console.log('Redis\'e başarıyla bağlandı.'); })(); const rateLimitMiddleware = async (req, res, next) => { const ip = req.ip; // Veya req.headers['x-forwarded-for'] const key = `rate_limit:${ip}`; const maxRequests = 10; // 10 saniyede maksimum 10 istek const windowSize = 10; // 10 saniye try { // Redis'ten mevcut istek sayısını al ve artır const requests = await redisClient.incr(key); // Anahtarın TTL'i yoksa, pencere boyutuna göre ayarla if (requests === 1) { await redisClient.expire(key, windowSize); } if (requests > maxRequests) { return res.status(429).send('Çok fazla istek! Lütfen daha sonra tekrar deneyin.'); } next(); } catch (error) { console.error('Rate Limit Hatası:', error); res.status(500).send('Sunucu hatası.'); } }; app.use(rateLimitMiddleware); app.get('/api/data', (req, res) => { res.json({ message: 'Veri başarıyla alındı!', timestamp: new Date().toISOString() }); }); app.listen(PORT, () => { console.log(`Sunucu ${PORT} portunda çalışıyor.`); }); ``` ### 6.5 Liderlik Tabloları ve Oyun Skorları Redis'in sıralı setleri (Sorted Sets) bu tür senaryolar için mükemmeldir. **Problem:** Oyunlarda veya yarışmalarda kullanıcıları skorlarına göre sıralamak ve hızlıca ilk N kişiyi listelemek. **Çözüm:** Sıralı setleri kullanarak kullanıcı ID'lerini skorlarıyla birlikte depolamak. ```javascript // leaderboard.js const redis = require('redis'); const client = redis.createClient({ url: 'redis://localhost:6379' }); client.on('error', (err) => console.log('Redis Client Error', err)); (async () => { await client.connect(); console.log('Redis\'e başarıyla bağlandı.'); const leaderboardKey = 'game_leaderboard'; // Oyuncu skorlarını ekle/güncelle async function updateScore(player, score) { await client.zAdd(leaderboardKey, { score: score, value: player }); console.log(`${player} skorunu ${score} olarak güncelledi.`); } // En iyi N oyuncuyu getir async function getTopPlayers(count) { // ZRANGE ile en yüksek skorluları tersten sıralayarak alıyoruz const topPlayers = await client.zRange(leaderboardKey, 0, count - 1, { REV: true, WITHSCORES: true }); console.log(`En iyi ${count} oyuncu:`, topPlayers); return topPlayers; } // Bir oyuncunun sırasını ve skorunu getir async function getPlayerRankAndScore(player) { const rank = await client.zRank(leaderboardKey, player, { REV: true }); // Tersten sıralanmış rank const score = await client.zScore(leaderboardKey, player); if (rank !== null && score !== null) { console.log(`${player} sırası: ${rank + 1}, Skoru: ${score}`); return { rank: rank + 1, score: score }; } else { console.log(`${player} liderlik tablosunda bulunamadı.`); return null; } } (async () => { await updateScore('Alice', 1500); await updateScore('Bob', 2000); await updateScore('Charlie', 1200); await updateScore('David', 2500); await updateScore('Alice', 1800); // Alice'in skoru güncellendi await getTopPlayers(3); await getPlayerRankAndScore('Alice'); await getPlayerRankAndScore('Eve'); // Bulunamayacak bir oyuncu await client.quit(); })(); })(); ``` Bu örnekler, Redis'in temel veri yapılarını ve kullanım senaryolarını göstermektedir. Her bir senaryo, uygulamanızın performansını ve ölçeklenebilirliğini artırmak için Redis'in nasıl kullanılabileceğine dair pratik bir bakış sunar. ## 7. İleri Seviye Teknikler (2026) Redis'i sadece temel önbellekleme için kullanmak, onun potansiyelinin küçük bir kısmını kullanmak demektir. İşte Redis'in daha güçlü yönlerini ortaya çıkaran ileri seviye teknikler: ### 7.1 Redis İşlemleri (Transactions - MULTI/EXEC) Redis, atomik (bölünmez) işlemler sağlamak için `MULTI` ve `EXEC` komutlarını kullanır. Bu, birden fazla komutun tek bir atomik birim olarak yürütülmesini sağlar, yani tüm komutlar ya başarılı olur ya da hiçbiri olmaz. Bu, özellikle tutarlılık gerektiren senaryolarda önemlidir. **Problem:** Birden fazla Redis komutunun tek bir atomik operasyon olarak çalışmasını sağlamak, veri tutarsızlığını önlemek. **Çözüm:** `MULTI` ile bir işlem başlatıp komutları sıraya almak ve `EXEC` ile tümünü çalıştırmak. ```javascript const redis = require('redis'); const client = redis.createClient({ url: 'redis://localhost:6379' }); client.on('error', (err) => console.log('Redis Client Error', err)); (async () => { await client.connect(); const userId = 'user:101'; const productId = 'product:A456'; try { // Bir kullanıcının cüzdanından para çekip bir ürünü satın alma senaryosu await client.set(`${userId}:balance`, 100); // Başlangıç bakiyesi await client.set(`${productId}:stock`, 5); // Ürün stoğu const transactionResult = await client.multi() .decrBy(`${userId}:balance`, 20) // Bakiyeden 20 düşür .decr(`${productId}:stock`) // Stoğu 1 azalt .exec(); console.log('İşlem Sonucu:', transactionResult); // [ 80, 4 ] çıktısı beklenir, yani bakiye 80, stok 4 oldu. const currentBalance = await client.get(`${userId}:balance`); const currentStock = await client.get(`${productId}:stock`); console.log(`Güncel Bakiye: ${currentBalance}, Güncel Stok: ${currentStock}`); } catch (error) { console.error('İşlem Hatası:', error); } finally { await client.quit(); } })(); ``` > **Uyarı:** `WATCH` komutu ile optimist kilit mekanizması kullanarak bir anahtarın değeri değiştiğinde işlemi iptal edebilirsiniz. Bu, `MULTI/EXEC` ile birlikte daha karmaşık tutarlılık senaryoları için kullanılır. ### 7.2 Lua Scripting Redis, sunucu tarafında Lua betikleri çalıştırmanıza olanak tanır. Bu, birden fazla Redis komutunu atomik olarak ve ağ gecikmesi olmadan çalıştırmak için güçlü bir yoldur. Özellikle karmaşık işlemleri tek bir komut gibi yürütmek için idealdir. **Problem:** Birden fazla komutun ağ üzerinden gönderilmesi gecikmeye neden oluyor ve atomiklik garantilenemiyor. **Çözüm:** Lua betikleri ile birden fazla komutu Redis sunucusunda atomik olarak çalıştırmak. ```javascript const redis = require('redis'); const client = redis.createClient({ url: 'redis://localhost:6379' }); client.on('error', (err) => console.log('Redis Client Error', err)); (async () => { await client.connect(); // Lua betiği: Eğer anahtar varsa değerini artır, yoksa 1 olarak ayarla ve TTL ver. const luaScript = ` local current_value = redis.call('GET', KEYS[1]) if current_value then redis.call('INCR', KEYS[1]) else redis.call('SET', KEYS[1], 1) redis.call('EXPIRE', KEYS[1], ARGV[1]) end return redis.call('GET', KEYS[1]) `; const key = 'my_atomic_counter'; const ttl = 60; // 60 saniye try { let result1 = await client.eval(luaScript, { keys: [key], arguments: [ttl.toString()] }); console.log(`İlk çalıştırma: ${key} değeri: ${result1}`); // 1 let result2 = await client.eval(luaScript, { keys: [key], arguments: [ttl.toString()] }); console.log(`İkinci çalıştırma: ${key} değeri: ${result2}`); // 2 // Anahtarın TTL'ini kontrol edelim (opsiyonel) const remainingTTL = await client.ttl(key); console.log(`${key} için kalan TTL: ${remainingTTL} saniye`); } catch (error) { console.error('Lua Script Hatası:', error); } finally { await client.quit(); } })(); ``` ### 7.3 Redis Streams Redis Streams, olay günlüğü (event log) benzeri bir veri yapısıdır. Gerçek zamanlı olay işleme, mesaj kuyrukları ve değişiklik veri yakalama (CDC) senaryoları için güçlü bir araçtır. **Problem:** Uygulamalar arasında olay tabanlı iletişim kurmak, olayların sırasını korumak ve birden fazla tüketici tarafından işlenmesini sağlamak. **Çözüm:** Redis Streams kullanarak olayları bir akışa eklemek ve tüketici grupları ile işlemek. ```javascript const redis = require('redis'); const client = redis.createClient({ url: 'redis://localhost:6379' }); client.on('error', (err) => console.log('Redis Client Error', err)); (async () => { await client.connect(); const streamKey = 'my_event_stream'; const consumerGroup = 'my_group'; const consumerName = 'consumer_alpha'; try { // Tüketici grubunu oluştur (eğer yoksa) await client.xGroupCreate(streamKey, consumerGroup, '0', { MKSTREAM: true }).catch(err => { if (err.message.includes('BUSYGROUP')) { console.log('Tüketici grubu zaten mevcut.'); } else { throw err; } }); // Akışa olay ekle await client.xAdd(streamKey, '*', { event_type: 'user_login', userId: '123', timestamp: new Date().toISOString() }); console.log('user_login olayı eklendi.'); await client.xAdd(streamKey, '*', { event_type: 'product_view', productId: 'P456', userId: '123', timestamp: new Date().toISOString() }); console.log('product_view olayı eklendi.'); // Tüketici grubundan olayları oku const messages = await client.xReadGroup(consumerGroup, consumerName, [ { key: streamKey, id: '>' } // '>' yeni mesajları okur ], { count: 1, block: 1000 }); // 1 saniye bekle, 1 mesaj oku if (messages && messages.length > 0) { console.log('Alınan Mesajlar:', JSON.stringify(messages, null, 2)); // İşlenen mesajı ACK'le for (const stream of messages) { for (const message of stream.messages) { await client.xAck(streamKey, consumerGroup, message.id); console.log(`Mesaj ACK'lendi: ${message.id}`); } } } else { console.log('Yeni mesaj yok.'); } } catch (error) { console.error('Redis Stream Hatası:', error); } finally { await client.quit(); } })(); ``` ### 7.4 Redis Modülleri (Redis Stack) Redis, RediSearch, RedisJSON, RedisGraph, RedisTimeSeries gibi modüllerle işlevselliğini genişletebilir. Bu modüller, Redis'i sadece bir önbellekten çok daha fazlası yapar. **Problem:** Tam metin arama, JSON veri yönetimi veya grafik veritabanı işlevselliği eklemek için ayrı bir veritabanı kullanma ihtiyacı. **Çözüm:** Redis Stack ile entegre modülleri kullanarak Redis'in yeteneklerini genişletmek. Örnek olarak, RedisJSON modülü ile JSON belgelerini doğrudan Redis içinde depolayabilir ve sorgulayabilirsiniz: ```javascript // redisjson.js const redis = require('redis'); const client = redis.createClient({ url: 'redis://localhost:6379' }); client.on('error', (err) => console.log('Redis Client Error', err)); (async () => { await client.connect(); const userKey = 'user:profile:456'; const userData = { name: 'Ayşe Yılmaz', email: 'ayse.yilmaz@example.com', age: 30, interests: ['coding', 'hiking', 'reading'], address: { city: 'İstanbul', country: 'Türkiye' } }; try { // JSON.SET ile bir JSON belgesi kaydet await client.json.set(userKey, ' , userData); console.log('JSON verisi kaydedildi.'); // JSON.GET ile tüm belgeyi al const retrievedUser = await client.jso