Performans Analizi: redis-cli ile Redis Monitoring

Redis cluster’ınız yavaşladığında, memory kullanımı patladığında ya da uygulama ekibinden “neden bu kadar yavaş?” sorusu geldiğinde, ilk başvuracağınız yer redis-cli olmalı. Bu yazıda, Redis performans analizini gerçek dünya senaryoları üzerinden ele alacağız ve redis-cli‘ın monitoring yeteneklerini derinlemesine inceleyeceğiz.

Temel Monitoring Komutlarına Giriş

Redis’in durumunu anlık olarak görmek için INFO komutu altın değerindedir. Tek başına çalıştırdığınızda devasa bir çıktı verir, ama bölüm bazında da kullanabilirsiniz.

# Tüm bilgileri getir
redis-cli INFO

# Sadece server bilgileri
redis-cli INFO server

# Sadece memory bilgileri
redis-cli INFO memory

# Sadece stats bilgileri
redis-cli INFO stats

# Sadece replication durumu
redis-cli INFO replication

# Sadece keyspace bilgileri
redis-cli INFO keyspace

Şimdi bu çıktıların içinden gerçekten önemli olan metriklere odaklanalım.

Memory Kullanımını Analiz Etmek

Bir gün sabah 9’da uyarı aldınız: “Redis memory yüzde 90’a ulaştı.” İşte o anda ne yapmanız gerektiğini anlatalım.

redis-cli INFO memory | grep -E "used_memory_human|used_memory_peak_human|mem_fragmentation_ratio|maxmemory_human"

Bu komutun çıktısından dikkat etmeniz gereken değerler şunlar:

  • used_memory_human: Şu an kullanılan gerçek memory miktarı
  • used_memory_peak_human: Tarihsel en yüksek memory kullanımı
  • mem_fragmentation_ratio: Memory parçalanma oranı, 1.0 ile 1.5 arası normal, 1.5 üzeri sorun sinyali
  • maxmemory_human: Tanımlı maksimum memory limiti

mem_fragmentation_ratio değeri 1.5’i geçiyorsa, Redis’in işletim sistemine geri vermediği boş memory blokları var demektir. Bu durumda şu adımı deneyebilirsiniz:

# Memory defragmentation'ı aktif et (Redis 4.0+)
redis-cli CONFIG SET activedefrag yes
redis-cli CONFIG SET active-defrag-ignore-bytes 100mb
redis-cli CONFIG SET active-defrag-threshold-lower 10

Gerçek Zamanlı Monitoring

redis-cli --stat komutu, saniye saniye güncellenen bir monitoring ekranı sunar. Production ortamında bir şeyler ters gittiğinde bu komut hayat kurtarır.

# Her saniye güncellenen istatistikler
redis-cli --stat

# Her 2 saniyede bir güncelle
redis-cli --stat -i 2

Çıktıda şu sütunlara dikkat edin:

  • keys: Toplam key sayısı
  • mem: Kullanılan memory
  • clients: Bağlı client sayısı
  • blocked: Bloklanmış client sayısı (bu sıfır olmalı idealde)
  • requests: Saniyedeki istek sayısı
  • connections: Toplam bağlantı sayısı

Blocked client sayısı sürekli artıyorsa, BLPOP veya BRPOP gibi blocking komutlar kullanan işlemleriniz var ve bunlar beklediği key’leri alamıyor demektir.

Latency Analizi

Uygulamanızın Redis’ten gelen yanıt sürelerinde tutarsızlıklar yaşandığını düşünüyorsunuz. İşte latency analizi için araçlarınız:

# Latency monitoring'i aktif et
redis-cli CONFIG SET latency-monitor-threshold 10

# Latency geçmişini görüntüle
redis-cli LATENCY HISTORY event

# Son latency olaylarını listele
redis-cli LATENCY LATEST

# Latency grafiğini ASCII olarak göster
redis-cli LATENCY GRAPH event

# Latency istatistiklerini sıfırla
redis-cli LATENCY RESET

Gerçek bir senaryo: E-ticaret platformumuzun checkout sayfası zaman zaman 2-3 saniye gecikmeyle yanıt veriyordu. LATENCY LATEST komutu bize şunu gösterdi: command event için max latency 450ms’e çıkmıştı. Sonradan anlaşıldı ki, bir geliştirici KEYS * komutunu production üzerinde çalıştıran bir script yazmış ve bu komut her çalıştığında tüm Redis’i bloke ediyordu.

Yavaş Sorgu Analizi

KEYS * örneğini verince, yavaş sorgu loglamasından bahsetmemek olmaz.

# Slowlog threshold'u ayarla (mikrosaniye cinsinden, 10000 = 10ms)
redis-cli CONFIG SET slowlog-log-slower-than 10000

# Slowlog maksimum boyutunu ayarla
redis-cli CONFIG SET slowlog-max-len 128

# Mevcut slowlog kayıtlarını görüntüle
redis-cli SLOWLOG GET

# Son 10 yavaş komutu göster
redis-cli SLOWLOG GET 10

# Toplam slowlog kayıt sayısını öğren
redis-cli SLOWLOG LEN

# Slowlog'u temizle
redis-cli SLOWLOG RESET

SLOWLOG GET çıktısını parse etmek için şu bash scriptini kullanabilirsiniz:

#!/bin/bash
# slowlog_analyzer.sh - Redis slowlog analizi

REDIS_HOST=${1:-localhost}
REDIS_PORT=${2:-6379}

echo "=== Redis Slowlog Analizi ==="
echo "Host: $REDIS_HOST:$REDIS_PORT"
echo "Tarih: $(date)"
echo ""

# Toplam yavaş sorgu sayısı
TOTAL=$(redis-cli -h $REDIS_HOST -p $REDIS_PORT SLOWLOG LEN)
echo "Toplam yavaş sorgu sayısı: $TOTAL"
echo ""

# Son 20 yavaş sorguyu getir ve formatla
echo "=== Son Yavaş Sorgular ==="
redis-cli -h $REDIS_HOST -p $REDIS_PORT SLOWLOG GET 20 | 
  awk '
    /^[0-9]+)/ { id=$2 }
    /microseconds/ { time=$2 }
    /command/ { cmd=$2 }
    { print }
  '

Key Analizi ve Büyük Key Tespiti

Redis’te memory problemi yaşıyorsanız, büyük keyleri bulmak kritik önem taşır. Redis 4.0 ile gelen --bigkeys parametresi bu iş için biçilmiş kaftan:

# Büyük keyleri bul (production'da dikkatli kullanın, scan tabanlı çalışır)
redis-cli --bigkeys

# Belirli bir örnekleme oranıyla tara
redis-cli --bigkeys --i 0.1

# Belirli bir pattern'a göre analiz et
redis-cli --bigkeys --pattern "user:*"

Önemli uyarı: --bigkeys komutu arka planda SCAN kullanır, yani production’da çalıştırmak güvenlidir ama yoğun trafik anlarında yine de dikkatli olun. Bekleme süresi eklemek için -i parametresini kullanın: -i 0.1 her 100 komut arasına 0.1 saniye bekletir.

Daha gelişmiş key analizi için --memkeys parametresi Redis 7.0 ile geldi:

# Her key'in memory kullanımını analiz et
redis-cli --memkeys

# Belirli bir pattern için memory analizi
redis-cli --memkeys --pattern "session:*"

Key Expiry ve TTL Analizi

Bir sabah Redis’inizdeki key sayısının sürekli arttığını fark ettiniz. TTL analizi yapma zamanı:

# Keyspace istatistiklerini gör
redis-cli INFO keyspace

# Belirli bir key'in TTL'ini kontrol et
redis-cli TTL "kullanici:12345:session"

# TTL'siz (kalıcı) keyleri bul - dikkatli kullanın!
redis-cli --scan --pattern "*" | while read key; do
  ttl=$(redis-cli TTL "$key")
  if [ "$ttl" == "-1" ]; then
    echo "Kalıcı key: $key"
  fi
done

Yukarıdaki script production’da binlerce key varsa çok yavaş çalışır. Daha verimli bir yaklaşım için SCAN komutunu doğrudan kullanın:

#!/bin/bash
# ttl_analyzer.sh - TTL analizi

CURSOR=0
NO_TTL_COUNT=0
EXPIRED_COUNT=0

echo "TTL analizi başlıyor..."

while true; do
  RESULT=$(redis-cli SCAN $CURSOR COUNT 100)
  CURSOR=$(echo "$RESULT" | head -1)
  KEYS=$(echo "$RESULT" | tail -n +2)
  
  while IFS= read -r key; do
    TTL=$(redis-cli TTL "$key")
    if [ "$TTL" == "-1" ]; then
      ((NO_TTL_COUNT++))
    elif [ "$TTL" == "-2" ]; then
      ((EXPIRED_COUNT++))
    fi
  done <<< "$KEYS"
  
  if [ "$CURSOR" == "0" ]; then
    break
  fi
done

echo "TTL'siz key sayısı: $NO_TTL_COUNT"
echo "Süresi dolmuş key sayısı: $EXPIRED_COUNT"

Bağlantı ve Client Analizi

“Redis’e bağlanamıyoruz” şikayetiyle karşılaştığınızda, client listesini incelemeniz gerekir.

# Bağlı tüm clientları listele
redis-cli CLIENT LIST

# Client sayısını öğren
redis-cli CLIENT INFO

# Belirli bir client'ı ID ile getir
redis-cli CLIENT GETNAME

# Uzun süredir idle olan bağlantıları bul
redis-cli CLIENT LIST | grep -v "idle=0 "

# En uzun idle client'ları bul
redis-cli CLIENT LIST | awk -F'[= ]' '{for(i=1;i<=NF;i++) if($i=="idle") print $(i+1), $0}' | sort -rn | head -10

Client listesinde dikkat etmeniz gereken alanlar:

  • cmd: Son çalıştırılan komut
  • idle: Kaç saniyedir idle durumda
  • age: Bağlantının kaç saniyedir açık olduğu
  • flags: Client durumu (b=blocked, x=executing, t=watching)
  • multi: Multi/exec transaction içinde bekleyen komut sayısı

Gerçek senaryo: Bir Node.js uygulamasında connection pool yanlış yapılandırılmıştı ve her istek yeni bir Redis bağlantısı açıyordu. CLIENT LIST çıktısında 1200’ü aşkın bağlantı gördük. Redis default olarak 10000 bağlantı limitine sahiptir ama bu kadar bağlantı zaten performansı mahvediyordu.

# Mevcut bağlantı limitini kontrol et
redis-cli CONFIG GET maxclients

# Bağlantı limitini değiştir
redis-cli CONFIG SET maxclients 500

# Belirli bir IP'den gelen bağlantıları say
redis-cli CLIENT LIST | grep "addr=192.168.1.100" | wc -l

Hit/Miss Oranı ve Cache Etkinliği

Redis’in önbellek olarak ne kadar verimli çalıştığını anlamak için hit/miss oranına bakmanız gerekir.

# Cache hit ve miss istatistikleri
redis-cli INFO stats | grep -E "keyspace_hits|keyspace_misses"

Bu değerlerden hit oranını hesaplamak için:

#!/bin/bash
# cache_efficiency.sh - Cache etkinlik hesaplama

HITS=$(redis-cli INFO stats | grep keyspace_hits | awk -F: '{print $2}' | tr -d 'r')
MISSES=$(redis-cli INFO stats | grep keyspace_misses | awk -F: '{print $2}' | tr -d 'r')
TOTAL=$((HITS + MISSES))

if [ $TOTAL -gt 0 ]; then
  HIT_RATE=$(echo "scale=2; $HITS * 100 / $TOTAL" | bc)
  echo "Cache Hit Oranı: %$HIT_RATE"
  echo "Toplam İstek: $TOTAL"
  echo "Hit: $HITS"
  echo "Miss: $MISSES"
  
  if (( $(echo "$HIT_RATE < 80" | bc -l) )); then
    echo "UYARI: Hit oranı %80'in altında! Cache stratejinizi gözden geçirin."
  fi
else
  echo "Henüz istek istatistiği yok"
fi

İdeal hit oranı uygulamaya göre değişir ama genel kural şudur: %80’in altındaysanız cache stratejinizi gözden geçirin. %60’ın altındaysanız Redis’in size çok fazla fayda sağlamadığını düşünebilirsiniz.

Replication Durumu Monitoring

Master-Slave Redis kurulumunda replikasyon lag’ı kritik bir metriktir:

# Replication bilgilerini getir
redis-cli INFO replication

# Slave'lerin durumunu izle
redis-cli INFO replication | grep -E "slave[0-9]+:|master_repl_offset|slave_repl_offset"

Replication lag hesaplamak için:

#!/bin/bash
# replication_lag.sh - Replikasyon gecikmesi kontrolü

MASTER_HOST="192.168.1.10"
SLAVE_HOST="192.168.1.11"
REDIS_PORT=6379

MASTER_OFFSET=$(redis-cli -h $MASTER_HOST -p $REDIS_PORT INFO replication | grep master_repl_offset | awk -F: '{print $2}' | tr -d 'r')
SLAVE_OFFSET=$(redis-cli -h $SLAVE_HOST -p $REDIS_PORT INFO replication | grep slave_repl_offset | awk -F: '{print $2}' | tr -d 'r')

LAG=$((MASTER_OFFSET - SLAVE_OFFSET))
echo "Master Offset: $MASTER_OFFSET"
echo "Slave Offset: $SLAVE_OFFSET"
echo "Replikasyon Lag (byte): $LAG"

if [ $LAG -gt 1000000 ]; then
  echo "KRITIK: Replikasyon lag 1MB'ı aştı!"
elif [ $LAG -gt 100000 ]; then
  echo "UYARI: Replikasyon lag 100KB'ı aştı."
else
  echo "OK: Replikasyon sağlıklı görünüyor."
fi

Ops/Sec ve Throughput Analizi

Saniyede kaç komut işlendiğini takip etmek, capacity planning açısından önemlidir:

# Anlık işlem istatistikleri
redis-cli INFO stats | grep -E "total_commands_processed|instantaneous_ops_per_sec|total_net_input_bytes|total_net_output_bytes"

instantaneous_ops_per_sec değeri anlık olarak saniyedeki komut sayısını verir. Bu değer normal yükte beklenenden çok yüksekse, bir runaway process veya döngü içinde Redis’i çağıran bir bug olabilir.

Monitor Komutu ile Anlık Debug

Çok dikkatli kullanın: MONITOR komutu, Redis’e gelen tüm komutları gerçek zamanlı olarak gösterir. Production’da kısa süreli debug için kullanılabilir ama uzun süre açık bırakırsanız performansı yarı yarıya düşürebilir.

# Tüm komutları izle (Ctrl+C ile durdur)
redis-cli MONITOR

# Sadece belirli bir pattern içeren komutları filtrele
redis-cli MONITOR | grep "user:"

# 10 saniye boyunca izle ve dosyaya kaydet
timeout 10 redis-cli MONITOR > /tmp/redis_monitor_$(date +%Y%m%d_%H%M%S).log

# Hangi komutlar en çok kullanılıyor?
timeout 30 redis-cli MONITOR | awk '{print $3}' | sort | uniq -c | sort -rn | head -20

Kapsamlı Monitoring Script’i

Tüm bu komutları bir araya getiren, cronjob ile çalıştırılabilecek bir monitoring scripti:

#!/bin/bash
# redis_health_check.sh - Kapsamlı Redis sağlık kontrolü
# Kullanım: ./redis_health_check.sh [host] [port]

REDIS_HOST=${1:-localhost}
REDIS_PORT=${2:-6379}
LOG_FILE="/var/log/redis_health_$(date +%Y%m%d).log"
ALERT_EMAIL="[email protected]"
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')

log() {
  echo "[$TIMESTAMP] $1" | tee -a $LOG_FILE
}

alert() {
  log "UYARI: $1"
  echo "Redis Uyarısı: $1" | mail -s "Redis Alert - $REDIS_HOST" $ALERT_EMAIL 2>/dev/null
}

# Redis erişilebilirlik kontrolü
PING_RESULT=$(redis-cli -h $REDIS_HOST -p $REDIS_PORT PING 2>/dev/null)
if [ "$PING_RESULT" != "PONG" ]; then
  alert "Redis $REDIS_HOST:$REDIS_PORT erişilemiyor!"
  exit 1
fi

log "Redis bağlantısı OK"

# Memory kontrolü
USED_MEM=$(redis-cli -h $REDIS_HOST -p $REDIS_PORT INFO memory | grep used_memory: | awk -F: '{print $2}' | tr -d 'r')
MAX_MEM=$(redis-cli -h $REDIS_HOST -p $REDIS_PORT CONFIG GET maxmemory | tail -1)
FRAG_RATIO=$(redis-cli -h $REDIS_HOST -p $REDIS_PORT INFO memory | grep mem_fragmentation_ratio | awk -F: '{print $2}' | tr -d 'r')

log "Kullanılan Memory: $(redis-cli -h $REDIS_HOST -p $REDIS_PORT INFO memory | grep used_memory_human | awk -F: '{print $2}' | tr -d 'r')"
log "Fragmentation Ratio: $FRAG_RATIO"

# Fragmentation uyarısı
if (( $(echo "$FRAG_RATIO > 1.5" | bc -l) )); then
  alert "Memory fragmentation ratio yüksek: $FRAG_RATIO"
fi

# Hit oranı kontrolü
HITS=$(redis-cli -h $REDIS_HOST -p $REDIS_PORT INFO stats | grep keyspace_hits | awk -F: '{print $2}' | tr -d 'r')
MISSES=$(redis-cli -h $REDIS_HOST -p $REDIS_PORT INFO stats | grep keyspace_misses | awk -F: '{print $2}' | tr -d 'r')
TOTAL=$((HITS + MISSES))

if [ $TOTAL -gt 0 ]; then
  HIT_RATE=$(echo "scale=2; $HITS * 100 / $TOTAL" | bc)
  log "Cache Hit Oranı: %$HIT_RATE"
  if (( $(echo "$HIT_RATE < 70" | bc -l) )); then
    alert "Cache hit oranı düşük: %$HIT_RATE"
  fi
fi

# Client sayısı
CONNECTED_CLIENTS=$(redis-cli -h $REDIS_HOST -p $REDIS_PORT INFO clients | grep connected_clients | awk -F: '{print $2}' | tr -d 'r')
log "Bağlı Client Sayısı: $CONNECTED_CLIENTS"

if [ "$CONNECTED_CLIENTS" -gt 1000 ]; then
  alert "Bağlı client sayısı yüksek: $CONNECTED_CLIENTS"
fi

# Slowlog kontrolü
SLOW_COUNT=$(redis-cli -h $REDIS_HOST -p $REDIS_PORT SLOWLOG LEN)
log "Slowlog Kayıt Sayısı: $SLOW_COUNT"

if [ "$SLOW_COUNT" -gt 50 ]; then
  alert "Çok fazla yavaş sorgu tespit edildi: $SLOW_COUNT kayıt"
fi

log "Health check tamamlandı"

Bu scripti crontab’a eklemek için:

# Her 5 dakikada bir çalıştır
*/5 * * * * /usr/local/bin/redis_health_check.sh redis-server.local 6379

Sonuç

redis-cli, sadece basit get/set işlemleri için bir araç değil, güçlü bir performans analizi ve monitoring platformudur. Bu yazıda ele aldığımız konuları özetleyecek olursak:

  • INFO komutu ve alt bölümleri, anlık durum değerlendirmesi için temel başlangıç noktanızdır.
  • –stat parametresi, gerçek zamanlı metrik takibi için idealdir.
  • LATENCY komutları, ani yavaşlamaların kaynağını bulmayı sağlar.
  • SLOWLOG, kötü yazılmış komutları yakalamanızın en etkili yoludur.
  • –bigkeys ve –memkeys, memory problemlerinin kaynağını tespit etmenizi kolaylaştırır.
  • CLIENT LIST, bağlantı problemlerini ve connection leak’lerini ortaya çıkarır.
  • MONITOR, kısa süreli debug için vazgeçilmezdir, ama production’da dikkatli kullanılmalıdır.

Redis monitoring’i reaktif değil, proaktif yapmanın püf noktası şudur: Bu scriptleri ve komutları bir şeyler bozulmadan önce düzenli çalıştırmak, baseline değerler oluşturmak ve anormalliklerden erken haberdar olmak. Bir anomali gördüğünüzde “normal” değerin ne olduğunu biliyorsanız, sorunu çok daha hızlı çözersiniz. Grafana + Prometheus + Redis Exporter kombinasyonu uzun vadeli monitoring için harika bir seçenek, ama redis-cli ile yapabileceğiniz anlık analizler hiçbir zaman değerini yitirmiyor.

Yorum yapın