rsync ile Dosya Senkronizasyonu ve Uzak Yedekleme

Sistem yöneticiliğinde en çok ihtiyaç duyduğun araçlardan biri, dosyaları güvenilir şekilde senkronize edip yedekleyebilen bir çözümdür. rsync tam olarak bu iş için tasarlanmış, onlarca yıllık geçmişe sahip, savaşta test edilmiş bir araçtır. Basit bir dosya kopyalama işleminden tutun da karmaşık uzak yedekleme senaryolarına kadar her şeyi halleder. Bu yazıda rsync’i gerçek dünya senaryolarıyla ele alacağız, temel parametrelerden başlayıp ileri seviye kullanım örneklerine kadar ineceğiz.

rsync Nedir ve Neden Bu Kadar Güçlüdür?

rsync, “remote sync” kelimelerinin kısaltmasıdır ve adından da anlaşılacağı üzere hem lokal hem de uzak sistemler arasında dosya senkronizasyonu yapar. Ama onu gerçekten güçlü yapan şey, çalışma biçimidir. Kopyalama yaparken sadece değişen kısımları transfer eder, bu sayede bant genişliği kullanımı dramatik biçimde düşer.

rsync’in öne çıkan özellikleri:

  • Delta transfer algoritması: Sadece değişen blokları gönderir, tüm dosyayı değil
  • SSH desteği: Uzak transferleri şifreli kanaldan yapar
  • İzin ve sahiplik koruması: Dosya meta verilerini birebir korur
  • Bant genişliği sınırlama: Üretim ortamlarında ağı boğmaz
  • Kısmi transfer desteği: Kesilen transferleri kaldığı yerden devam ettirir
  • Checksum doğrulama: Dosya bütünlüğünü garantiler

Temel Kullanım ve Önemli Parametreler

rsync’in sözdizimi şu şekildedir:

rsync [seçenekler] kaynak hedef

En sık kullanılan parametreler:

  • -a (–archive): Arşiv modu, izinleri, sahipliği, zaman damgalarını korur
  • -v (–verbose): İşlemleri ekranda gösterir
  • -z (–compress): Transfer sırasında veriyi sıkıştırır
  • -P: İlerleme çubuğu gösterir ve kısmi transferlere izin verir
  • -n (–dry-run): Gerçekten kopyalamadan ne yapacağını simüle eder
  • -r (–recursive): Dizinleri özyinelemeli olarak işler
  • -u (–update): Hedefte daha yeni olan dosyaları atlar
  • –delete: Kaynakta olmayan dosyaları hedeften siler
  • –exclude: Belirli dosya veya dizinleri dışarıda tutar
  • –bwlimit: Bant genişliğini KB/s cinsinden sınırlar
  • -e: Kullanılacak uzak kabuk programını belirtir
  • –checksum: Zaman damgası yerine checksum kullanarak karşılaştırır
  • –hard-links: Sabit bağlantıları korur
  • –progress: Transfer ilerlemesini gösterir

İlk Basit Örnekler

Lokal bir dizini başka bir dizine kopyalamak:

rsync -av /home/ahmet/belgeler/ /mnt/backup/belgeler/

Burada dikkat edilmesi gereken önemli bir nokta var: kaynak dizinin sonundaki eğik çizgi. /belgeler/ yazdığında dizinin içeriğini kopyalar, /belgeler yazdığında ise dizinin kendisini kopyalar. Bu ince fark çok karışıklığa yol açar.

# Dizinin içeriğini kopyalar
rsync -av /kaynak/dizin/ /hedef/dizin/

# Dizinin kendisini kopyalar (hedefte /hedef/dizin/dizin oluşur)
rsync -av /kaynak/dizin /hedef/dizin/

Dry-run ile önce ne olacağını gör:

rsync -avn /home/ahmet/belgeler/ /mnt/backup/belgeler/

Uzak Sunucu ile Senkronizasyon

rsync’in asıl gücü SSH üzerinden uzak transferlerde ortaya çıkar. İki farklı sözdizimi vardır.

SSH ile Dosya Gönderme

Lokal sunucudan uzak sunucuya dosya göndermek:

rsync -avz -e "ssh -p 2222" /var/www/html/ [email protected]:/var/www/html/

Burada -e "ssh -p 2222" ile standart dışı SSH portu belirttik. Eğer SSH anahtarı kullanıyorsanız ve port standartta ise sadece şunu yazmanız yeterli:

rsync -avz /var/www/html/ deploy@web-sunucu:/var/www/html/

Uzak Sunucudan Dosya Çekmek

Uzak sunucudan lokal makineye çekmek de aynı şekilde çalışır, sadece kaynak ve hedef yer değiştirir:

rsync -avz kullanici@uzak-sunucu:/etc/nginx/ /backup/nginx-config/

Bant Genişliği Sınırlama

Üretim ortamında gece yedekleme yaparken ağı boğmamak için:

rsync -avz --bwlimit=5000 /data/buyuk-dosyalar/ kullanici@yedek-sunucu:/data/

Bu komut transfer hızını 5000 KB/s (yaklaşık 5 MB/s) ile sınırlar.

Gerçek Dünya Senaryosu 1: Web Sunucusu Yedekleme

Diyelim ki bir web sunucunuz var ve her gece /var/www ile /etc/nginx dizinlerini uzak bir yedek sunucuya göndermek istiyorsunuz. --delete parametresiyle birlikte tam ayna yedek oluşturabilirsiniz.

#!/bin/bash

KAYNAK_SUNUCU="web01"
YEDEK_SUNUCU="backup01"
YEDEK_KULLANICI="rsync-backup"
LOG_DOSYASI="/var/log/web-backup.log"
TARIH=$(date +%Y-%m-%d)

echo "[$TARIH] Yedekleme basliyor..." >> $LOG_DOSYASI

# Web dizinini yedekle
rsync -avz --delete 
  --exclude='*.tmp' 
  --exclude='cache/' 
  --exclude='*.log' 
  -e "ssh -i /root/.ssh/backup_key -o StrictHostKeyChecking=no" 
  /var/www/ 
  $YEDEK_KULLANICI@$YEDEK_SUNUCU:/backup/web01/www/ >> $LOG_DOSYASI 2>&1

# Nginx konfigürasyonunu yedekle
rsync -avz --delete 
  -e "ssh -i /root/.ssh/backup_key" 
  /etc/nginx/ 
  $YEDEK_KULLANICI@$YEDEK_SUNUCU:/backup/web01/nginx-config/ >> $LOG_DOSYASI 2>&1

echo "[$TARIH] Yedekleme tamamlandi." >> $LOG_DOSYASI

Bu scripti crontab’a ekleyerek her gece 02:00’de çalıştırın:

0 2 * * * /root/scripts/web-backup.sh

Gerçek Dünya Senaryosu 2: –delete ile Ayna Yedek

--delete parametresi, kaynakta silinmiş dosyaları hedeften de siler. Bu tam anlamıyla bir ayna yedek oluşturur. Ancak dikkatli olun: yanlış kullanırsanız önemli dosyaları silebilir.

# Dikkatli kullanılacak komut - once dry-run yapın!
rsync -avz --delete --dry-run /production/data/ /backup/data/

# Her şey doğruysa gerçek komutu çalıştırın
rsync -avz --delete /production/data/ /backup/data/

--delete-after ile silme işlemini transfer bittikten sonra yapmak daha güvenlidir:

rsync -avz --delete-after /production/data/ /backup/data/

Gerçek Dünya Senaryosu 3: Artımlı Yedekleme (–link-dest ile)

rsync’in en gelişmiş özelliklerinden biri --link-dest parametresidir. Bu parametre sayesinde disk alanından tasarruf ederek her gün tam yedek alıyormuş gibi görünen ama aslında artımlı çalışan bir yedekleme sistemi kurabilirsiniz. Hard link sihri burada devreye girer.

#!/bin/bash

KAYNAK="/home/"
HEDEF="/backup/incremental"
TARIH=$(date +%Y-%m-%d)
DUNKUYEDEK="$HEDEF/$(date -d yesterday +%Y-%m-%d)"
BUGUNKUYEDEK="$HEDEF/$TARIH"

rsync -avz 
  --delete 
  --link-dest="$DUNKUYEDEK" 
  /home/ 
  "$BUGUNKUYEDEK/"

echo "Artimli yedek tamamlandi: $BUGUNKUYEDEK"

Bu yöntemde her yedek dizini sanki tam yedekmişcesine görünür ama değişmeyen dosyalar hard link olarak saklandığından disk alanı çok az harcar. 30 günlük yedek tutuyorsanız ve dosyaların %95’i değişmiyorsa, 30 kat disk alanı değil neredeyse 1 kat disk alanı kullanırsınız.

Dosyaları Hariç Tutmak: –exclude ve –exclude-from

Yedekleme yaparken her şeyi yedeklemek istemeyebilirsiniz. Geçici dosyalar, cache dizinleri, log dosyaları bunların başında gelir.

rsync -avz 
  --exclude='*.tmp' 
  --exclude='*.swp' 
  --exclude='.git/' 
  --exclude='node_modules/' 
  --exclude='__pycache__/' 
  /projeler/ kullanici@yedek:/projeler/

Hariç tutulacaklar çoksa bir dosyaya yazabilirsiniz:

# /etc/rsync-exclude.txt dosyası oluşturun
cat > /etc/rsync-exclude.txt << EOF
*.tmp
*.log
*.swp
.git/
node_modules/
__pycache__/
.DS_Store
cache/
sessions/
EOF

# Sonra bu dosyayı kullanın
rsync -avz --exclude-from='/etc/rsync-exclude.txt' /kaynak/ /hedef/

rsync Daemon Modu

rsync’i SSH yerine kendi protokolüyle daemon olarak çalıştırabilirsiniz. Bu özellikle büyük iç ağlarda, yüksek trafikli ortamlarda daha verimlidir.

Yedek sunucuda /etc/rsyncd.conf dosyasını oluşturun:

# /etc/rsyncd.conf

uid = rsync
gid = rsync
use chroot = yes
max connections = 4
syslog facility = local5
pid file = /var/run/rsyncd.pid

[web-backup]
    path = /backup/web
    comment = Web Sunucusu Yedekleri
    read only = false
    list = false
    auth users = backup-user
    secrets file = /etc/rsyncd.secrets
    hosts allow = 192.168.1.0/24

Şifre dosyasını oluşturun:

echo "backup-user:guvenli-sifre123" > /etc/rsyncd.secrets
chmod 600 /etc/rsyncd.secrets

Daemon’ı başlatın:

systemctl enable rsync
systemctl start rsync

Artık istemci tarafından şöyle bağlanabilirsiniz:

rsync -avz /var/www/ rsync://backup-user@yedek-sunucu/web-backup/

SSH Anahtarı ile Otomatik Yedekleme Kurulumu

Cron ile çalışan yedekleme scriptleri için parola girmeden SSH bağlantısı kurabilmeniz gerekir. Bunun için SSH anahtar çiftini ayarlamanız gerekiyor.

# Backup için özel anahtar oluşturun
ssh-keygen -t ed25519 -f /root/.ssh/backup_key -N "" -C "backup-rsync-key"

# Public anahtarı uzak sunucuya kopyalayın
ssh-copy-id -i /root/.ssh/backup_key.pub backup-user@yedek-sunucu

# Bağlantıyı test edin
ssh -i /root/.ssh/backup_key backup-user@yedek-sunucu "echo Baglanti basarili"

# Artık rsync kullanabilirsiniz
rsync -avz -e "ssh -i /root/.ssh/backup_key" /data/ backup-user@yedek-sunucu:/backup/data/

Güvenliği artırmak için authorized_keys dosyasında bu anahtarı sadece rsync çalıştırabilecek şekilde kısıtlayabilirsiniz:

# Uzak sunucudaki ~/.ssh/authorized_keys dosyasına şunu ekleyin
command="rsync --server --daemon .",no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-ed25519 AAAA...anahtariniz... backup-rsync-key

Performans İpuçları

Checksum Yerine Zaman Damgası Kullanımı

Varsayılan olarak rsync dosyaları zaman damgası ve boyutuna göre karşılaştırır. --checksum ile MD5 kontrolü yapılır ama bu çok daha yavaştır. Sadece dosya bütünlüğünden şüphelendiğinizde kullanın:

rsync -avz --checksum /kritik-veri/ /backup/kritik-veri/

Sıkıştırma ile Transfer Hızlandırma

Ağ bant genişliğiniz diskten yavaşsa -z ile sıkıştırma yapın. Ama zaten sıkıştırılmış dosyalar (jpg, mp4, zip, gz) için bunu kullanmak CPU’yu boşu boşuna yorar:

# Metin dosyaları ve kod için sıkıştırma iyi
rsync -avz /var/log/ /backup/logs/

# Medya dosyaları için sıkıştırma gereksiz
rsync -av /medya/fotolar/ /backup/fotolar/

Paralel Transfer

Çok sayıda küçük dosyanız varsa GNU Parallel ile rsync’i paralel çalıştırabilirsiniz:

# Büyük bir dizini parçalara böl ve paralel rsync çalıştır
ls /buyuk-dizin/ | parallel -j4 rsync -az /buyuk-dizin/{}/ kullanici@sunucu:/backup/{}/

Yedekleme Doğrulama

Yedek aldınız ama doğru mu alındı? rsync ile kontrol edebilirsiniz:

# Kaynak ve hedef arasında fark var mı kontrol et
rsync -avnc /kaynak/veri/ /backup/veri/

# -n dry-run, -c checksum kontrolü yapar
# Eğer çıktı boşsa her şey senkronize demektir

Daha detaylı doğrulama için:

#!/bin/bash
echo "Yedek dogrulama basliyor..."
FARKLAR=$(rsync -avnc /kaynak/ /backup/ 2>&1 | grep -v "/$" | grep -v "sending" | grep -v "sent" | wc -l)

if [ "$FARKLAR" -gt 0 ]; then
    echo "UYARI: $FARKLAR dosyada fark tespit edildi!"
    rsync -avnc /kaynak/ /backup/ 2>&1 | grep -v "/$"
else
    echo "Yedek dogrulama basarili. Tum dosyalar eslesiyoor."
fi

Sık Karşılaşılan Sorunlar ve Çözümleri

İzin hatası alıyorum:

# --rsync-path ile uzak rsync'i sudo ile çalıştır
rsync -avz --rsync-path="sudo rsync" /etc/ kullanici@sunucu:/backup/etc/

Bağlantı zaman aşımına uğruyor:

# SSH timeout değerlerini ayarla
rsync -avz -e "ssh -o ConnectTimeout=30 -o ServerAliveInterval=60" /data/ kullanici@sunucu:/backup/

Transfer yarıda kesildi, kaldığı yerden devam et:

# --partial ve --append ile yarım kalan transferi devam ettir
rsync -avzP --append /buyuk-dosya.tar kullanici@sunucu:/backup/

Sembolik bağlantılar yedeklenmedi:

# -l parametresi ile sembolik bağlantıları koru
rsync -avlz /kaynak/ /hedef/

# Sembolik bağlantıların gösterdiği dosyaları kopyalamak için
rsync -avLz /kaynak/ /hedef/

Pratik Bir Monitoring Scripti

Günlük yedekleme sonuçlarını e-posta ile almak için:

#!/bin/bash

KAYNAK="/var/www/"
HEDEF="backup@yedek-sunucu:/backup/www/"
SSH_KEY="/root/.ssh/backup_key"
EMAIL="[email protected]"
GECICI_LOG=$(mktemp)
TARIH=$(date '+%d.%m.%Y %H:%M')

rsync -avz --delete 
  --stats 
  -e "ssh -i $SSH_KEY" 
  $KAYNAK $HEDEF > $GECICI_LOG 2>&1

EXIT_CODE=$?

if [ $EXIT_CODE -eq 0 ]; then
    BASLIK="[BASARILI] Web Yedekleme - $TARIH"
else
    BASLIK="[HATA] Web Yedekleme Basarisiz - $TARIH (Kod: $EXIT_CODE)"
fi

mail -s "$BASLIK" $EMAIL < $GECICI_LOG
rm -f $GECICI_LOG

Sonuç

rsync, sistem yöneticisinin araç kutusundaki en değerli araçlardan biridir. Delta transfer algoritması, SSH entegrasyonu ve esnek parametre yapısıyla hem basit dosya senkronizasyonu hem de kurumsal düzeyde yedekleme çözümleri için idealdir. Yazdığım senaryolara bakıldığında, tek bir araçla ne kadar farklı ihtiyacı karşılayabildiğini görüyorsunuz.

Başlangıç için şu üç alışkanlığı edinin: Her yeni rsync komutunu önce -n ile test edin, yedekleme scriptlerinize log yazımı ekleyin ve zaman zaman yedekleri --checksum ile doğrulayın. Yedek almak tek başına yeterli değildir, alınan yedeğin geri yüklenebilir olduğunu da doğrulamak zorundaysınız.

rsync’in tüm parametrelerini ezberlemek gerekmez ama temel senaryoları aklınızda tutun ve ihtiyaç duydukça man rsync ile detaylara bakın. Zira man sayfası oldukça kapsamlı ve iyi yazılmış bir dokümandır.

Yorum yapın