Redis’te Kalıcı Veri Saklama: RDB ve AOF Yapılandırması

Redis’i production ortamında kullanmaya başladığınızda, ilk etapta her şey güzel görünür. Veriler hızla yazılıp okunuyor, gecikme süreleri minimal, uygulama uçuyor. Ta ki sunucu beklenmedik bir şekilde yeniden başlayana kadar. Eğer kalıcı veri saklama yapılandırmanızı düzgün yapmadıysanız, o ana kadar biriken tüm verileriniz bir anda yok olur. Bu yazıda Redis’in iki temel kalıcılık mekanizması olan RDB ve AOF’u, gerçek dünya senaryoları eşliğinde detaylıca ele alacağız.

Redis Kalıcılık Mekanizmalarını Anlamak

Redis, özünde bir in-memory veritabanıdır. Yani tüm veriler öncelikle RAM’de tutulur. Bu durum Redis’i inanılmaz hızlı yapar ama aynı zamanda veri kaybı riskini de beraberinde getirir. İşte bu riski minimize etmek için Redis iki farklı kalıcılık yöntemi sunar.

RDB (Redis Database Backup) belirli aralıklarla belleğin anlık görüntüsünü (snapshot) diske yazar. Kompakt ve hızlı bir yöntemdir.

AOF (Append Only File) ise her yazma işlemini log dosyasına ekler. Daha fazla disk I/O gerektirir ama çok daha güvenlidir.

Bu ikisi birlikte de kullanılabilir ve production ortamlarında genellikle bu kombinasyon tercih edilir.

RDB: Snapshot Tabanlı Kalıcılık

RDB Nasıl Çalışır?

RDB, belirli koşullar sağlandığında fork() sistem çağrısını kullanarak bir child process oluşturur ve bu child process mevcut bellek durumunu diske yazar. Parent process çalışmaya devam ederken child process arka planda snapshot’ı tamamlar. Bu yaklaşım sayesinde Redis normal operasyonlarını sürdürürken disk yazma işlemi paralel olarak gerçekleşir.

RDB Yapılandırması

Redis konfigürasyon dosyası genellikle /etc/redis/redis.conf yolunda bulunur. RDB ile ilgili temel parametreler şunlardır:

# /etc/redis/redis.conf

# save <saniye> <degisiklik_sayisi>
# Belirtilen süre içinde en az bu kadar anahtar değiştiyse snapshot al
save 900 1       # 15 dakikada en az 1 değişiklik olduysa
save 300 10      # 5 dakikada en az 10 değişiklik olduysa
save 60 10000    # 1 dakikada en az 10000 değişiklik olduysa

# RDB dosyasinin adi
dbfilename dump.rdb

# RDB dosyasinin kaydedilecegi dizin
dir /var/lib/redis

# RDB kaydetme basarisiz olursa yazma islemlerini durdur
stop-writes-on-bgsave-error yes

# RDB dosyasini sikistir (LZF algoritmasi)
rdbcompression yes

# RDB dosyasinin butunlugunu kontrol et
rdbchecksum yes

Buradaki save direktifini biraz daha açalım. save 900 1 şu anlama gelir: Son 900 saniye (15 dakika) içinde en az 1 anahtar değiştiyse snapshot al. Bu üç satır birlikte değerlendirildiğinde Redis, hangisi önce gerçekleşirse o koşula göre snapshot alır.

RDB’yi Manuel Olarak Tetiklemek

Bazen scheduled backup’ların dışında anlık snapshot almak isteyebilirsiniz. Bunun için iki komut kullanılır:

# Redis CLI ile baglanti
redis-cli -h 127.0.0.1 -p 6379

# Asenkron snapshot (tavsiye edilen, Redis calismaya devam eder)
127.0.0.1:6379> BGSAVE

# Senkron snapshot (Redis bu süre boyunca bloke olur - PRODUCTION'DA KULLANMAYIN)
127.0.0.1:6379> SAVE

# Son basarili snapshot'in ne zaman alindigini kontrol et
127.0.0.1:6379> LASTSAVE

BGSAVE komutunu production ortamlarında tercih edin. SAVE komutu Redis’i bloke ettiği için yüksek trafikli sistemlerde ciddi sorunlara yol açabilir.

RDB Dosyasını Doğrulama

RDB dosyasının sağlıklı olup olmadığını kontrol etmek için Redis’in kendi aracını kullanabilirsiniz:

# RDB dosyasini dogrulama
redis-check-rdb /var/lib/redis/dump.rdb

# Cikti ornegi
[offset 0] Checking RDB file dump.rdb
[offset 26] AUX FIELD redis-ver = '7.0.5'
[offset 40] AUX FIELD redis-bits = '64'
[offset 52] AUX FIELD ctime = '1699876543'
[offset 61] AUX FIELD used-mem = '1234567'
[offset 79] Selecting DB ID 0
[offset 12345678] Checksum OK

Eğer dosya bozuksa bu araç size hangi offset’te hata olduğunu bildirecektir.

AOF: Log Tabanlı Kalıcılık

AOF Nasıl Çalışır?

AOF, Redis’e gelen her yazma komutunu (SET, DEL, LPUSH, ZADD vs.) bir log dosyasına ekler. Sistem yeniden başladığında Redis bu log dosyasını baştan sona okuyarak veri setini yeniden oluşturur. Bu yaklaşım RDB’ye göre çok daha az veri kaybına yol açar.

AOF Yapılandırması

# /etc/redis/redis.conf

# AOF'u etkinlestir
appendonly yes

# AOF dosyasinin adi
appendfilename "appendonly.aof"

# AOF dosyasinin kaydedilecegi dizin (dir parametresiyle ayni)
# dir /var/lib/redis

# Fsync politikasi - en kritik parametre
# always: Her yazma isleminde fsync (en guvenli, en yavas)
# everysec: Her saniyede bir fsync (iyi denge)
# no: OS'a birakilir (en hizli, en az guvenli)
appendfsync everysec

# AOF yeniden yazma sirasinda fsync'i durdur
no-appendfsync-on-rewrite no

# AOF yeniden yazma icin minimum boyut
auto-aof-rewrite-min-size 64mb

# AOF boyutu ne kadar büyüdüğünde yeniden yazma tetiklensin (yüzde)
auto-aof-rewrite-percentage 100

Fsync Politikası Seçimi

Bu parametre production ortamınızda alabileceğiniz en kritik kararlardan biridir:

appendfsync always: Her yazma işleminden sonra mutlaka diske yazar. Maksimum veri güvenliği sağlar ama performans açısından en yavaş seçenektir. Saniyede birkaç yüz yazma işlemi yapabilirsiniz genellikle.

appendfsync everysec: Her saniyede bir diske yazar. Bir saniyeye kadar veri kaybı yaşanabilir ama bu çoğu kullanım senaryosu için kabul edilebilirdir. Hem performans hem güvenlik açısından iyi bir denge noktasıdır.

appendfsync no: Fsync işlemini işletim sistemine bırakır. Linux’ta bu genellikle 30 saniyeye kadar uzayabilir. En hızlı seçenektir ama sistem çökmesi durumunda ciddi veri kaybı yaşanabilir.

Yüksek trafikli bir e-ticaret platformu için everysec genellikle doğru tercih olacaktır. Finansal işlemler gibi sıfır veri kaybı toleransı olan sistemler için always düşünülebilir.

AOF Rewrite: Log Dosyasını Küçültmek

AOF dosyası zamanla büyür çünkü her komutu loglar. Örneğin bir sayacı 1000 kez artırdıysanız AOF dosyasında 1000 satır olur. Oysa bu 1000 satırı tek bir SET counter 1000 komutuyla ifade edebilirsiniz. AOF rewrite işte bunu yapar:

# AOF rewrite'i manuel tetikleme
redis-cli BGREWRITEAOF

# Rewrite durumunu izleme
redis-cli INFO persistence | grep aof

auto-aof-rewrite-percentage 100 parametresi şu anlama gelir: AOF dosyası son rewrite’dan bu yana iki katına çıktığında otomatik olarak rewrite tetikle. auto-aof-rewrite-min-size 64mb ise rewrite’ın başlaması için minimum dosya boyutunu belirler. Bu ikisi birlikte çalışır.

AOF Dosyasını Doğrulama ve Onarma

# AOF dosyasini dogrulama
redis-check-aof /var/lib/redis/appendonly.aof

# Bozuk AOF dosyasini onar (son gecersiz komutu siler)
redis-check-aof --fix /var/lib/redis/appendonly.aof

# Onay istemeden onar
redis-check-aof --fix /var/lib/redis/appendonly.aof
# "This will shrink the AOF from X bytes, with X records loss. Continue? [y/N]:" sorusu gelecek

Sistem çöküşlerinden sonra AOF dosyasının son birkaç satırı bozulabilir. --fix seçeneği bu bozuk kısmı keserek geri kalan sağlıklı veriyi kurtarır.

RDB ve AOF Birlikte Kullanmak

Production ortamlarının büyük çoğunluğunda her iki yöntemi birlikte kullanmak en iyi stratejidir. Redis yeniden başladığında hangi dosyayı kullanacağı konusunda belirli bir öncelik sırası vardır: AOF aktifse ve AOF dosyası mevcutsa Redis bunu kullanır. AOF devre dışıysa RDB kullanılır.

# /etc/redis/redis.conf - Hibrit yapilandirma ornegi

# RDB ayarlari
save 900 1
save 300 10
save 60 10000
dbfilename dump.rdb
dir /var/lib/redis
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes

# AOF ayarlari
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

# Genel ayarlar
maxmemory 4gb
maxmemory-policy allkeys-lru

Bu yapılandırmada RDB, hızlı yeniden başlatma için bir taban oluşturur. AOF ise RDB snapshot’ından bu yana yapılan değişiklikleri kaydeder. Sistem yeniden başladığında Redis, RDB’den hızlıca başlar ve sonra AOF’tan kalan değişiklikleri uygular.

Gerçek Dünya Senaryoları

Senaryo 1: E-Ticaret Oturumu Yönetimi

Bir e-ticaret sitesinde kullanıcı oturumlarını Redis’te saklıyorsunuz. Her gün ortalama 50.000 aktif oturum var ve kullanıcılar sepetlerini bu oturumlarda tutuyor.

Bu senaryoda maksimum 1 saniye veri kaybı kabul edilebilir ama sıfır kabul edilemez çünkü dolu sepetler önemli gelir temsil eder. Aşağıdaki yapılandırma uygundur:

# /etc/redis/redis.conf - E-ticaret oturum yonetimi

save 300 100     # 5 dakikada 100 degisiklik
save 60 1000     # 1 dakikada 1000 degisiklik

appendonly yes
appendfsync everysec
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 128mb

maxmemory 8gb
maxmemory-policy volatile-lru  # Sadece expire suresi olan anahtarlari sil

Senaryo 2: Gerçek Zamanlı Skor Tablosu

Bir oyun platformunda milyonlarca kullanıcının anlık skorlarını saklıyorsunuz. Kısa süreli veri kaybı tolere edilebilir çünkü skorlar oyun sunucusundan yeniden alınabilir.

# /etc/redis/redis.conf - Skor tablosu (performans odakli)

save 900 1
save 300 1000
# Cok sik snapshot alma, yuk fazla

appendonly yes
appendfsync no   # OS'a birak, hiz oncelikli
auto-aof-rewrite-percentage 200
auto-aof-rewrite-min-size 256mb

maxmemory 16gb
maxmemory-policy allkeys-lru

Senaryo 3: Monitoring ve Backup Script

Production ortamında Redis kalıcılığını izlemek ve düzenli yedek almak için bir script yazalım:

#!/bin/bash
# /usr/local/bin/redis-backup.sh

REDIS_CLI="/usr/bin/redis-cli"
BACKUP_DIR="/backup/redis"
DATE=$(date +%Y%m%d_%H%M%S)
LOG_FILE="/var/log/redis-backup.log"

log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
}

# Redis'in calisiyor olup olmadigini kontrol et
if ! $REDIS_CLI ping > /dev/null 2>&1; then
    log "HATA: Redis'e baglanilamiyor!"
    exit 1
fi

# Backup dizini yoksa olustur
mkdir -p "$BACKUP_DIR"

# BGSAVE tetikle
log "BGSAVE baslatiliyor..."
$REDIS_CLI BGSAVE

# BGSAVE tamamlanmasini bekle
while [ "$($REDIS_CLI LASTSAVE)" == "$LAST_SAVE" ]; do
    sleep 1
done

LAST_SAVE=$($REDIS_CLI LASTSAVE)
log "BGSAVE tamamlandi. Son kayit: $LAST_SAVE"

# RDB dosyasini kopyala
cp /var/lib/redis/dump.rdb "$BACKUP_DIR/dump_$DATE.rdb"

# AOF dosyasini kopyala (aktifse)
if [ -f /var/lib/redis/appendonly.aof ]; then
    cp /var/lib/redis/appendonly.aof "$BACKUP_DIR/appendonly_$DATE.aof"
    log "AOF dosyasi yedeklendi."
fi

# 7 günden eski yedekleri sil
find "$BACKUP_DIR" -name "*.rdb" -mtime +7 -delete
find "$BACKUP_DIR" -name "*.aof" -mtime +7 -delete

log "Yedekleme tamamlandi: $BACKUP_DIR/dump_$DATE.rdb"

# Persistence durumunu raporla
PERSISTENCE_INFO=$($REDIS_CLI INFO persistence)
log "Persistence Durumu:"
echo "$PERSISTENCE_INFO" | grep -E "rdb_|aof_" | while read line; do
    log "  $line"
done

Bu scripti crontab’a ekleyerek otomatik hale getirebilirsiniz:

# Crontab - her saat basi yedek al
crontab -e

# Her saat basi yedekleme
0 * * * * /usr/local/bin/redis-backup.sh

# Scripti calistirilebilir yap
chmod +x /usr/local/bin/redis-backup.sh

Senaryo 4: Redis Persistence Durumunu İzlemek

Sistemin sağlığını düzenli olarak kontrol etmek için:

#!/bin/bash
# Redis persistence saglik kontrolu

REDIS_CLI="redis-cli"

echo "=== Redis Persistence Saglik Raporu ==="
echo ""

# RDB bilgileri
echo "--- RDB Durumu ---"
$REDIS_CLI INFO persistence | grep -E "rdb_" | while IFS=: read key value; do
    echo "  $key: $value"
done

echo ""

# AOF bilgileri
echo "--- AOF Durumu ---"
$REDIS_CLI INFO persistence | grep -E "aof_" | while IFS=: read key value; do
    echo "  $key: $value"
done

echo ""

# Bellek kullanimi
echo "--- Bellek Kullanimi ---"
$REDIS_CLI INFO memory | grep -E "used_memory_human|maxmemory_human|mem_fragmentation_ratio" | while IFS=: read key value; do
    echo "  $key: $value"
done

echo ""

# Son RDB kaydi
LAST_SAVE=$($REDIS_CLI LASTSAVE)
LAST_SAVE_DATE=$(date -d @$LAST_SAVE '+%Y-%m-%d %H:%M:%S')
echo "Son RDB Kaydi: $LAST_SAVE_DATE"

# Dosya boyutlari
echo ""
echo "--- Dosya Boyutlari ---"
ls -lh /var/lib/redis/dump.rdb 2>/dev/null && echo "" || echo "  RDB dosyasi bulunamadi"
ls -lh /var/lib/redis/appendonly.aof 2>/dev/null || echo "  AOF dosyasi bulunamadi"

Performans Optimizasyonu İpuçları

Disk I/O Optimizasyonu

RDB ve AOF dosyalarını mümkünse ayrı disk bölümlerine yerleştirmek I/O çakışmalarını azaltır. Production ortamında SSD kullanmak AOF performansını önemli ölçüde artırır.

# RDB ve AOF icin farkli dizin kullanma (redis.conf)
# Normalde ikisi de dir parametresindeki dizine gider
# Ayirmak icin sembolik link veya mount point kullanabilirsiniz

# Ornek: AOF icin ayri mount point
mkdir -p /mnt/ssd-fast/redis-aof
ln -s /mnt/ssd-fast/redis-aof /var/lib/redis/aof

Fork Süresi ve Büyük Veri Setleri

RDB snapshot ve AOF rewrite işlemleri sırasında Redis fork() çağrısı yapar. Büyük veri setlerinde bu fork işlemi zaman alabilir. Bunu izlemek için:

# Fork süresini kontrol et
redis-cli INFO stats | grep latest_fork_usec

# Cikti ornegi: latest_fork_usec:1500
# 1500 mikrosaniye = 1.5 milisaniye (kabul edilebilir)
# 10000+ mikrosaniye ise dikkat etmek gerekir

Linux Kernel Ayarları

Redis production ortamları için bazı kernel ayarları önemlidir:

# /etc/sysctl.conf veya /etc/sysctl.d/redis.conf

# Overcommit memory - Redis fork islemi icin gerekli
vm.overcommit_memory = 1

# Transparent Huge Pages'i kapat (Redis performansini etkiler)
echo never > /sys/kernel/mm/transparent_hugepage/enabled

# Kalici yapmak icin rc.local veya systemd service kullanin

Felaket Kurtarma Prosedürü

Her şey planlandığı gibi gitmediğinde ne yapacağınızı bilmeniz gerekir. İşte temel bir kurtarma prosedürü:

# 1. Redis'i durdur
systemctl stop redis

# 2. Mevcut bozuk dosyalari yedekle
mv /var/lib/redis/dump.rdb /var/lib/redis/dump.rdb.bozuk
mv /var/lib/redis/appendonly.aof /var/lib/redis/appendonly.aof.bozuk

# 3. Yedekten geri yukle
cp /backup/redis/dump_20231114_120000.rdb /var/lib/redis/dump.rdb
cp /backup/redis/appendonly_20231114_120000.aof /var/lib/redis/appendonly.aof

# 4. Dosya sahipligini duzenle
chown redis:redis /var/lib/redis/dump.rdb
chown redis:redis /var/lib/redis/appendonly.aof

# 5. AOF dosyasini dogrula ve gerekirse onar
redis-check-aof --fix /var/lib/redis/appendonly.aof

# 6. RDB dosyasini dogrula
redis-check-rdb /var/lib/redis/dump.rdb

# 7. Redis'i baslat
systemctl start redis

# 8. Veri dogrulama
redis-cli DBSIZE
redis-cli INFO keyspace

Sonuç

Redis kalıcılık yapılandırması, tek doğru cevabı olmayan bir konudur. Her sistem farklı gereksinimler taşır ve doğru yapılandırma bu gereksinimlere göre şekillenir.

Genel önerim şu yönde: Eğer Redis’i bir cache olarak kullanıyorsanız ve veriler başka bir kaynaktan yeniden doldurulabiliyorsa, RDB tek başına yeterli olabilir. Ama Redis’i birincil veri deposu olarak kullanıyorsanız veya veri kaybı ciddi sonuçlar doğuruyorsa, RDB ve AOF’u birlikte kullanın.

appendfsync everysec ayarı çoğu production ortamı için sağlıklı bir başlangıç noktasıdır. Hem makul bir güvenlik seviyesi sunar hem de performansı gereksiz yere feda etmez. Zamanla sistemin davranışını izleyerek ve gerçek ihtiyaçları anlayarak bu ayarları rafine edebilirsiniz.

Son olarak, hangi yapılandırmayı seçerseniz seçin, yedeklerinizi düzenli olarak test edin. En iyi backup sistemi, geri yükleme testinden geçmiş olandır. Bir felaket anında ilk kez geri yükleme yapmaya çalışmak yerine, bunu periyodik olarak tatbikat yaparak prova etmek hayat kurtarır.

Yorum yapın