Redis (REmote DIctionary Server) bellek içi (in-memory) bir veri yapısı sunucusudur ve modern backend mimarilerinin neredeyse tamamında bir noktada karşınıza çıkar — cache, session store, rate limiter, mesaj broker, leaderboard, geo arama, hatta küçük ölçekli birincil veritabanı olarak. redis.io üzerinde belgelenen tek node bir Redis 7.x sürecinin tipik gecikmesi 0.1-0.5 ms arasıdır ve saniyede yüzbinlerce komut işleyebilir. Bu rehberde Redis'in neden bu kadar yaygın olduğunu, hangi veri tiplerini nasıl kullanacağınızı, kurulumdan kümeye kadar üretim ortamında dikkat etmeniz gereken her şeyi gerçek komutlar ve uygulama kodlarıyla anlatıyoruz.

Redis Nedir, Hangi Problemleri Çözer?

İlgili rehberler: Yazılım geliştirme süreçleri · PostgreSQL optimizasyonu · Git ileri seviye komutlar · Docker ile deploy · KEYDAL yazılım geliştirme hizmetleri

Redis tek node üzerinde RAM'de tutulan key-value tabanlı bir veri yapısı motorudur. Veriler RAM'de tutulduğu için eriştiği gecikme PostgreSQL veya MySQL gibi disk-tabanlı veritabanlarının çok altındadır. Komut işleme döngüsü çoğunlukla tek thread'lidir; bu, atomiklik garantisi sağlar — bir komut çalışırken araya başka bir komut girmez. I/O için ise Redis 6'dan itibaren io-threads ile birden fazla thread kullanabilir. Varsayılan port 6379, ana protokol RESP'dir.

Tipik kullanım senaryoları: yavaş veritabanı sorgularını cache'lemek, kullanıcı oturumlarını HTTP istekleri arası tutmak, dakikada N istek gibi rate limit kuralları uygulamak, gerçek zamanlı bildirim ve sohbet için pub/sub yayını yapmak, leaderboard ve sıralama tabloları, geo proximity (yakındaki sürücüler), HyperLogLog ile milyonlarca tekil kullanıcıyı sabit hafızada saymak, Redis Streams ile Kafka benzeri olay akışları.

Redis vs Memcached

Memcached da bellek içi bir cache servisidir, ama Redis ile karşılaştırıldığında oldukça sınırlıdır. Aşağıdaki farklar production seçimini doğrudan etkiler:

  • Veri tipleri: Memcached sadece string. Redis string, hash, list, set, sorted set, stream, bitmap, hyperloglog, geo destekler.
  • Persistence: Memcached %100 uçucudur — restart sonrası tüm veri kaybolur. Redis RDB ve AOF ile diske yazabilir.
  • Replication ve HA: Memcached'de yerleşik replikasyon yok. Redis master-replica, Sentinel (otomatik failover) ve Cluster (sharding) sunar.
  • Pub/Sub ve Streams: Memcached'de yok; Redis ikisini de destekler.
  • Atomik komutlar: Redis tüm komutları tek thread üzerinde sırayla çalıştırdığı için INCR, SADD, ZADD gibi işlemler atomiktir. Lua script ile çoklu komutu atomik birim olarak çalıştırabilirsiniz.
  • Bellek kullanımı: Memcached basit string'lerde biraz daha verimli olabilir; ama Redis'in tinyintset, listpack gibi optimizasyonları büyük listelerde Memcached'i geride bırakır.

Pratik kural: salt cache lazımsa ve veriyi kaybetmek sorun değilse Memcached da iş görür. Hibrit kullanım (cache + queue + leaderboard + session) gerekiyorsa Redis tek seçenektir.

Kurulum: apt, Docker ve Yönetilen Servisler

Üretim ortamlarında Redis'i kurmanın üç pratik yolu vardır: paket yöneticisi (Ubuntu/Debian), Docker konteyneri, ve managed hizmet (Upstash, Redis Cloud, AWS ElastiCache). Geliştirme için Docker en hızlısıdır.

# Ubuntu/Debian — apt ile native kurulum
sudo apt update
sudo apt install -y redis-server
sudo systemctl enable --now redis-server

# Durumu kontrol et
redis-cli ping
# PONG

# Sürüm bilgisi
redis-server --version
# Redis server v=7.2.4 sha=00000000:0 malloc=jemalloc-5.3.0 bits=64
# Docker ile (geliştirme)
docker run -d --name redis -p 6379:6379 redis:7-alpine

# Production benzeri (persistent volume + custom config)
docker run -d --name redis \
  -p 6379:6379 \
  -v redis-data:/data \
  -v $(pwd)/redis.conf:/usr/local/etc/redis/redis.conf \
  redis:7-alpine redis-server /usr/local/etc/redis/redis.conf

# Redis Stack (RedisJSON, RediSearch, TimeSeries, Bloom dahil)
docker run -d --name redis-stack \
  -p 6379:6379 -p 8001:8001 \
  redis/redis-stack:latest

Yönetilen Redis için Upstash serverless ve istek bazlı ücretlendirir; düşük trafikli projeler için aylık $0 ile başlar. AWS ElastiCache daha klasik, sürekli açık node modeli sunar. Redis'in resmi şirketi olan Redis Inc., Redis Stack modüllerini önceden yüklü Redis Cloud planları üzerinde çalıştırır — redis.io/docs/stack.

redis-cli ile İlk Komutlar

redis-cli, Redis sunucusuna bağlanmak için kullanılan resmi terminal istemcisidir. Bağlandıktan sonra interaktif modda komut yazabilirsiniz. Komut listesinin tamamı redis.io/commands üzerinde belgelidir.

# Local sunucuya bağlan
redis-cli

# Uzak sunucuya, parolayla bağlan
redis-cli -h 10.0.0.5 -p 6379 -a 'StrongP@ss!' --no-auth-warning

# Tek komut çalıştır ve çık
redis-cli SET hello 'world'
redis-cli GET hello
# "world"

# Tüm key'leri tara (üretimde KEYS yerine SCAN kullanın)
redis-cli --scan --pattern 'user:*' | head -20

# Latency ölçümü
redis-cli --latency -i 1
# min: 0, max: 1, avg: 0.16 (1234 samples)

Veri Tipi: String

En temel ve en yaygın kullanılan tip. Bir key altında binary-safe bir string saklanır. Sayaç olarak kullanmak için INCR/DECR, TTL atamak için EXPIRE komutları vardır.

# Set/Get
SET user:1:name 'Egemen'
GET user:1:name
# "Egemen"

# TTL ile (5 dakika sonra siler)
SET session:abc123 '{"uid":42}' EX 300
TTL session:abc123
# (integer) 297

# Atomik sayaç (sayfa görüntüleme)
INCR pageviews:home
INCR pageviews:home
GET pageviews:home
# "2"

# Sadece yoksa yaz (distributed lock için temel)
SET lock:order:42 'worker-1' NX EX 30
# OK
SET lock:order:42 'worker-2' NX EX 30
# (nil)  ← lock alınamadı

Veri Tipi: List

Çift uçlu bağlı liste. LPUSH/RPUSH ile uçlara ekler, LPOP/RPOP ile çıkarırsınız. BLPOP bloklayıcı pop ile basit bir worker queue'ya dönüşür.

# Job queue olarak kullanım
LPUSH jobs '{"type":"send_email","to":"a@b.com"}'
LPUSH jobs '{"type":"resize_image","id":42}'
LLEN jobs
# (integer) 2

# Worker (5 saniye bekleyerek pop)
BRPOP jobs 5
# 1) "jobs"
# 2) "{\"type\":\"send_email\",\"to\":\"a@b.com\"}"

# Aralık göster
LRANGE jobs 0 -1

# En yeni 100 log girişini sakla (sliding window)
LPUSH logs:app 'request from 1.2.3.4'
LTRIM logs:app 0 99   # sadece ilk 100'ü tut

Veri Tipi: Hash

Bir key altında alan→değer çiftleri tutar. Kullanıcı profili, ürün metadatası gibi yapısal verileri tek key altında toplamak için idealdir. Aynı kullanıcının tüm alanları aynı node'a düşer.

# Kullanıcı profili
HSET user:42 name 'Ada' email 'ada@example.com' age 33
HGET user:42 email
# "ada@example.com"

HGETALL user:42
# 1) "name"
# 2) "Ada"
# 3) "email"
# 4) "ada@example.com"
# 5) "age"
# 6) "33"

# Sayaç alanı (atomik artış)
HINCRBY user:42 login_count 1

# Sadece bazı alanlar
HMGET user:42 name age

Veri Tipi: Set

Sıralanmamış, tekrar etmeyen string kümesi. Etiketler, takipçi listeleri, günlük tekil ziyaretçiler için kullanılır. Kümeler arası kesişim, birleşim ve fark işlemlerini sunucu tarafında yapabilirsiniz — uygulamada O(1) gibi gelir.

# Bir gönderinin etiketleri
SADD post:101:tags 'redis' 'cache' 'performance'
SMEMBERS post:101:tags

# Takip ve takipçi
SADD user:1:following 2 3 4
SADD user:2:following 1 4 5

# Ortak takip edilenler (kesişim)
SINTER user:1:following user:2:following
# 1) "4"

# Tekil günlük ziyaretçi (yaklaşık değil, kesin)
SADD visitors:2026-04-25 'ip:1.2.3.4' 'ip:5.6.7.8'
SCARD visitors:2026-04-25

Veri Tipi: Sorted Set (ZSET)

Her elemanın bir score'u olan sıralı küme. Leaderboard, en güncel/en popüler içerikler, time-series gibi sıralamayla yapılan tüm işler için altın standart. Eleman ekleme ve sıralı listeleme O(log N).

# Oyun leaderboard
ZADD leaderboard 1500 'alice' 1820 'bob' 1340 'carol' 2100 'dave'

# En yüksek 3 oyuncu (skor ile)
ZREVRANGE leaderboard 0 2 WITHSCORES
# 1) "dave"
# 2) "2100"
# 3) "bob"
# 4) "1820"
# 5) "alice"
# 6) "1500"

# Score'u güncelle (atomik artış)
ZINCRBY leaderboard 50 'alice'

# 1500-1900 aralığındaki oyuncular
ZRANGEBYSCORE leaderboard 1500 1900

# Bir oyuncunun sırası
ZREVRANK leaderboard 'alice'

Veri Tipi: Bitmap, HyperLogLog ve Geo

Bitmap aslında bir string üzerinde tek tek bit'leri okuyup yazar. Günlük aktif kullanıcı (DAU) takibi için bir kullanıcının yıl içindeki günlere bit olarak işaretlenmesi 365 bit = 46 byte yer kaplar — milyonlarca kullanıcı için bile çok ucuz.

# DAU: kullanıcı 42 bugün giriş yaptı
SETBIT dau:2026-04-25 42 1
GETBIT dau:2026-04-25 42
# (integer) 1

# Bugünkü aktif kullanıcı sayısı
BITCOUNT dau:2026-04-25
# (integer) 17834

# HyperLogLog — milyon kayıtlık unique sayım, ~12 KB hafıza
PFADD visitors:home 'ip:1.2.3.4' 'ip:5.6.7.8'
PFCOUNT visitors:home
# (integer) 2 (yaklaşık ±%0.81 hata)

# Geo — yakındaki noktalar
GEOADD drivers 28.9784 41.0082 'driver:1' 28.9850 41.0105 'driver:2'
GEOSEARCH drivers FROMLONLAT 28.98 41.01 BYRADIUS 2 km ASC
# 1) "driver:1"
# 2) "driver:2"

Veri Tipi: Stream (Redis Streams)

Redis 5+ ile gelen, append-only log yapısı. redis.io/docs/data-types/streams üzerinde belgelendiği gibi Kafka benzeri tüketici grupları (consumer groups) ve mesaj onayı (XACK) ile çalışır. Microservice mimarilerinde olay yayını için Kafka kurmadan başlamanın hızlı yoludur.

# Olay yayınla
XADD events:orders * type 'created' order_id 1001 amount 250
XADD events:orders * type 'paid'    order_id 1001

# Stream uzunluğu
XLEN events:orders
# (integer) 2

# Tüketici grubu oluştur
XGROUP CREATE events:orders billing $ MKSTREAM

# Worker olarak oku (yeni gelen mesajları)
XREADGROUP GROUP billing worker-1 COUNT 10 BLOCK 5000 STREAMS events:orders >

# İşledikten sonra ack
XACK events:orders billing 1714050000000-0

# Pending (henüz ack edilmemiş)
XPENDING events:orders billing

Cache Pattern: Cache-Aside (Lazy Loading)

En yaygın cache pattern'i. Uygulama önce cache'e bakar; yoksa veritabanından çeker, cache'e yazar, dönderir. ioredis ile Node.js örneği:

// npm i ioredis
import Redis from 'ioredis';
const redis = new Redis({ host: '127.0.0.1', port: 6379 });

async function getProduct(id) {
  const key = `product:${id}`;

  // 1) Cache
  const cached = await redis.get(key);
  if (cached) return JSON.parse(cached);

  // 2) Veritabanı
  const product = await db.query('SELECT * FROM products WHERE id=$1', [id]);
  if (!product) return null;

  // 3) Cache'e yaz (10 dakika TTL)
  await redis.set(key, JSON.stringify(product), 'EX', 600);
  return product;
}

// Invalidation: ürün güncellendiğinde
async function updateProduct(id, patch) {
  await db.update(id, patch);
  await redis.del(`product:${id}`);
}

Aynı pattern'i Python ile, redis-py kullanarak:

# pip install redis
import json, redis
r = redis.Redis(host='127.0.0.1', port=6379, decode_responses=True)

def get_product(pid: int):
    key = f'product:{pid}'
    cached = r.get(key)
    if cached:
        return json.loads(cached)

    product = db.fetch_one('SELECT * FROM products WHERE id=%s', (pid,))
    if not product:
        return None

    r.set(key, json.dumps(product), ex=600)
    return product

Cache Pattern: Write-Through ve Write-Behind

Cache-aside dışındaki iki strateji genellikle daha karmaşık ihtiyaçları karşılar:

  • Write-through: Uygulama yazma anında hem veritabanına hem cache'e senkron yazar. Stale veri ihtimali düşer ama yazma latency'si artar.
  • Write-behind (write-back): Uygulama önce cache'e yazar, cache asenkron olarak veritabanına flush eder. Yüksek yazma yükü olan sistemlerde performans sıçraması sağlar; ama crash anında veri kaybı riski vardır.
  • Read-through: Uygulama cache'e bakar; cache miss durumunda cache motoru kendi başına veritabanından çekip doldurur. Redis'te bu pattern genellikle bir kütüphane veya kendi yazdığınız wrapper ile gelir.

Session Store: Express, Django, Laravel

HTTP session'ını Redis'te tutmak yatay ölçeklenmenin (birden fazla app server) ön şartıdır. Cookie içindeki session ID, Redis'te key olarak yaşar; herhangi bir node aynı session'ı görebilir. Express için resmi entegrasyon connect-redis:

// npm i express express-session connect-redis ioredis
import express from 'express';
import session from 'express-session';
import { RedisStore } from 'connect-redis';
import Redis from 'ioredis';

const app = express();
const redis = new Redis(process.env.REDIS_URL);

app.use(session({
  store: new RedisStore({ client: redis, prefix: 'sess:' }),
  secret: process.env.SESSION_SECRET,
  resave: false,
  saveUninitialized: false,
  cookie: {
    httpOnly: true,
    secure: true,
    sameSite: 'lax',
    maxAge: 1000 * 60 * 60 * 24 * 7  // 7 gün
  }
}));

app.get('/', (req, res) => {
  req.session.views = (req.session.views || 0) + 1;
  res.send(`Görüntüleme: ${req.session.views}`);
});

Django tarafında django-redis ile SESSION_ENGINE = 'django.contrib.sessions.backends.cache'; Laravel'de .env içinde SESSION_DRIVER=redis ve config/database.php içindeki Redis ayarları yeterli. Üç çerçevede de cookie içeriği değil, sadece session ID istemcide tutulur — kalıcı veri Redis'tedir.

Rate Limiting: Sliding Window ve Lua

En basit rate limit: INCR + EXPIRE. IP başına 60 saniyede 100 istek kuralı için key her dakika sıfırlanır. Sabit pencereli, yaklaşık doğrulukta:

// Basit sabit pencere — 60 sn'de 100 istek
async function allow(ip) {
  const key = `rl:${ip}:${Math.floor(Date.now() / 60000)}`;
  const count = await redis.incr(key);
  if (count === 1) await redis.expire(key, 60);
  return count <= 100;
}

Daha hassas (sliding window) için Lua script atomik olarak çalışır — race condition olmaz:

-- KEYS[1] = rate limit key (sorted set)
-- ARGV[1] = pencere uzunluğu (sn), ARGV[2] = limit, ARGV[3] = şimdiki ts (ms)
local window = tonumber(ARGV[1]) * 1000
local limit  = tonumber(ARGV[2])
local now    = tonumber(ARGV[3])
local cutoff = now - window

-- Eski isteklerii sil
redis.call('ZREMRANGEBYSCORE', KEYS[1], 0, cutoff)

-- Şu anki sayım
local count = redis.call('ZCARD', KEYS[1])
if count >= limit then
  return 0  -- reddet
end

-- Yeni isteği ekle
redis.call('ZADD', KEYS[1], now, now)
redis.call('PEXPIRE', KEYS[1], window)
return 1  -- izin ver
// ioredis ile script kullanımı
const script = fs.readFileSync('rate_limit.lua', 'utf8');
redis.defineCommand('ratelimit', { numberOfKeys: 1, lua: script });

async function allow(ip) {
  const ok = await redis.ratelimit(`rl:${ip}`, 60, 100, Date.now());
  return ok === 1;
}

Pub/Sub: Gerçek Zamanlı Bildirim

PUBLISH/SUBSCRIBE komutları abonelere fire-and-forget mesaj gönderir. Tarayıcıya WebSocket üzerinden push, mikroservisler arası anlık olay yayını için kullanılır. Mesaj kalıcı değildir — abone yoksa kaybolur. Kalıcılık gerekiyorsa Redis Streams tercih edin.

// Yayıncı (publisher)
import Redis from 'ioredis';
const pub = new Redis();
await pub.publish('notifications:user:42', JSON.stringify({
  type: 'message',
  from: 'alice',
  body: 'Selam!'
}));

// Abone (subscriber) — ayrı bağlantı kullanın
const sub = new Redis();
await sub.subscribe('notifications:user:42');
sub.on('message', (channel, payload) => {
  const msg = JSON.parse(payload);
  console.log('Yeni bildirim:', msg);
});

// Pattern subscribe
await sub.psubscribe('notifications:*');
sub.on('pmessage', (pattern, channel, payload) => { /* ... */ });

Redis 7'den itibaren SSUBSCRIBE/SPUBLISH ile sharded pub/sub mevcut — küme modunda mesaj yayını sadece bir shard üzerinde gerçekleştirilerek tüm node'ların yükü azaltılır.

Persistence: RDB, AOF ve Hibrit

Bellek içi olmasına rağmen Redis verisini diske yazabilir. İki yöntem vardır ve genellikle ikisi birlikte kullanılır:

  • RDB (snapshot): Tüm veri belirli aralıklarla tek bir dump.rdb dosyasına yazılır. Restart sonrası en hızlı geri yükleme. Snapshot anlarında crash olursa son snapshot'tan beri yazılan veriler kaybolur.
  • AOF (Append Only File): Her yazma komutu appendonly.aof dosyasına eklenir. Crash anında en fazla fsync politikası kadar veri kaybedilir. Disk büyür, dolayısıyla periyodik BGREWRITEAOF ile kompaktlanır.
  • Hibrit (RDB + AOF): Redis 4+ ile birlikte aof-use-rdb-preamble yes ayarı ile AOF dosyasının başına RDB snapshot'ı eklenir. Restart hem hızlı hem güvenli olur. Production'da varsayılan tercih budur.
# /etc/redis/redis.conf — persistence
# RDB snapshots
save 900 1       # 15 dk içinde >=1 değişiklik varsa snapshot
save 300 10
save 60  10000

# AOF
appendonly yes
appendfsync everysec     # her saniye fsync (best balance)
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

# Hibrit format (Redis 4+)
aof-use-rdb-preamble yes

Replication ve Sentinel

Master-replica replikasyonu ile bir master node yazma trafiğini alır, replikalar okuma trafiğini ölçeklemek için kullanılabilir. Replica'da replicaof <master_ip> 6379 tek satırlık ayar yeterlidir.

Yüksek erişilebilirlik için Redis Sentinel kullanılır. Sentinel master'ı sürekli izler, master düştüğünde otomatik olarak bir replica'yı yeni master olarak terfi ettirir ve istemcileri yönlendirir. Quorum tabanlı çalıştığı için 3 Sentinel node minimum önerilir.

# sentinel.conf — temel
port 26379
sentinel monitor mymaster 10.0.0.10 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
sentinel parallel-syncs mymaster 1
sentinel auth-pass mymaster 'StrongP@ss!'

Cluster: Sharding ve Hash Slots

Tek bir master'ın RAM ve CPU sınırlarına ulaştığınızda Redis Cluster devreye girer. Veri 16384 hash slot'a bölünür ve slot'lar master node'lar arasında paylaştırılır. Her master'ın opsiyonel replikası vardır. İstemci kütüphanesi (ioredis, redis-py, Lettuce) hangi key'in hangi node'da olduğunu otomatik bulur.

# 6 node'lu klasik cluster (3 master + 3 replica)
redis-cli --cluster create \
  10.0.0.10:7000 10.0.0.11:7000 10.0.0.12:7000 \
  10.0.0.10:7001 10.0.0.11:7001 10.0.0.12:7001 \
  --cluster-replicas 1

# Cluster'a komut gönder
redis-cli -c -h 10.0.0.10 -p 7000
10.0.0.10:7000> SET user:1 'Ada'
-> Redirected to slot [5798] located at 10.0.0.11:7000
OK

# Yeni master ekle ve resharding yap
redis-cli --cluster add-node 10.0.0.13:7000 10.0.0.10:7000
redis-cli --cluster reshard 10.0.0.10:7000

Cluster modunda dikkat edilmesi gereken nokta: birden fazla key'le çalışan komutlar (MGET, MSET, MULTI/EXEC) sadece tüm key'ler aynı slot'a düşerse çalışır. Aynı slot'a zorlamak için key'lerin içine {tag} eklenir: user:{42}:profile ve user:{42}:sessions aynı node'a düşer.

Memory Yönetimi ve Eviction

Redis'in en büyük üretim hatası: maxmemory ayarlanmamış olarak çalıştırılması. RAM dolduğunda OS sürekli swap'a iner, Redis donar. Mutlaka bir limit ayarlayın ve eviction politikası seçin. redis.io/docs/manual/eviction dokümantasyonu tüm seçenekleri listeler.

  • noeviction — bellek dolunca yazma reddedilir (sadece veri kaybetmemek istediğiniz primary DB kullanımları için)
  • allkeys-lru — en az kullanılan key silinir, tüm key'ler aday (cache için en yaygın)
  • volatile-lru — sadece TTL'li key'lerden LRU
  • allkeys-lfu — en az sıklıkla kullanılan (LRU yerine LFU; sıcak veri belirginse daha iyi)
  • volatile-ttl — yakında expire olacak key öncelikli silinir
  • allkeys-random / volatile-random — rastgele (nadiren tercih)
# redis.conf
maxmemory 4gb
maxmemory-policy allkeys-lru

# Cluster modunda her node'un kendi maxmemory'si var; toplam = node sayısı * limit

Güvenlik: AUTH, ACL, TLS

Redis güvenlik kılavuzuna göre üretim Redis'inin asla doğrudan internete açılmaması gerekir. Ek olarak en az şu üç katman uygulanmalı:

  • protected-mode yes — varsayılan, sadece localhost dinler
  • requirepass ile parola koruması
  • ACL (Redis 6+) ile her uygulamaya kendi kullanıcısı, sadece ihtiyaç duyduğu komut/key prefix'i
  • TLS ile şifreli bağlantı (özellikle managed servislerde zorunlu)
  • bind 127.0.0.1 10.0.0.5 — sadece belirli ağ arayüzlerini dinle
  • rename-command FLUSHALL '' ile yıkıcı komutları kapat
# redis.conf — temel güvenlik
bind 127.0.0.1 10.0.0.5
protected-mode yes
requirepass 'a-very-long-and-random-string-32+chars'

# Yıkıcı komutları kapat
rename-command FLUSHALL ''
rename-command FLUSHDB  ''
rename-command DEBUG    ''
rename-command CONFIG   ''

# TLS
tls-port 6380
port 0
tls-cert-file /etc/redis/tls/redis.crt
tls-key-file  /etc/redis/tls/redis.key
tls-ca-cert-file /etc/redis/tls/ca.crt
tls-auth-clients yes
# ACL — uygulama kullanıcıları
ACL SETUSER app-web on >App!Pass1 ~app:* +@read +@write -@dangerous
ACL SETUSER app-worker on >Wrk!Pass2 ~jobs:* +@stream +@list -@dangerous
ACL SETUSER readonly on >Read!Pass3 ~* +@read -@write

# Tüm kullanıcıları listele
ACL LIST

# Komut gruplarını gör
ACL CAT

Monitoring ve Tanılama

INFO komutu sunucu sağlığı için ilk durağınızdır. SLOWLOG yavaş komutları yakalar. MONITOR tüm komutları gerçek zamanlı yazdırır — sadece geliştirme için, üretimde ciddi performans yükü oluşturur.

# Sağlık özeti
redis-cli INFO server | head
# redis_version:7.2.4
# redis_mode:standalone
# os:Linux 6.8.0-31-generic x86_64
# tcp_port:6379
# uptime_in_seconds:1284923

redis-cli INFO memory | grep used_memory_human
# used_memory_human:1.43G

redis-cli INFO stats | grep -E 'instantaneous_ops|total_connections'
# total_connections_received:184231
# instantaneous_ops_per_sec:8421

# Slow log: 10ms üzeri komutlar
redis-cli CONFIG SET slowlog-log-slower-than 10000
redis-cli SLOWLOG GET 10

# Latency tracker (real-time histogram)
redis-cli --latency-history -i 5

Prometheus ekosistemine taşımak için redis_exporter en yaygın çözümdür. Tek bir Docker container olarak çalışır, /metrics endpoint'i sunar; Grafana üzerinde hazır dashboard'lar mevcuttur.

# docker-compose.yml — redis + exporter
services:
  redis:
    image: redis:7-alpine
    command: redis-server --requirepass ${REDIS_PASS}
    ports: ['6379:6379']

  redis-exporter:
    image: oliver006/redis_exporter
    environment:
      REDIS_ADDR: 'redis://redis:6379'
      REDIS_PASSWORD: ${REDIS_PASS}
    ports: ['9121:9121']

Pipeline, Transaction ve Lua

Birden fazla komutu tek round-trip'te göndermek istiyorsanız üç seçenek vardır:

  • Pipeline: Komutlar sırayla gönderilir, sunucu sırayla cevaplar; arada başka istemci komutu girebilir. En düşük latency için kullanın.
  • MULTI/EXEC (transaction): Komutlar kuyruklanır, EXEC anında atomik olarak yürütülür; arada başka komut çalışmaz. Hata durumunda tek tek komutlar başarısız olabilir, rollback yoktur.
  • Lua script (EVAL): Sunucu tarafında atomik olarak çalışır; karmaşık koşullu mantık için en güçlü seçenek. Redis 7+ ile FUNCTION komutu daha kalıcı bir alternatif sunar.
// Pipeline
const pipe = redis.pipeline();
pipe.set('a', 1);
pipe.incr('a');
pipe.get('a');
const results = await pipe.exec();
// [[null,'OK'],[null,2],[null,'2']]

// Transaction
const tx = redis.multi();
tx.zadd('lb', 100, 'alice');
tx.zadd('lb', 200, 'bob');
await tx.exec();

Yaygın Hatalar ve Tuzaklar

  • KEYS * üretimde asla — tüm key'leri tarar, milyonlarca key'de Redis'i kilitler. SCAN kullanın.
  • FLUSHALL tek satırla tüm veriyi siler. ACL veya rename-command ile kilitleyin.
  • BGSAVE sırasında fork() RAM kullanımını ikiye katlayabilir; cloud'da OOM kill nedeni. Hesapta tutun.
  • Cookie içine session içeriği koyup Redis'e key olarak hash atmak yerine, sadece session ID koyun. Cookie boyutu büyürse her request'te yük artar.
  • Pub/Sub kalıcı değil. Mesaj garantili teslim için Streams + consumer groups kullanın.
  • Aynı bağlantı üzerinde hem normal komut hem SUBSCRIBE çalıştırılamaz; abonelik için ayrı connection açın.
  • TTL'siz cache key'leri RAM'i sızdırır; her cache yazımına bir EX argümanı koyun.
  • Lua script çok uzun olursa sunucuyu bloklar. lua-time-limit aşıldığında script kill edilir; uzun işleri parçalayın.
  • Cluster modunda multi-key komutları için {hashtag} kullanmayı unutmak yaygın hata.
  • MSET key1 val1 key2 val2 bir komutta birçok key set eder, ama pipeline kadar esnek değildir; mantığı anlayıp seçim yapın.

Redis 7.x ile Gelen Önemli Yenilikler

  • Functions: Lua script'lerin yerine geçen, sunucuda kalıcı olarak yüklenebilen fonksiyonlar. Replikasyona katılır; restart sonrası kaybolmaz.
  • Sharded Pub/Sub: Cluster modunda mesajlar her node'a değil, sadece ilgili shard'a iletilir.
  • ACL v2: Channel bazlı izinler, key pattern'larında daha esnek tanımlar.
  • Multi-part AOF: AOF dosyası tek dev dosya yerine birden fazla dosyaya bölündü; rewrite işlemi çok daha verimli.
  • Listpack varsayılan: ziplist tamamen kaldırıldı; küçük list/hash/zset'ler hafıza açısından daha verimli.

Hangi Senaryoda Hangi Setup?

  • Geliştirme / küçük üretim: Tek node, RDB + AOF persistence, requirepass. Tek VPS yeterli.
  • Yüksek erişilebilirlik: 1 master + 2 replica + 3 Sentinel. Otomatik failover; tek node kaybı tolere edilir.
  • Yüksek hacim / büyük dataset: Redis Cluster (3+ master). Sharding + her shard için 1 replica.
  • Serverless veya değişken yük: Upstash veya managed servis. Bağlantı sayısı kontrol altında, idle ücret yok.
  • Modüller (RediSearch, RedisJSON): Redis Stack imajı veya Redis Cloud. Tam metin arama, JSON belge tipi, time-series için.

Modern Yazılım Geliştirme ve DevOps Pratikleri

Profesyonel yazılım geliştirme süreci üç pillar üzerine kuruludur: kaynak kontrolü (Git + GitHub/GitLab pull request akışı, code review zorunlu), CI/CD pipeline (otomatik test + lint + build + deploy), ve gözlemlenebilirlik (Sentry/Datadog/Grafana ile log, metric, trace toplama). Test piramidi (unit > integration > e2e) ile kod kalitesini garantilemek, mikroservis mimarisinde Docker container ve Kubernetes orkestrasyonu kullanmak, REST veya GraphQL API tasarımında OpenAPI/GraphQL Schema sözleşmesi tutmak modern standardlardır. Yazılım geliştirme yaşam döngüsü boyunca (gereksinim → tasarım → implementasyon → test → deploy → bakım) Agile/Scrum sprintleri 1-2 hafta, DevOps takımları sürekli teslim (continuous delivery) prensibiyle çalışır.

Kaynaklar

İlgili Yazılar ve Servisler

Redis'i üretimde doğru kurmak için destek alın

Cache stratejisi, Sentinel/Cluster mimarisi, ACL ve TLS sertleştirme, Prometheus monitoring — Redis altyapınız için danışmanlık ve operasyon desteği için bize yazın

WhatsApp