Yüksek Erişilebilirlik ile Felaket Kurtarma Arasındaki Fark

Bir gece saat 03:00’te telefon çalıyor. Veritabanı sunucusu çökmüş. Panikle sisteme bağlanmaya çalışıyorsun ama bir yandan aklında şu soru dönüyor: “Biz HA kurmuştuk, neden hala buradayım?” İşte bu sorunun cevabı, HA ve DR arasındaki farkı anlamamaktan geliyor. Bu yazıda ikisini net bir şekilde ayırt edeceğiz ve gerçek dünya senaryolarıyla ne zaman hangisine ihtiyaç duyduğunu göstereceğiz.

Temel Kavramlar: HA ve DR Nedir?

Yüksek Erişilebilirlik (High Availability – HA), sistemlerin planlı veya plansız kesintiler sırasında çalışmaya devam etmesini sağlamak için tasarlanmış mimaridir. Temel hedefi, downtime’ı sıfıra yaklaştırmaktır. Bir düğüm düşerse, diğeri otomatik olarak devreye girer. Saniyeler, belki birkaç dakika içinde.

Felaket Kurtarma (Disaster Recovery – DR), ise daha büyük ölçekli olaylar için hazırlıktır. Veri merkezi yangını, sel, büyük siber saldırı, bölgesel internet kesintisi gibi durumlarda iş sürekliliğini korumak için kullanılır. Burada kurtarma süresi saatler, hatta günler olabilir. Ve bu tamamen kabul edilebilirdir, eğer RTO/RPO hedefleriniz buna izin veriyorsa.

İkisini karıştıran sistemcilerin yaptığı en yaygın hata şu: “Zaten Kubernetes cluster’ımız var, DR’a gerek yok.” Hayır, Kubernetes HA sağlar. Ama tüm cluster bir veri merkezinde yanıyorsa, o Kubernetes sana ne faydası var?

RTO ve RPO: Her Şeyin Temelindeki İki Metrik

HA ve DR tartışmalarında iki kavram sürekli karşına çıkar:

RTO (Recovery Time Objective): Bir kesinti sonrasında sistemin tekrar çalışır hale gelmesi için kabul edilen maksimum süre. “Sistemimiz en fazla 4 saat downtime yaşayabilir” diyorsan, RTO’n 4 saattir.

RPO (Recovery Point Objective): Bir kesinti sonrasında kabul edebileceğin maksimum veri kaybı miktarı. “Son 1 saatlik veriden vazgeçebiliriz” diyorsan, RPO’n 1 saattir.

HA sistemleri genellikle düşük RTO ve neredeyse sıfır RPO hedefler. Bir failover olduğunda belki 30 saniye, belki 2 dakika kesinti yaşarsın. Veri kaybı ise senkron replikasyon kullanıyorsan sıfırdır.

DR sistemleri ise daha geniş RTO/RPO toleransıyla çalışır. Kritik sistemler için RTO 4 saat, RPO 1 saat olabilir. Daha az kritik sistemler için bu değerler 24 saate kadar çıkabilir. Ve bu tamamen normal.

HA Mimarisi Nasıl Çalışır?

HA’nın temeli redundancy (artıklık) ve otomatik failover‘dır. Klasik bir HA kurulumu şöyle görünür:

Keepalived ile Basit HA Kurulumu

İki sunucu arasında sanal IP (VIP) paylaşımı için Keepalived kullanabilirsin:

# Master sunucuda /etc/keepalived/keepalived.conf
vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass gizlisifre123
    }
    virtual_ipaddress {
        192.168.1.100/24
    }
    notify_master "/etc/keepalived/notify.sh MASTER"
    notify_backup "/etc/keepalived/notify.sh BACKUP"
    notify_fault "/etc/keepalived/notify.sh FAULT"
}
# Backup sunucuda aynı config, sadece şu iki satır farklı:
state BACKUP
priority 90
# Diğer her şey aynı

Bu yapıda master sunucu düşerse, backup otomatik olarak VIP’yi üstlenir. Kullanıcılar fark bile etmez. İşte bu HA.

PostgreSQL Streaming Replication ile HA

Veritabanı katmanında HA için PostgreSQL’in kendi replikasyon mekanizmasını kullanabilirsin:

# Primary sunucuda postgresql.conf ayarları
wal_level = replica
max_wal_senders = 3
wal_keep_size = 1GB
synchronous_commit = on
synchronous_standby_names = 'standby1'

# Primary'de replication kullanıcısı oluştur
psql -c "CREATE USER replicator REPLICATION LOGIN ENCRYPTED PASSWORD 'reppass';"

# pg_hba.conf'a ekle
echo "host replication replicator 192.168.1.0/24 md5" >> /etc/postgresql/15/main/pg_hba.conf
# Standby sunucuda base backup al ve başlat
pg_basebackup -h 192.168.1.10 -D /var/lib/postgresql/15/main 
  -U replicator -P -Xs -R

# standby.signal dosyası pg_basebackup -R ile otomatik oluşturulur
# postgresql.auto.conf içinde primary_conninfo da otomatik ayarlanır

# Replikasyon durumunu kontrol et
psql -c "SELECT client_addr, state, sent_lsn, write_lsn, flush_lsn, replay_lsn FROM pg_stat_replication;"

Burada synchronous_commit = on ayarı kritiktir. Senkron modda, bir transaction standby’a yazılmadan commit başarılı sayılmaz. Bu sıfır RPO sağlar ama biraz latency ekler.

DR Altyapısı Nasıl Çalışır?

DR, HA’dan hem kapsam hem de hedef açısından farklıdır. DR’da asıl soru şudur: “Her şey yansa, her şey silinse, işi nasıl ayağa kaldırırım?”

3-2-1 Yedekleme Kuralı ve DR’ın Temeli

DR planının temelinde yedekleme stratejisi yatar. 3-2-1 kuralı hala geçerliliğini korur:

  • 3 kopya veri tut
  • 2 farklı ortam kullan (disk + bulut gibi)
  • 1 kopya farklı coğrafi konumda olsun
# rsync ile uzak sunucuya yedek gönderme scripti
#!/bin/bash

BACKUP_DATE=$(date +%Y%m%d_%H%M%S)
SOURCE="/var/lib/mysql"
DEST_LOCAL="/backup/mysql"
DEST_REMOTE="[email protected]:/backup/mysql"
LOG_FILE="/var/log/backup/mysql_backup.log"

# Lokal yedek
echo "[${BACKUP_DATE}] Lokal yedek başlıyor..." >> $LOG_FILE
mysqldump --all-databases --single-transaction 
  --routines --triggers --events 
  -u root -pSifreBuraya | 
  gzip > ${DEST_LOCAL}/full_backup_${BACKUP_DATE}.sql.gz

# Uzak DR sitesine gönder
rsync -avz --delete 
  --exclude="*.tmp" 
  -e "ssh -i /root/.ssh/dr_backup_key -p 2222" 
  ${DEST_LOCAL}/ 
  ${DEST_REMOTE}/ >> $LOG_FILE 2>&1

if [ $? -eq 0 ]; then
    echo "[${BACKUP_DATE}] DR replikasyonu başarılı." >> $LOG_FILE
else
    echo "[${BACKUP_DATE}] HATA: DR replikasyonu başarısız!" >> $LOG_FILE
    # Alarm gönder
    curl -s -X POST https://hooks.slack.com/services/XXXXX 
      -H 'Content-type: application/json' 
      -d '{"text":"DR backup başarısız! Kontrol edin."}'
fi

# 30 günden eski lokal yedekleri temizle
find ${DEST_LOCAL} -name "*.sql.gz" -mtime +30 -delete

DR Test Senaryosu: Tam Kesinti Simülasyonu

DR planının en önemli parçası test etmektir. Test etmediğin DR planı, olmayan DR planıdır. İşte basit bir test scripti:

#!/bin/bash
# dr_test.sh - DR test senaryosu

echo "=== DR Test Başlıyor: $(date) ==="
echo "Test ID: DR-$(date +%Y%m%d)"

# Adım 1: Mevcut durumu kaydet
echo "--- Adım 1: Üretim durumu snapshot alınıyor ---"
PROD_DB_SIZE=$(mysql -u root -pSifre -e "SELECT SUM(data_length+index_length) FROM information_schema.tables;" 2>/dev/null | tail -1)
echo "Üretim DB boyutu: ${PROD_DB_SIZE} bytes"

# Adım 2: Son DR yedeğinin tarihini kontrol et
echo "--- Adım 2: Son DR yedeği kontrol ediliyor ---"
LAST_BACKUP=$(ssh [email protected] 
  "ls -t /backup/mysql/*.sql.gz | head -1")
echo "Son yedek: ${LAST_BACKUP}"

# Adım 3: DR sitesinde restore simülasyonu
echo "--- Adım 3: DR sitesinde restore testi ---"
ssh [email protected] << 'ENDSSH'
  cd /tmp
  LATEST=$(ls -t /backup/mysql/*.sql.gz | head -1)
  echo "Restore ediliyor: ${LATEST}"
  
  # Test DB'ye restore et (üretim DB'ye dokunma!)
  gunzip -c ${LATEST} | mysql -u root -pDRSifre dr_test_db 2>&1
  
  if [ $? -eq 0 ]; then
      echo "RESTORE BAŞARILI"
      # Tablo sayısını kontrol et
      mysql -u root -pDRSifre dr_test_db 
        -e "SELECT COUNT(*) as tablo_sayisi FROM information_schema.tables WHERE table_schema='dr_test_db';"
  else
      echo "RESTORE BAŞARISIZ - ACİL MÜDAHALE GEREKİYOR"
  fi
ENDSSH

echo "=== DR Test Tamamlandı: $(date) ==="

HA ve DR’ın Birlikte Çalıştığı Gerçek Dünya Senaryosu

Bu ikisini birbirinin alternatifi olarak değil, tamamlayıcı katmanlar olarak düşün. Tipik bir kurumsal altyapı şöyle görünebilir:

Katman 1 – HA (Aynı Veri Merkezi İçinde)

  • Load balancer cluster (Keepalived + HAProxy)
  • Uygulama sunucuları cluster (minimum 2 node)
  • Veritabanı primary + standby (senkron replikasyon)
  • Shared storage (Ceph veya DRBD)

Katman 2 – DR (Farklı Coğrafi Konum)

  • Günlük tam yedek + saatlik incremental
  • Asenkron veritabanı replikasyonu (ikinci bölge)
  • Kritik konfigürasyon dosyaları git repo’da
  • İnfrastructure as Code (Terraform/Ansible ile çabuk ayağa kalkabilme)
# Ansible ile DR site'de altyapı hızlıca ayağa kaldırma
# dr_restore_playbook.yml'ı çalıştır

ansible-playbook -i dr_inventory.ini dr_restore_playbook.yml 
  --extra-vars "restore_date=20240115 environment=dr" 
  --tags "webserver,database,loadbalancer" 
  -v 2>&1 | tee /var/log/dr_restore_$(date +%Y%m%d_%H%M%S).log

DRBD ile Senkron Block Device Replikasyonu

Aynı veri merkezindeki HA için DRBD kullanıyorsan:

# /etc/drbd.d/mysql.res
resource mysql {
  protocol C;  # Senkron mod - en güvenli
  
  on sunucu1 {
    device    /dev/drbd0;
    disk      /dev/sdb1;
    address   192.168.1.11:7789;
    meta-disk internal;
  }
  
  on sunucu2 {
    device    /dev/drbd0;
    disk      /dev/sdb1;
    address   192.168.1.12:7789;
    meta-disk internal;
  }
}
# DRBD durumunu kontrol et
drbdadm status mysql

# Manuel failover (bakım için)
drbdadm secondary mysql   # Mevcut primary'de
drbdadm primary mysql     # Yeni primary'de

# Senkronizasyon yüzdesini izle
watch -n 2 'cat /proc/drbd'

Monitoring: HA ve DR’ı İzleme

HA sistemlerin çalışıp çalışmadığını bilmezsen, o sistem sağlam değildir. İzleme kritik.

#!/bin/bash
# ha_health_check.sh - HA sağlık kontrolü

# VIP'nin doğru yerde olup olmadığını kontrol et
VIP="192.168.1.100"
EXPECTED_MASTER="sunucu1"

CURRENT_VIP_HOST=$(arping -I eth0 -c 1 ${VIP} 2>/dev/null | 
  grep "reply from" | awk '{print $5}' | tr -d '[]')

echo "VIP kontrolü: ${VIP}"
echo "Mevcut host: ${CURRENT_VIP_HOST}"

# Keepalived state kontrolü
KEEPALIVED_STATE=$(cat /tmp/keepalived_state 2>/dev/null || 
  systemctl is-active keepalived)
echo "Keepalived durumu: ${KEEPALIVED_STATE}"

# PostgreSQL replikasyon lag kontrolü
REPLICATION_LAG=$(psql -U postgres -t -c 
  "SELECT EXTRACT(EPOCH FROM (now() - pg_last_xact_replay_timestamp()))::INT;" 
  2>/dev/null)

if [ -n "${REPLICATION_LAG}" ]; then
    echo "Replikasyon gecikmesi: ${REPLICATION_LAG} saniye"
    if [ ${REPLICATION_LAG} -gt 300 ]; then
        echo "UYARI: Replikasyon gecikmesi 5 dakikayı aştı!"
        # Alarm tetikle
    fi
fi

Yaygın Hatalar ve Tuzaklar

Yıllarca bu sistemleri kurarken ve başkalarının kurduğu sistemleri düzeltirken gördüğüm en yaygın hatalar şunlar:

HA’yı DR sanmak: En başta söyledim, tekrar söylüyorum. Aynı raf içinde iki sunucun varsa ve o raf yanarsa, HA’n sana hiç yardımcı olmaz.

DR testlerini ihmal etmek: “Yedekler gidiyor, tamam” demek yeterli değil. Ayda bir restore testi yapmıyorsan, o yedekler çalışmıyor sayılır. Ben bir projede 8 aylık yedek aldıklarını sanan bir ekiple çalıştım. Test ettiğimizde yedeklerin 3 aydır bozuk gittiğini keşfettik.

RTO/RPO hedeflerini belirlemeden mimari kurmak: İş birimlerine “Kaç saat downtime kabul edersiniz?” sorusunu sormadan sistem tasarlama. Bu soru, bütçe ve mimari kararlarını doğrudan etkiler.

Split-brain senaryolarını düşünmemek: HA cluster’larda iki node birbirini göremez hale gelince ikisi de primary olmaya çalışabilir. Quorum ve STONITH mekanizmalarını ihmal etme.

# Pacemaker ile STONITH konfigürasyonu
# Split-brain'i önlemek için fence device ekle
pcs stonith create fence_sunucu2 fence_ipmilan 
  ipaddr="192.168.1.200" 
  login="admin" 
  passwd="ipmipass" 
  pcmk_host_list="sunucu2" 
  lanplus=1

# STONITH test et - dikkatli ol, bu komutu çalıştırırsan sunucu2 kapanır!
# pcs stonith fence sunucu2

DR Planı Dokümantasyonu: Runbook Örneği

Her DR planının yazılı, adım adım bir runbook’u olmalı. Gece 03:00’te panikle ne yapacağını bilmen gerekiyor.

# Bu bir runbook şablonu değil, otomatik DR başlatma scripti örneği
#!/bin/bash
# dr_failover.sh - SADECE tam felaket senaryosunda kullan

echo "UYARI: Bu script DR failover başlatır. Emin misiniz? (EVET yazın)"
read ONAY

if [ "$ONAY" != "EVET" ]; then
    echo "İşlem iptal edildi."
    exit 1
fi

FAILOVER_TIME=$(date +%Y%m%d_%H%M%S)
LOG="/var/log/dr_failover_${FAILOVER_TIME}.log"

echo "DR Failover başlıyor: ${FAILOVER_TIME}" | tee -a $LOG

# Adım 1: DNS'i DR sitesine çevir
echo "Adım 1: DNS güncelleniyor..." | tee -a $LOG
# Route53 veya benzeri ile DNS güncelle
aws route53 change-resource-record-sets 
  --hosted-zone-id ZXXXXXXXXXXXXX 
  --change-batch file:///etc/dr/dns_failover.json 
  2>&1 | tee -a $LOG

# Adım 2: DR veritabanını primary yap
echo "Adım 2: DR DB promote ediliyor..." | tee -a $LOG
ssh [email protected] 
  "pg_ctl promote -D /var/lib/postgresql/15/main" 
  2>&1 | tee -a $LOG

# Adım 3: Uygulama sunucularını başlat
echo "Adım 3: DR uygulama sunucuları başlatılıyor..." | tee -a $LOG
ansible-playbook -i /etc/dr/dr_inventory.ini 
  /etc/dr/start_services.yml 
  2>&1 | tee -a $LOG

echo "DR Failover tamamlandı. Log: ${LOG}" | tee -a $LOG

Maliyet Dengesi: Ne Kadar HA, Ne Kadar DR?

Bu sorunun cevabı tamamen iş gereksinimlerine bağlı. Ama genel rehber şöyle:

E-ticaret sitesi, her dakika para kazandıran sistem: Güçlü HA + aktif-aktif DR (multi-region). Maliyet yüksek ama downtime daha pahalı.

Şirket içi ERP, mesai saatlerinde kullanılan sistem: Orta düzey HA + soğuk DR (cold standby). Geceleri sistem kapalıysa kimse fark etmez.

Arşiv sistemleri, az kullanılan uygulamalar: Minimal HA + sadece yedekleme tabanlı DR. RTO 24 saat bile kabul edilebilir.

Sonuç

HA ve DR, birbirinin rakibi değil tamamlayıcısıdır. HA sana operasyonel sürekliliği verir, sunucu çökmeleri ve donanım hatalarına karşı korur. DR ise seni gerçek felaketlere karşı korur, veri merkezinin yok olduğu, büyük siber saldırıların yaşandığı senaryolara karşı bir ağ görevi görür.

Her sistemci şu soruları kendine sorarak başlamalı: “Bu sistem kaç saat downtime kaldırabilir? Kaç saatlik veri kaybını kabul edebiliriz?” Bu soruların cevapları, mimariyi şekillendirir ve bütçeyi belirler.

En önemli hatırlatma ise şu: Test etmediğin her şey var olmayan bir şeydir. DR planın varsa, ayda bir test et. Keepalived failover’ın varsa, yılda birkaç kez manuel tetikle. Yedeklerin varsa, restore et ve çalıştığını gör. Çünkü gece 03:00’te gerçek bir felaketle karşılaştığında, o ana kadar test etmediğin her şey seni yarı yolda bırakacaktır.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir