Redis Tech Talk
Data Types & Pub/Sub
🚀 Redis Nedir?
REmote DIctionary Server
Redis, verileri RAM’de saklayan açık kaynaklı, in-memory çalışan bir NoSQL veritabanıdır.
📝 Türü
NoSQL Veritabanı
🗝️ Modeli
Key-Value (Anahtar-Değer)
⚡ Çalışma Prensibi
Bellek (RAM) tabanlı çalışır, yani veriler öncelikle bellekte tutulur. Bu da çok yüksek hız sağlar.
🔧 Çok Yönlü
String, Hash, List, Set, Sorted Set veri yapıları
💾 Kalıcılık
RDB (snapshot) ve AOF (yazma geçmişi) desteği
📡 Pub/Sub
Gerçek zamanlı mesajlaşma sistemi
🔤 Veri Yapısı #1: Strings (Metinler)
Nedir?
En basit veri tipidir. Bir anahtara, bir metin veya sayısal değer atarsınız.
💡 Senaryo
Kullanıcının token bilgisini sakla.
Kod Örneği
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
async function stringsExample() { // Kullanıcının token bilgisini sakla await redisClient.set('token:kullanici:123', 'eyJhbGciOiJIUzI1NiIs...'); // Kullanıcının token bilgisini sakla (30 dakika TTL) await redisClient.setEx('token:kullanici:123', 1800, 'eyJhbGciOiJIUzI1NiIs...'); // Integer değerler için increment value await redisClient.incr('loginCount:kullanici:123'); // Token'ı getir const token = await redisClient.get('token:kullanici:123'); console.log(`User Token: ${token}`); // Çıkış yaptı, token'ı sil await redisClient.del('token:kullanici:123'); } |
🗂️ Veri Yapısı #2: Hashes (Sözlükler)
Nedir?
Alanlar ve değerlerden oluşan veri yapısı, tıpkı JSON objesi gibi. Bir anahtar altında birden fazla alt anahtar-değer çifti.
💡 Senaryo
Kullanıcı profil bilgileri (ad, soyad, e-posta). Her alan için ayrı STRING’ten çok daha verimli.
Kod Örneği
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
async function hashesExample(redisClient) { // Kullanıcının profilini tek anahtarda sakla await redisClient.hSet('kullanici:456', { ad: 'Ayşe', soyad: 'Yılmaz', }); // Sadece bir alanı getir const ad = await redisClient.hGet('kullanici:456', 'ad'); console.log(`Kullanicinin adi: ${ad}`); // Çıktı: Ayşe // Tüm alanları ve değerlerini getir const kullanici = await redisClient.hGetAll('kullanici:456'); console.log('Kullanici bilgileri:', kullanici); // Çıktı: { ad: 'Ayşe', soyad: 'Yılmaz', eposta: '[email protected]' } } |
📋 Veri Yapısı #3: Lists (Listeler)
Nedir?
Elemanların eklendiği sırayla tutulduğu bir veri yapısıdır. Bir listenin başına veya sonuna eleman ekleyebilir, çıkarabilirsiniz.
💡 Senaryo
İş Kuyrukları (Task Queues) veya bir kullanıcının yaptığı son 10 işlemi tutan bir akış listesi.
Kod Örneği
|
1 2 3 4 5 6 7 8 9 10 11 12 |
async function listsExample() { // Listenin soluna (başına) iki eleman ekle await redisClient.lPush('is_kuyrugu', ['email_gonder', 'resim_isle']); // Listenin sağından (sonundan) bir eleman al (ve sil) const gorev = await redisClient.rPop('is_kuyrugu'); console.log(`Kuyruktan alinan gorev: ${gorev}`); // Kuyruktaki eleman sayısını al const uzunluk = await redisClient.lLen('is_kuyrugu'); console.log(`Kuyruktaki eleman sayisi: ${uzunluk}`); } |
🎯 Veri Yapısı #4: Sets (Kümeler)
Nedir?
Tıpkı matematikteki gibi, benzersiz ve sırasız elemanların olduğu bir veri kümesidir.
💡 Senaryo
Bir blog yazısını beğenen benzersiz kullanıcıları tutmak veya bir e-ticaret sitesindeki bir ürüne ait etiketleri yönetmek.
⚡ List vs Set Farkı
List: Sıralı, duplicate (tekrarlı) eleman olabilir → [‘a’, ‘b’, ‘a’] ✅
Set: Sırasız, sadece benzersiz elemanlar → {‘a’, ‘b’} ✅
Kod Örneği
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
async function setsExample() { // Bir ürünün etiketlerini benzersiz olarak ekle await redisClient.sAdd('urun:123:etiketler', ['elektronik', 'akilli-saat', 'indirimli', 'akilli-saat']); // 'akilli-saat' sadece bir kez eklenir. // Kümenin tüm elemanlarını getir const etiketler = await redisClient.sMembers('urun:123:etiketler'); console.log('Urun etiketleri:', etiketler); // İki kümenin ortak elemanlarını bul (Intersection) const ortakEtiketler = await redisClient.sInter(['urun:123:etiketler', 'urun:456:etiketler']); console.log('Iki urunun ortak etiketleri:', ortakEtiketler); } |
🏆 Veri Yapısı #5: Sorted Sets (Sıralı Kümeler)
Nedir?
Her elemanın benzersiz olduğu, ancak her bir elemanın ilişkili bir “skor” ile birlikte saklandığı ve bu skorlara göre otomatik olarak sıralandığı bir kümedir.
💡 Senaryo
Oyunlardaki en iyi oyuncular listesi (leaderboard), en çok satan ürünler listesi veya kullanıcıların popülerlik skorları.
Kod Örneği
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
async function sortedSetsExample() { // Oyun skorlarını ekle await redisClient.zAdd('leaderboard:oyun', [ { score: 1000, value: 'Ahmet' }, { score: 500, value: 'Ayse' }, { score: 750, value: 'Mehmet' }, ]); // Bir elemanın skorunu getir const skor = await redisClient.zScore('leaderboard:oyun', 'Ahmet'); console.log('Ahmet\'in skoru:', skor); // En yüksek skordan başlayarak en iyi 3 oyuncuyu getir const siralama = await redisClient.zRevRange('leaderboard:oyun', 0, 2); console.log('En iyi 3 oyuncu:', siralama); // Belirli bir skor aralığındaki oyuncuları getir const skorAraligi = await redisClient.zRangeByScore('leaderboard:oyun', 500, 1000); console.log('500-1000 skor aralığındaki oyuncular:', skorAraligi); } |
🌍 Bonus: Geospatial Indexes (Coğrafi Uzamsal İndeksler)
Nedir?
GPS koordinatlarını (enlem, boylam) saklayan ve bu koordinatlar üzerinde “bana en yakın X şeyi bul” gibi sorguları hızlıca yapmamızı sağlayan özel bir veri yapısıdır.
💡 Senaryo
Bir restoranın konumuna en yakın 5 kuryeyi bulmak.
Kod Örneği
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
async function geospatialExample() { // Kurye konumunu ekle await redisClient.geoAdd('couriers', { longitude: 28.979530, latitude: 41.015137, member: 'courier_65d4bb9a7e3d3d001e43e8c2' }); // SubCompany konum bilgisi const subCompany = { lat: 41.018500, lon: 28.982000 }; // 5 km çapında arama yap const searchCourierRangeKm = 5; // SubCompany'e en yakın kuryeleri mesafe ve koordinatlarıyla getir const yakinKuryeler = await redisClient.geoRadius('couriers', { longitude: subCompany.lon, latitude: subCompany.lat }, searchCourierRangeKm, 'km', { // Sonuçları mesafeye göre sırala (en yakından en uzağa) SORT: 'ASC', // Sonuçlarla birlikte mesafeyi ve koordinatları da getir WITHCOORD: true, WITHDIST: true }); console.log('Yakın kuryeler (mesafe ve konum bilgisiyle):', yakinKuryeler); } |
📡 Redis Pub/Sub (Yayınla/Abone Ol)
Nedir?
Uygulamalar arasında gerçek zamanlı mesajlaşma sağlayan bir modeldir. Kanallar (channels) üzerinden mesaj iletimi yapılır.
💡 Kavramlar
Publisher: Mesajı yayınlayan
Subscriber: Kanala abone olan
Channel: Mesajların iletim kanalı
🔹 Asenkron Mesajlaşma Mantığı
⚡ Asenkron Yapı
• Mesajlar gerçek zamanlı iletilir
• Publisher mesajı gönderir ve beklemez
• Subscriber’lar mesajları bağımsız alır
• Hiçbiri diğerini bloklamaz
⚠️ Kalıcı Değil!
• Mesajlar sadece o anda aktif olan subscriber’lara gider
• Offline olan istemciler mesajı kaçırır
• Redis mesajları saklamaz
• “Fire and forget” mantığı
Kod Örneği – Bildirim Sistemi
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
const redis = require('redis'); // 1️⃣ ABONE OLAN SERVİS (Mobile App) const mobileAppSubscriber = redis.createClient(); mobileAppSubscriber.subscribe('user-notifications', (bildirim) => { // Kullanıcının telefonuna push notification gönder sendPushNotification(bildirim); console.log('📱 Mobil uygulamaya bildirim gönderildi'); }); // 2️⃣ YAYINLAYAN SERVİS (Order Service) const orderServicePublisher = redis.createClient(); function siparisOnaylandi(siparisDetay) { // Sipariş onaylandığında ASENKRON olarak bildirim yayınla orderServicePublisher.publish('user-notifications', `Siparişiniz onaylandı! #${siparisDetay.id}`); // ⚡ Publish işlemi BİTTİ, servis başka işlerine devam eder // Bildirimin gidip gitmediğini BEKLEMEZ! } // 💡 Asenkron çalışma: Sipariş servisi bildirim gönderip beklemez, // Mobile app servisi ise sürekli dinler ve anında tepki verir |
🎯 Pub/Sub Örnek Senaryolar
🏗️ Event-Driven Architecture – E-Ticaret Siparişi
📦 Sipariş Verildi!
Order Service
“siparis-olusturuldu” kanalına
mesaj yayınlar
⚡ Anında Tetiklenen Servisler:
- 📧 Email Servisi: Sipariş onay maili gönderir
- 📱 SMS Servisi: Kısa mesaj bildirimi atar
- 📊 Analytics Servisi: Satış verilerini günceller
- 📦 Warehouse Servisi: Stok düşürür, paketleme başlatır
- 💳 Payment Servisi: Ödeme takibini başlatır
🔄 Tüm bu işlemler PARALEL ve BİRBİRİNDEN BAĞIMSIZ çalışır!
📻 Radyo İstasyonu – Binlerce Dinleyici
🎵 DJ Yayında!
Radyo İstasyonu
“radyo-100-3” kanalından
şarkı yayını yapıyor
🔊 Dinleyici Deneyimi:
- 👥 Binlerce dinleyici aynı anda “radyo-100-3” kanalını dinliyor
- 📱 Mobil uygulamalar şarkı bilgilerini anında alıyor
- 🚗 Araç sistemleri current track’i gösteriyor
- 💻 Web siteleri “şu an çalıyor” bilgisini güncelliyor
- ⏰ Geç bağlananlar o anki şarkıyı duyar (öncekini kaçırır)
📡 DJ broadcast yapar, kim dinliyorsa o anda alır!
💬 Canlı Sohbet Uygulaması – Ölçeklenebilir Chat
💬 Mesaj Gönderildi!
Socket.io Server
“sohbet-odasi-1” kanalına
mesajı yayınlar
🌐 Çoklu Server Yapısı:
- 🖥️ Server 1: Ahmet ve Ayşe’nin WebSocket bağlantıları
- 🖥️ Server 2: Mehmet ve Fatma’nın bağlantıları
- 📡 Redis Pub/Sub: Serverlar arası mesaj köprüsü
- ⚡ Anında senkronizasyon: Hangi serverda olursa olsun herkes görür
- 🚀 Horizontal scaling: Yeni server eklense de sorun yok
🔗 Redis olmadan: Sadece aynı server’daki kullanıcılar mesajı görür!
🎁 Bonus: Mesajlaşma Teknolojileri Karşılaştırması
| Özellik | Redis Pub/Sub | RabbitMQ (veya Kafka) | Socket.IO |
|---|---|---|---|
| Rolü | Mesaj Yayıncısı / Veri Deposu | Dedicated Mesaj Broker’ı | Client-Server İletişim Kütüphanesi |
| Temel Görev | Anlık, düşük gecikmeli broadcast. | Güvenli, garantili, sıraya alma (queuing). | Tarayıcı ve sunucu arasında gerçek zamanlı, çift yönlü iletişim. |
| Mesaj Saklama | Yok. Abone offline ise mesajı kaçırır. | Var. Mesajlar okunana kadar saklanır. | Yok. Sadece aktif bağlantıya iletir. |
| Kullanım Alanı | Canlı skorlar, anlık bildirimler, chat uygulamaları. | Arka plan işleri (e-mail, resim işleme), kritik işlemler. | Frontend’den backend’e gerçek zamanlı veri akışı. |
| Mimari Fit | Sunucu içi (server-to-server) ve Socket.IO ile birlikte sunucu-client iletişimi. | Sunucu içi (server-to-server) ve mikroservisler arası iletişim. | Sadece Sunucu-Tarayıcı arasında bir köprü. |
| Örnek Senaryo | Borsadan anlık hisse fiyatı yayını. | Bankacılıkta para transferi işleminin sıraya alınması. | Müşterinin web sitesinde kuryenin konumunun canlı takibi. |
💡 Bu teknolojiler rakip değil, tamamlayıcı! Gerçek projelerde genellikle birlikte kullanılırlar:
• Redis Pub/Sub: Hızlı, anlık bildirimler için
• RabbitMQ/Kafka: Kritik, garantili işlemler için
• Socket.IO: Frontend ile backend arasında köprü olarak
