TuZaKK 1
TuZaKK
kaptanmikro1 1
kaptanmikro1
farkmt2official 2
farkmt2official
kralhakan2009 1
kralhakan2009
Vahsi Uzman 1
Vahsi Uzman
Bvural41 1
Bvural41
Hikaye Ekle

[NODE JS] Redis ile Veri Saklama

Türkiye'de ilk Mobil & PC Aynı Anda Metin2 Oyna. Triarchonline kalıcı ve uzun ömürlü yapısı ile 24 Temmuz'da açılıyor. | 1-99 Mobil Metin2 Triarch HEMEN TIKLA!

nodejs.png


[NODE JS] Redis ile Veri Saklama​


Redis, bellekte çalışan ve inanılmaz hızlı bir veri saklama çözümüdür. İlk kez Redis ile tanıştığımda, "Bu gerçekten bu kadar hızlı olabilir mi?" diye düşünmüştüm. Veritabanı sorgularının milisaniyeler sürdüğü bir dünyada, Redis mikrosaniyeler seviyesinde yanıt verebiliyor. Bu yazıda Node.js ile Redis'i nasıl kullanabileceğinizi, temel veri yapılarını ve pratik senaryoları ele alacağız.

Redis'in en güçlü yanlarından biri, sadece basit key-value deposu olmamasıdır. String, Hash, List, Set ve Sorted Set gibi zengin veri yapılarını destekler. Her birinin kendine özgü kullanım alanları vardır. Örneğin, bir kullanıcının oturum bilgilerini saklamak için Hash yapısı mükemmeldir. Bir sıralama tablosu oluşturmak istiyorsanız Sorted Set tam ihtiyacınız olan şeydir. Bu çeşitlilik, Redis'i neredeyse her projede kullanılabilir kılar.

Node.js ekosisteminde Redis ile çalışmak için birkaç farklı kütüphane bulunuyor. Eskiden "redis" paketi en yaygın tercihti, ancak son dönemde "ioredis" kütüphanesi performansı ve özellik zenginliği ile öne çıkıyor. Ben projelerimde genellikle ioredis tercih ediyorum çünkü Promise desteği, cluster modu ve pipeline gibi gelişmiş özellikleri kutudan çıkar çıkmaz sunuyor.

Redis'i bir projede kullanmaya başlamadan önce, veri modelinizi iyi düşünmeniz gerekiyor. İlişkisel veritabanlarından farklı olarak Redis'te JOIN işlemi yoktur. Bu yüzden verilerinizi nasıl okuyacağınıza göre yapılandırmanız çok önemlidir. Denormalizasyon burada dostunuzdur. Aynı veriyi birden fazla yapıda saklamak, okuma performansını dramatik şekilde artırabilir.

Bir e-ticaret projesinde ürün detaylarını Redis'te saklamaya başladığımda, sayfa yüklenme süreleri yarı yarıya düştü. Kullanıcı deneyimi açısından bu muazzam bir fark yarattı. Ancak dikkat etmeniz gereken nokta, Redis bellekte çalıştığı için veri boyutunuzu kontrol altında tutmanız gerektiğidir. Gereksiz verileri TTL ile otomatik silmek, bellek yönetimi açısından kritik bir pratiktir.

Redis'in bir diğer güçlü özelliği de atomik işlemlerdir. INCR, DECR gibi komutlar sayesinde sayaç işlemlerini güvenli şekilde gerçekleştirebilirsiniz. Yarış koşullarından endişelenmenize gerek kalmaz. Bu özellik özellikle oy verme sistemleri, beğeni sayaçları ve stok takibi gibi senaryolarda hayat kurtarıcıdır.

Üretim ortamında Redis kullanırken, bağlantı havuzu yönetimine dikkat edin. ioredis bu işi otomatik halleder, ancak bağlantı sayısını ve zaman aşımı değerlerini doğru yapılandırmak önemlidir. Ayrıca Redis sunucunuzun güvenliğini sağlamak için şifre koruması ve ağ erişim kısıtlamalarını mutlaka uygulayın. Açık bırakılmış bir Redis sunucusu, ciddi güvenlik açıklarına yol açabilir.

JavaScript:
// Redis ile Veri Saklama - Temel İşlemler
const Redis = require('ioredis');

// Redis bağlantısı oluşturma
const redis = new Redis({
  host: '127.0.0.1',
  port: 6379,
  password: 'guclu_sifre_123',
  db: 0,
  retryStrategy: function (times) {
    const delay = Math.min(times * 50, 2000);
    return delay;
  },
  maxRetriesPerRequest: 3
});

// Bağlantı olaylarını dinleme
redis.on('connect', () => {
  console.log('Redis bağlantısı başarıyla kuruldu');
});

redis.on('error', (hata) => {
  console.error('Redis bağlantı hatası:', hata.message);
});

// ==========================================
// STRING Veri Yapısı
// ==========================================
async function stringIslemleri() {
  // Basit string değer saklama
  await redis.set('uygulama:isim', 'Müşteri Yönetim Paneli');

  // TTL ile değer saklama (60 saniye sonra silinir)
  await redis.set('gecici:token', 'abc123xyz', 'EX', 60);

  // Değer okuma
  const uygulamaIsmi = await redis.get('uygulama:isim');
  console.log('Uygulama:', uygulamaIsmi);

  // Sayaç işlemleri (atomik)
  await redis.set('sayac:ziyaretci', 0);
  await redis.incr('sayac:ziyaretci');
  await redis.incr('sayac:ziyaretci');
  await redis.incrby('sayac:ziyaretci', 10);

  const ziyaretci = await redis.get('sayac:ziyaretci');
  console.log('Toplam ziyaretçi:', ziyaretci); // 12

  // Birden fazla değeri aynı anda saklama
  await redis.mset(
    'ayar:dil', 'tr',
    'ayar:tema', 'koyu',
    'ayar:bildirim', 'acik'
  );

  const ayarlar = await redis.mget('ayar:dil', 'ayar:tema', 'ayar:bildirim');
  console.log('Ayarlar:', ayarlar);
}

// ==========================================
// HASH Veri Yapısı - Kullanıcı Bilgileri
// ==========================================
async function hashIslemleri() {
  const kullaniciId = 'kullanici:1001';

  // Kullanıcı bilgilerini Hash olarak saklama
  await redis.hset(kullaniciId, {
    ad: 'Mehmet',
    soyad: 'Yılmaz',
    eposta: 'mehmet@ornek.com',
    yas: '28',
    sehir: 'İstanbul',
    kayitTarihi: new Date().toISOString(),
    aktif: 'true'
  });

  // Tek bir alan okuma
  const ad = await redis.hget(kullaniciId, 'ad');
  console.log('Kullanıcı adı:', ad);

  // Tüm alanları okuma
  const tumBilgiler = await redis.hgetall(kullaniciId);
  console.log('Tüm bilgiler:', tumBilgiler);

  // Belirli alanları güncelleme
  await redis.hset(kullaniciId, 'sehir', 'Ankara');
  await redis.hincrby(kullaniciId, 'yas', 1);

  // Alan varlığını kontrol etme
  const varMi = await redis.hexists(kullaniciId, 'eposta');
  console.log('E-posta alanı var mı:', varMi);
}

// ==========================================
// LIST Veri Yapısı - İşlem Kuyruğu
// ==========================================
async function listIslemleri() {
  const kuyrukAdi = 'kuyruk:gorevler';

  // Kuyruğa görev ekleme (sağdan)
  await redis.rpush(kuyrukAdi, JSON.stringify({
    id: 1, tur: 'eposta', alici: 'ali@ornek.com', konu: 'Hoş geldiniz'
  }));
  await redis.rpush(kuyrukAdi, JSON.stringify({
    id: 2, tur: 'bildirim', kullaniciId: 1001, mesaj: 'Yeni güncelleme mevcut'
  }));
  await redis.rpush(kuyrukAdi, JSON.stringify({
    id: 3, tur: 'rapor', donem: '2026-07', format: 'pdf'
  }));

  // Kuyruk uzunluğunu öğrenme
  const uzunluk = await redis.llen(kuyrukAdi);
  console.log('Kuyrukta bekleyen görev:', uzunluk);

  // Kuyruktan görev alma (soldan - FIFO)
  const gorev = await redis.lpop(kuyrukAdi);
  console.log('İşlenen görev:', JSON.parse(gorev));

  // Kuyruktaki tüm görevleri listeleme
  const tumGorevler = await redis.lrange(kuyrukAdi, 0, -1);
  tumGorevler.forEach((g, i) => {
    console.log(`Görev ${i + 1}:`, JSON.parse(g));
  });
}

// ==========================================
// SET Veri Yapısı - Etiketler
// ==========================================
async function setIslemleri() {
  // Makale etiketleri
  await redis.sadd('makale:101:etiketler', 'javascript', 'nodejs', 'redis', 'veritabanı');
  await redis.sadd('makale:102:etiketler', 'javascript', 'react', 'frontend', 'performans');

  // Ortak etiketleri bulma
  const ortakEtiketler = await redis.sinter('makale:101:etiketler', 'makale:102:etiketler');
  console.log('Ortak etiketler:', ortakEtiketler); // ['javascript']

  // Etiket sayısını öğrenme
  const etiketSayisi = await redis.scard('makale:101:etiketler');
  console.log('Etiket sayısı:', etiketSayisi);

  // Rastgele etiket seçme
  const rastgele = await redis.srandmember('makale:101:etiketler');
  console.log('Rastgele etiket:', rastgele);
}

// ==========================================
// SORTED SET - Sıralama Tablosu
// ==========================================
async function sortedSetIslemleri() {
  const tabloAdi = 'oyun:siralama';

  // Oyuncu puanlarını ekleme
  await redis.zadd(tabloAdi, 1500, 'Ahmet');
  await redis.zadd(tabloAdi, 2200, 'Ayşe');
  await redis.zadd(tabloAdi, 1800, 'Can');
  await redis.zadd(tabloAdi, 2500, 'Deniz');
  await redis.zadd(tabloAdi, 1950, 'Elif');

  // En yüksek puanlı 3 oyuncu
  const enIyiler = await redis.zrevrange(tabloAdi, 0, 2, 'WITHSCORES');
  console.log('İlk 3 oyuncu:', enIyiler);

  // Belirli oyuncunun sıralaması
  const sira = await redis.zrevrank(tabloAdi, 'Can');
  console.log('Can sıralamada kaçıncı:', sira + 1);

  // Puan güncelleme
  await redis.zincrby(tabloAdi, 300, 'Can');
  console.log('Can yeni puanıyla yükseldi');
}

// Ana fonksiyon
async function basla() {
  try {
    await stringIslemleri();
    await hashIslemleri();
    await listIslemleri();
    await setIslemleri();
    await sortedSetIslemleri();
    console.log('\nTüm Redis işlemleri başarıyla tamamlandı');
  } catch (hata) {
    console.error('Hata oluştu:', hata.message);
  } finally {
    await redis.quit();
  }
}

basla();

Redis ile çalışırken en önemli tavsiyem, veri yapılarını iyi öğrenmeniz ve her senaryo için en uygun yapıyı seçmenizdir. Doğru veri yapısı seçimi, hem performansı artırır hem de kodunuzu daha okunabilir hale getirir. Bir sonraki yazıda Redis'in cache mekanizması olarak nasıl kullanılacağını detaylıca inceleyeceğiz.
 

Şu an konuyu görüntüleyenler (Toplam : 0, Üye: 0, Misafir: 0)

Geri
Üst